From 2f3504106baaff0b5d270a935a30c2f98debc11d Mon Sep 17 00:00:00 2001 From: Aryan Date: Sat, 1 Aug 2026 10:10:57 +0530 Subject: [PATCH] fix(ci): run product-invariants on main pushes with the merge-commit body (#9744) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit repo-checks.yml ran the manifest on main pushes with --skip-pr-body-checks, so product-invariants (and failure-class-protocol) were silently skipped — even though GitHub folds the PR description, including locked invariant citations like INV-CHAT-1, into the merge commit message. A main-push Hygiene run therefore could not verify citations at all (#9734 merged with the IDs in its body, yet the post-merge run reported them missing). Pass the merge-commit body through --pr-body-file instead. Fail-closed is preserved: a direct push whose commit message omits required invariant IDs still fails product-invariants. Updates the two wiring regression guards in test_run_checks.py: the main-push path must now pass --pr-body-file (not --skip-pr-body-checks), and body-requiring checks must be selected when a body is supplied. Failure-Class: none Co-authored-by: CommandCodeBot --- .github/scripts/test_run_checks.py | 30 ++++++++++++++++++++++++++++-- .github/workflows/repo-checks.yml | 15 ++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/.github/scripts/test_run_checks.py b/.github/scripts/test_run_checks.py index df328ad945a..c7ee32d2ef1 100755 --- a/.github/scripts/test_run_checks.py +++ b/.github/scripts/test_run_checks.py @@ -197,7 +197,13 @@ def test_workflow_checks_are_registered_or_exempt(self) -> None: def test_ci_lane_is_reachable_from_repo_checks(self) -> None: workflow = (WORKFLOWS_DIR / "repo-checks.yml").read_text(encoding="utf-8") self.assertRegex(workflow, r"run_checks\.py\s+--lane\s+ci") - self.assertIn("--skip-pr-body-checks", workflow) + # #9744: main pushes must pass the merge-commit body through + # --pr-body-file (not --skip-pr-body-checks), so product-invariants can + # see the citations GitHub folds into the merge commit message. This + # assertion is the wiring regression guard for that path. + self.assertNotIn("--skip-pr-body-checks", workflow) + self.assertRegex(workflow, r"git log -1 --format=%B HEAD") + self.assertRegex(workflow, r"--pr-body-file") manifest = load_manifest(MANIFEST_PATH) self.assertTrue(any("ci" in check.lanes for check in manifest.checks)) @@ -518,7 +524,27 @@ def test_failure_class_protocol_runs_in_both_lanes(self) -> None: selected = {check.id for check in resolve_checks(manifest, ["app/lib/example.dart"], lane)} self.assertIn("failure-class-protocol", selected) - def test_main_push_excludes_only_pr_body_checks(self) -> None: + def test_main_push_includes_pr_body_checks_when_body_supplied(self) -> None: + """#9744: main pushes now pass the merge-commit body through + --pr-body-file, so body-requiring checks (product-invariants, + failure-class-protocol) must run — not be silently skipped.""" + manifest = load_manifest(MANIFEST_PATH) + selected = { + check.id + for check in resolve_checks( + manifest, + ["app/lib/example.dart"], + "ci", + include_pr_body_checks=True, + ) + } + self.assertIn("product-invariants", selected) + self.assertIn("failure-class-protocol", selected) + self.assertIn("diff-hygiene", selected) + + def test_main_push_without_body_still_excludes_pr_body_checks(self) -> None: + """Fail-closed: a main push with no body must NOT run body-requiring + checks (they would fail on empty text), preserving the old skip.""" manifest = load_manifest(MANIFEST_PATH) selected = { check.id diff --git a/.github/workflows/repo-checks.yml b/.github/workflows/repo-checks.yml index c4a47cc9ba2..ceab1f6d179 100644 --- a/.github/workflows/repo-checks.yml +++ b/.github/workflows/repo-checks.yml @@ -134,7 +134,20 @@ jobs: - name: Run deterministic check manifest on main pushes if: github.event_name != 'pull_request' - run: python3 .github/scripts/run_checks.py --lane ci --base "${{ needs.changes.outputs.diff_base }}" --skip-pr-body-checks + env: + PR_BODY_FILE: /tmp/main-push-commit-body.txt + run: | + # On main pushes there is no PR body. GitHub folds the PR description + # into the merge commit message (fetch-depth: 0 gives us the full + # commit), so pass that through --pr-body-file instead of skipping the + # body-requiring checks. Without this, product-invariants cannot see + # the citations the merge commit carries and every main-push Hygiene + # run reports them as missing (see #9744). Fail-closed is preserved: + # a direct push whose message omits required invariant IDs still fails. + git log -1 --format=%B HEAD > "$PR_BODY_FILE" + python3 .github/scripts/run_checks.py --lane ci \ + --base "${{ needs.changes.outputs.diff_base }}" \ + --pr-body-file "$PR_BODY_FILE" - name: Check typed error flow-control ratchet run: python3 .github/scripts/check_isinstance_return_ratchet.py