Skip to content

ci: skip main re-verification of PR-verified trees; harden release workflow - #403

Merged
entelecheia merged 1 commit into
mainfrom
feat/ci-402-dedup-main-checks
Sep 27, 2026
Merged

entelecheia merged 1 commit into
mainfrom
feat/ci-402-dedup-main-checks

Conversation

@entelecheia

Copy link
Copy Markdown
Member

Closes #402

Summary

  • .github/workflows/ci.yml: new first job decision (timeout 10 min; permissions contents:read, pull-requests:read, checks:read). Its output run_full is false only when the event is push, the pushed SHA is the merge_commit_sha of a merged PR, the pushed commit's tree SHA equals the PR head's tree SHA, and the five gate check runs (lint, pdf-parity, test (ubuntu-latest), test (macos-latest), test (windows-latest)) on the PR head are all completed/success — the same five names the release gates already require, so one contract holds across the three workflow files (a deliberate difference from the maru reference, which matches on run-name). Any API failure falls back to run_full=true with a ::warning::; the reason is written to $GITHUB_STEP_SUMMARY. lint, pdf-parity, and test are gated with needs: decision + if: needs.decision.outputs.run_full == 'true'. The paths filter is unchanged; the concurrency comment now notes that deduplicated main commits borrow the identical tree's PR signal.
  • .github/workflows/release.yml: verify-ci's Tagged commit has green CI step gains the identical-tree fallback, inline: (a) own five check runs green -> pass, evidence own check runs; (b) else resolve the merged PR with merge_commit_sha == tagged SHA, require equal tree SHAs and five green check runs on the PR head -> pass, evidence PR #N head <sha> validated identical tree <tree>; (c) else the previous fail behavior and message. Also adds workflow-level concurrency: { group: release, cancel-in-progress: false } (two update-formula runs can no longer race on Formula/hwp.rb) and timeout-minutes on all seven jobs (verify-ci 10, verify-version 5, create-release 5, upload-assets 30, skill-bundle 10, publish-release 5, update-formula 15).
  • .github/workflows/release-readiness.yml: the same identical-tree fallback, inline, in Gate ci-matrix. The pass evidence records PR #N head <sha> validated identical tree <tree> in the run record, so the record names the PR head it relied on. Kept inline (not a repository script) because the step is a controller step under the trust policy at L13-28 and must not execute code from the evaluated checkout. Fail/pending outcomes and their messages are unchanged.
  • docs/release-readiness.md + docs/release-readiness.ko.md (same commit, per the bilingual policy): the CI-matrix checklist item now notes that CI green can come from the commit's own check runs or from an identical-tree merged PR head.

scripts/tests/release-readiness-selfcheck.sh and the verification-block fixtures were re-grepped: neither references ci-matrix, so no extension was needed (matches the issue's task list).

Verification

Local, before opening this PR:

  • YAML syntax: all three workflows parse (yaml.safe_load); every edited run: block passes bash -n.
  • Step-logic harness: the three edited scripts were extracted verbatim and run against a fake gh API serving fixture JSON. 16/16 scenarios pass, covering: own-green pass, identical-tree fallback pass, tree-differs fail, no-PR fail/pending, head-checks-not-green fallthrough, API-failure fallback to run_full=true with ::warning::, pull_request/workflow_dispatch/unmerged-PR always running the full matrix, and the readiness evidence string naming the PR head.
  • Full local gate: scripts/check.sh ends with
    == check: OK (fmt/clippy/test/crate-edges/pdf-runner/structured-corpus/claims/doc-surface/release-block/readiness-selfcheck/skip-accounting/public-parity=skipped) skipped-for-missing-fixtures=4 (optional=4) ==
    (public-parity=skipped is expected on a host without the pinned pdfinfo version 24.02.0.)

Acceptance criteria from #402:

AC Status Method / run URL
AC1 (merging a PR with identical head tree runs only decision on main) Observable only after merge Will be verified by this PR's own merge: the main-push CI run for the squash commit should show only the decision job executing, with the summary naming this PR and the tree. Run URL to be pasted into #402 after merging.
AC2 (tree differs / direct push / workflow_dispatch run the full matrix) Verified in the harness (tree-differs and workflow_dispatch scenarios above); workflow_dispatch and direct-push behavior will also be observable on any subsequent non-PR main event Harness scenarios 7, 11, 12 (all pass).
AC3 (tagging a PR-verified squash commit passes verify-ci with identical-tree evidence) Logic verified in the harness; end-to-end observable at the next release Harness scenario "verify-ci: identical-tree PR head fallback passes". Release run URL to be pasted into #402 at the next tag.
AC4 (tagging a commit with neither green own checks nor an identical-tree green PR head fails verify-ci) Verified by exercising the step logic against fixtures, as the AC allows Harness scenarios "verify-ci: tree differs -> fail" and "verify-ci: no PR, incomplete own runs -> fail".
AC5 (readiness dispatched on a deduplicated main commit records ci-matrix pass with identical-tree evidence) Logic verified in the harness; end-to-end observable at the next readiness dispatch on such a commit Harness scenario "ci-matrix: identical-tree fallback -> pass with PR evidence". Readiness run URL to be pasted into #402 when it occurs.
AC6 (docs-only PR still triggers no CI run) Observable only after merge — the paths filter is byte-identical to before (untouched), but the regression guard is behavioral Will be verified with a docs-only PR changing docs/**/*.md outside docs/manual/; expect no CI run. PR URL to be pasted into #402.
AC7 (every release.yml job has timeout-minutes; workflow has concurrency with cancel-in-progress: false) Verified in the diff All seven jobs carry timeout-minutes; workflow-level concurrency: { group: release, cancel-in-progress: false } added.

No gates were weakened: scripts/check.sh passed unmodified, the paths filter is untouched, and every fallback defaults to running the full matrix on any doubt.

…rkflow

A main push whose tree a merged PR head already verified re-ran the full
3-OS matrix on an already green tree (25 of the last 30 main pushes).
ci.yml gains a first `decision` job: run_full is false only when the push
is the merge_commit_sha of a merged PR, the tree SHAs are equal, and the
five gate check runs on the PR head are all completed/success (the same
five names the release gates require, so one contract holds across the
three files). Any API failure falls back to run_full=true with a warning.
lint, pdf-parity and test are gated on it; the paths filter is unchanged.

release.yml verify-ci and release-readiness.yml Gate ci-matrix accept that
identical-tree PR head signal as a fallback when the target commit has no
own green check runs, recording evidence that names the PR head. The
readiness logic stays inline: Gate ci-matrix is a controller step and must
not execute code from the evaluated checkout.

release.yml also gets a workflow concurrency group (cancel-in-progress:
false, so update-formula runs cannot race on Formula/hwp.rb) and
timeout-minutes on all seven jobs.

Refs #402
Copilot AI balanced review requested due to automatic review settings September 27, 2026 11:04

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Code review skipped: your organization has reached its API usage limit, so Code Review can't run right now.

An organization admin can review the limit in your organization's usage and billing settings.

Once the limit resets or is raised, reopen this pull request to trigger a review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-27T11:08:26.837517Z 000aabc PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 000aabcbdc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/release.yml
@entelecheia
entelecheia merged commit 4d23291 into main Sep 27, 2026
7 checks passed
@entelecheia
entelecheia deleted the feat/ci-402-dedup-main-checks branch September 27, 2026 11:14
entelecheia added a commit that referenced this pull request Sep 27, 2026
The #403 identical-tree fallback ran unconditionally when own checks were not all green, so an own failed CI could be overridden by a green PR head on the same tree (Codex P1 on #403). The fallback now applies only when all five own check runs are absent or completed/skipped — the dedup signature observed on 4d23291 — and any own failed, cancelled, pending or partial run keeps the pre-#403 failure behavior. Scenario harness 31/31.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci: skip main re-verification of PR-verified trees; harden release workflow

2 participants