TL;DR — Reference solution for Exercise 3: the exact
gh runcommands to find a failure, enableACTIONS_STEP_DEBUG, fix the broken test, and pull the artifact down. Mirror this sequence the next time CI fails on a real PR.
Introduced an intentional test failure, debugged it with gh CLI and debug logging, fixed it, and downloaded the artifact.
# src/test_app.py — add this test
def test_intentional_failure():
assert 1 == 2, "This test is intentionally broken"git add src/test_app.py
git commit -m "test: intentional failure for debug exercise"
git push -u origin "$BRANCH"
gh pr create --title "debug: intentional failure exercise" --body "."gh run list --limit 3
gh run view <run-id> --log-failedWhat you should see:
AssertionError: This test is intentionally broken
assert 1 == 2
gh secret set ACTIONS_STEP_DEBUG --body "true"
gh run rerun <run-id> --failedIn the re-run logs, look for lines prefixed with ##[debug] — these show action inputs, paths, and environment details that are hidden in normal runs.
# Remove or fix the test
def test_intentional_failure():
assert 1 == 1, "Fixed!"git add src/test_app.py
git commit -m "fix: remove intentional failure"
git push
gh pr checks --watch # watch all checks go greengh secret delete ACTIONS_STEP_DEBUGgh run list --limit 1
gh run download <run-id> --name test-results-py3.11 --dir ./results
ls ./results/gh run view --log-failedshows only the failed step — much faster than reading all logs- Debug logs add significant noise — only enable when you need them, delete the secret after
- Artifacts persist even when a run fails, as long as the upload step ran with
if: always() - Re-running only failed jobs saves time — passed jobs don't re-run