fix(ci): check out the event sha into a per-job directory #49

Merged
Breadway merged 3 commits from fix/eco-79-isolated-checkout into main 2026-10-16 19:07:48 +08:00
Owner

Refs ECO-79 and depends on the shared helper in bread-ecosystem PR #79. PR #79 is still open and its helper is not integrated here. This PR therefore keeps a temporary inline bootstrap, rather than fetching an unmerged helper revision. Do not replace it with the shared helper until PR #79 is merged and the consumer can pin a reviewed commit plus verify the helper hash.

Change

  • check.yml and dev-release.yml clone into a unique RUNNER_TEMP directory, detach at GITHUB_SHA, validate its format, and explicitly verify HEAD == GITHUB_SHA.
  • Each workflow exports its own checkout directory through GITHUB_ENV and cleans only that guarded path in its final if: always() step.
  • Later steps run from the real clone path, not a symlink, so ci/build.sh mounts the expected parent directory.
  • The inline bootstrap is documented as temporary in the workflow comments and must be replaced with a pinned helper fetch plus integrity verification after the prerequisite merges.

Scope and gates

Only Bread's check.yml and dev-release.yml are changed. Bread's stable release.yml follow-up is ECO-81. The RC cleanup scope remains covered by ECO-56. Bread-ecosystem main-trigger workflows are tracked separately in ECO-82. No consumer workflow points at an unmerged helper commit.

Local workflow fixtures verified exact-SHA checkout in both workflows. Bread PR #49's earlier run on aa3eb6c succeeded. This updated head still needs its CI run.

Refs ECO-79 and depends on the shared helper in bread-ecosystem PR #79. PR #79 is still open and its helper is not integrated here. This PR therefore keeps a temporary inline bootstrap, rather than fetching an unmerged helper revision. Do not replace it with the shared helper until PR #79 is merged and the consumer can pin a reviewed commit plus verify the helper hash. ## Change - `check.yml` and `dev-release.yml` clone into a unique `RUNNER_TEMP` directory, detach at `GITHUB_SHA`, validate its format, and explicitly verify `HEAD == GITHUB_SHA`. - Each workflow exports its own checkout directory through `GITHUB_ENV` and cleans only that guarded path in its final `if: always()` step. - Later steps run from the real clone path, not a symlink, so `ci/build.sh` mounts the expected parent directory. - The inline bootstrap is documented as temporary in the workflow comments and must be replaced with a pinned helper fetch plus integrity verification after the prerequisite merges. ## Scope and gates Only Bread's `check.yml` and `dev-release.yml` are changed. Bread's stable `release.yml` follow-up is ECO-81. The RC cleanup scope remains covered by ECO-56. Bread-ecosystem main-trigger workflows are tracked separately in ECO-82. No consumer workflow points at an unmerged helper commit. Local workflow fixtures verified exact-SHA checkout in both workflows. Bread PR #49's earlier run on `aa3eb6c` succeeded. This updated head still needs its CI run.
fix(ci): check out the event sha into a per-job directory
Some checks failed
check / check (push) Failing after 5s
98fe7e39c9
Check and dev-release jobs cloned into the same relative src path on the
shared runner, so a second job could replace the tree mid-build (ECO-79).

Each job now clones into a mktemp directory, pins GITHUB_SHA, and links
src to it so the existing steps are unchanged. Cleanup removes only that
job directory in a final always() step.
fix(ci): run steps from the per-job clone instead of a src symlink
All checks were successful
check / check (push) Successful in 11m43s
aa3eb6cfc3
A src symlink in the job workspace made ci/build.sh resolve REPO_PARENT to
the workspace, so the container mount collided with it (mkdir /workspace/src:
file exists). Steps now cd into the clone under BREAD_CI_JOB_DIR directly, so
build.sh mounts a parent that holds only the clone.
fix(ci): verify exact event sha in checkout bootstrap
All checks were successful
check / check (push) Successful in 8m12s
01c416543a
The checkout remains inline until bread-ecosystem ECO-79 is reviewed and
merged; do not pin an unmerged helper revision. Validate GITHUB_SHA and
verify detached HEAD in both check and dev-release before using the tree.
Keep each job's checkout in its own RUNNER_TEMP directory and clean only
that directory in the final always() step.
Author
Owner

Independent review of bread PR 49 at exact head 01c416543a (base main d7add44b20). Verdict: PASS for this SHA, judged on its own. It does not depend on helper PR bread-ecosystem#79 and does not wait for it.

Criteria:

  • Inline verified event-SHA checkout in check.yml and dev-release.yml: full 40-hex format check, clone --no-checkout, checkout --detach "$GITHUB_SHA", then rev-parse HEAD equality. Pass.
  • Isolated per-job workspace: mktemp -d under RUNNER_TEMP with prefix bread-ci, repo in /src (a real path, so ci/build.sh still mounts the expected parent and basename). No bare "src" reference remains in either changed workflow (grep). Pass.
  • Env persisted safely: BREAD_CI_JOB_DIR written to GITHUB_ENV from mktemp output. Pass.
  • Own-dir cleanup: final if: always() step guarded by the bread-ci.* prefix and -d. I ran each workflow's checkout and cleanup steps extracted from the YAML against local fixtures: event sha (not branch tip) checked out, distinct dir per job, cleanup removes only its own dir and leaves a victim dir, "/", empty, other-prefix and ../ values alone, failed checkout then cleanup leaves nothing, and an injection-shaped GITHUB_SHA and short/upper/branch-name values are rejected without execution. Mutants: branch-tip checkout is caught; removing the format check or HEAD compare is not distinguishable on the happy path (defense in depth, acceptable). Pass.
  • No dependency on the unmerged helper; duplication explicit: the temporary bootstrap comments say to replace it with a pinned, hash-verified helper after #79 merges and point at docs/ci-checkout.md (that doc arrives with #79). Pass.
  • Actual CI: check / check (push) is success on this exact head, run 161 (8m12s); log shows the clone into .../bread-ci.X9BrjV/src and "Job succeeded". Pass.
  • Scope: only check.yml and dev-release.yml; stable release.yml and rc-release.yml still use the old pattern and are tracked separately (ECO-81, ECO-56). No tags or versions touched.

Residual risk, stated plainly: dev-release.yml cannot run on a PR (it triggers on main), so its first real execution is the post-merge dev publish on main. I verified its checkout/cleanup steps locally and that no relative src paths remain, but the publish step itself is unobserved until it runs. After merge, someone should confirm that dev-release run succeeds. Workspace-sharing on the runner remains an inference, not a confirmed observation.

Evidence: ~/.local/state/bread-ci/eco79/review-2026-10-16-second-pass.txt and bread-run161-job.log.

Independent review of bread PR 49 at exact head 01c416543a529528bf8bfd66aff18991fba07c88 (base main d7add44b204b7ce4a3648d5e98f32475ee705512). Verdict: PASS for this SHA, judged on its own. It does not depend on helper PR bread-ecosystem#79 and does not wait for it. Criteria: - Inline verified event-SHA checkout in check.yml and dev-release.yml: full 40-hex format check, clone --no-checkout, checkout --detach "$GITHUB_SHA", then rev-parse HEAD equality. Pass. - Isolated per-job workspace: mktemp -d under RUNNER_TEMP with prefix bread-ci, repo in <dir>/src (a real path, so ci/build.sh still mounts the expected parent and basename). No bare "src" reference remains in either changed workflow (grep). Pass. - Env persisted safely: BREAD_CI_JOB_DIR written to GITHUB_ENV from mktemp output. Pass. - Own-dir cleanup: final if: always() step guarded by the bread-ci.* prefix and -d. I ran each workflow's checkout and cleanup steps extracted from the YAML against local fixtures: event sha (not branch tip) checked out, distinct dir per job, cleanup removes only its own dir and leaves a victim dir, "/", empty, other-prefix and ../ values alone, failed checkout then cleanup leaves nothing, and an injection-shaped GITHUB_SHA and short/upper/branch-name values are rejected without execution. Mutants: branch-tip checkout is caught; removing the format check or HEAD compare is not distinguishable on the happy path (defense in depth, acceptable). Pass. - No dependency on the unmerged helper; duplication explicit: the temporary bootstrap comments say to replace it with a pinned, hash-verified helper after #79 merges and point at docs/ci-checkout.md (that doc arrives with #79). Pass. - Actual CI: check / check (push) is success on this exact head, run 161 (8m12s); log shows the clone into .../bread-ci.X9BrjV/src and "Job succeeded". Pass. - Scope: only check.yml and dev-release.yml; stable release.yml and rc-release.yml still use the old pattern and are tracked separately (ECO-81, ECO-56). No tags or versions touched. Residual risk, stated plainly: dev-release.yml cannot run on a PR (it triggers on main), so its first real execution is the post-merge dev publish on main. I verified its checkout/cleanup steps locally and that no relative src paths remain, but the publish step itself is unobserved until it runs. After merge, someone should confirm that dev-release run succeeds. Workspace-sharing on the runner remains an inference, not a confirmed observation. Evidence: ~/.local/state/bread-ci/eco79/review-2026-10-16-second-pass.txt and bread-run161-job.log.
Author
Owner

Merged after independent pass at head 01c416543a with check / check (push) green on that exact head (run 161), base unchanged at d7add44b20, no outstanding reviews. Merge commit 40ee494aef (parents: base and reviewed head). Not verified yet: the post-merge dev-release run on main, which is the first real execution of the changed dev-release.yml. ECO-79 stays open for verification; helper PR bread-ecosystem#79 is separate and still has changes requested.

Merged after independent pass at head 01c416543a529528bf8bfd66aff18991fba07c88 with check / check (push) green on that exact head (run 161), base unchanged at d7add44b204b7ce4a3648d5e98f32475ee705512, no outstanding reviews. Merge commit 40ee494aef39981943c6141c547c104968d93b03 (parents: base and reviewed head). Not verified yet: the post-merge dev-release run on main, which is the first real execution of the changed dev-release.yml. ECO-79 stays open for verification; helper PR bread-ecosystem#79 is separate and still has changes requested.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Breadway/bread!49
No description provided.