Skip to content

Follow-ups from the stage-1 action harness (PR #114) #116

Description

@mmcky

Handover note for resuming the action-harness work. PR #114 (stage 1 of #100) squash-merged to main as 99b81ed on 2026-07-30 — this issue collects everything that came out of that review and did not belong in the PR itself.

What landed

.github/workflows/test-actions.yml — a 14-job harness that exercises the composite actions in this repo via uses: ./<action> local paths, so it tests the code on the PR rather than a released ref. Plus the committed fixture .github/fixtures/mini-lectures/ (a two-page jupyter-book that executes a real code cell, so builds populate a genuine _build/.jupyter_cache), and two consumer-facing fixes the harness caught on its first run: the setup-environment conda cache was save-only on hosted runners (rooted at the root-owned ${CONDA}/envs), and build-lectures failed the step on a successful build because the exit builtin in a bash -l step triggers ~/.bash_logout, whose clear_console failure overrides the passed status. PLAN item 9 is closed. CONTRIBUTING gained release step 5 (drop obsolete @v0 workarounds when the floating tag moves).

#100 stays open for stages 2–4 (the QuantEcon/test-lectures canary repo, preview/publish coverage, tag-push trigger) — those need a separate repo plus Netlify/Cloudflare secrets.

Follow-ups, in priority order

# Item Blocked on Notes
1 Drop the rm -f ~/.bash_logout step from the bjc-smoke job The next release moving the floating v0 tag It exists only because build-jupyter-cache's internal build-lectures@v0 still carries the pre-fix exit pattern, and GitHub forbids expressions in uses: so that copy cannot pick the fix up until the tag moves. CONTRIBUTING step 5 is the tripwire; this is the one knowingly-temporary thing in the tree
2 Delete the dead tmp-verify-restore-cache.yml entry from the Actions sidebar Leftover registry entry from the throwaway harness that verified #104. The file exists on no branch, so it can never run and a commit cannot remove it — needs a click in the Actions UI
3 Tighten the negative build test's failure attribution build-fail-guard asserts the step outcome is failure, which would also be satisfied by a build that failed for an unrelated -W warning. Asserting harness/_build/html/reports/broken.err.log exists ties the red specifically to the execution error
4 Document the -W dependence in the build-lectures README See the note below; it is a real consumer-facing property, currently recorded nowhere in the docs
5 Companion workflow with negated paths:, if branch protection is ever enabled on main Someone enabling protection See the required-check note below

Two properties worth knowing before touching this again

A failing build only fails because of -W. The build-fail-guard job builds a page whose code cell raises. jupyter-book reports the CellExecutionError as a warning and keeps going, so the nonzero exit comes from -W in the extra-args default (-W --keep-going), not from the exception itself. The consequence for lecture repos: overriding extra-args without -W means a raised cell yields a published site plus an error-report page and exit 0 — a green CI over a broken lecture. Removing -W from the default would flip this harness job red, intentionally.

harness-summary as a required check would hang some PRs. The workflow has paths: filters. For pull_request events GitHub evaluates those against the whole PR diff, not the head commit, so any PR touching a covered path runs the harness — a docs-only commit pushed onto a PR that already touches a covered path is fine. But a PR whose entire diff touches none of the covered paths (docs-only, or publish-gh-pages/** only) never triggers the workflow, so a required Action harness: all checks would sit pending forever and block the merge. main was unprotected as of this merge, so this is latent. The fix is a companion workflow with the negated paths that emits a passing job of the same name.

Watch items, no action needed

The fixture pins jupyter-book==1.0.4post1 but leaves ipykernel and the python=3.13 resolution floating, so an upstream change can redden the harness on a PR that touched nothing related — arguably correct for a canary, but expect the occasional unrelated failure, and note that pinning policy properly belongs to the stage-2 canary. Separately, per-run cache salting (run_id-run_attempt, which is what makes the miss assertions trustworthy) means every run writes caches that are never reused again, including roughly two conda envs per run; that churns the repo's 10 GB cache budget and will LRU-evict the container-test caches. Both are by design.

Verification state at merge

All 14 jobs green on the PR head (9b379f5), plus an independent workflow_dispatch run on the previous commit with separately seeded caches. The post-merge push: main run is https://github.com/QuantEcon/actions/actions/runs/30524512574 — first run with f31f980 in the tree, and the run whose saved caches future PR runs will see.

Related: #100 (parent), #104 (the DOA save-mode bug that motivated the harness), #108 (container fixture cannot fail meaningfully), #109 (template drift — the stage-2 canary should consume templates verbatim to cover it).

Metadata

Metadata

Assignees

No one assigned

    Labels

    infrastructureSubstantial CI / build / deploy / tooling / automation work

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions