Skip to content

test(ci): exercise the broken-main notifier while main is green - #2057

Merged
Smana merged 1 commit into
mainfrom
test/ci-notify-main-broken
Sep 17, 2026
Merged

Smana merged 1 commit into
mainfrom
test/ci-notify-main-broken

Conversation

@Smana

@Smana Smana commented Sep 17, 2026

Copy link
Copy Markdown
Owner

🔍 test

📝 Summary

notify-main-broken runs if: failure() && github.event_name == 'push', so a healthy
repository never runs it — its first run that matters is also its first run ever. It
shipped broken in #2052 for exactly that reason, and a red main went unreported, the
one outcome the job exists to prevent. #2053 fixed it, but nothing proves it stays fixed:
the job still cannot run until main actually breaks.

This runs it offline, every PR.

🎯 Changes

  • New suite scripts/test-ci-notify-main-broken.sh
  • Wired into the links job, which already installs pyyaml
  • scripts/AGENTS.md records what it covers and why

📊 Flow

flowchart LR
    yaml["ci.yaml"] -->|"run: + env:"| extract["Extract as the runner sees it"]:::new
    extract --> syntax["bash -n + heredoc column"]:::new
    extract --> drive["Drive from a non-git dir<br/>against a gh stub"]:::new
    drive --> cases["create · comment · must-fail"]:::new
    classDef new fill:#1e3a8a,stroke:#3b82f6,stroke-width:3px,color:#fff
Loading

🗂️ Files

File Type Summary
scripts/test-ci-notify-main-broken.sh new The suite
.github/workflows/ci.yaml modified One step in the links job
scripts/AGENTS.md modified What it covers, and the trap below
The design point: the env comes from the workflow

Two earlier versions of this test passed against a workflow with no GH_REPO at all.
They exported GH_REPO themselves and then asserted the branch logic — open a new issue
vs comment on the open one. That is the same gap as the defect they were written for:
testing the script's logic while the break was in how the workflow invokes it.

This version reads the step's env: out of ci.yaml and runs with that. Verified by
mutation rather than assertion — removing the GH_REPO line:

      step env: COMMIT_URL GH_TOKEN LABEL RESULTS RUN_URL
FAIL  workflow-env-fresh -> rc=1; output was:
      failed to run git: fatal: not a git repository (or any of the parent directories): .git
FAIL  workflow-env-existing -> rc=1
FAILED

That is the production error message, reproduced offline. Restored, it passes:

      step env: COMMIT_URL GH_REPO GH_TOKEN LABEL RESULTS RUN_URL
PASS  heredoc terminator at column 0 (line 16)
PASS  the run block is syntactically valid bash
PASS  workflow-env-fresh -> issue create (rc=0, outside a git repository)
PASS  workflow-env-existing -> issue comment (rc=0, outside a git repository)
PASS  gh-repo-removed -> failed as expected (rc=1)

The third case drops GH_REPO deliberately and requires the failure to come back — without
it the first two could pass for the wrong reason.

Why it parses YAML instead of slicing with sed

The run: block is a YAML block scalar containing a heredoc, and the heredoc terminator
has to land at column zero after YAML strips the common indent. Get that wrong and the
step is still valid YAML while being broken bash — invisible to every other gate here.
So the suite asserts the terminator's column explicitly, then bash -ns the result.

It runs in the links job rather than shellcheck because it needs that pyyaml. The
shellcheck job installs only shellcheck, and this repo does not treat "it happens to be in
the runner image" as a dependency declaration — the same reasoning the two checks above it
already carry.

🏷️ Labels

Tests, configuration changes

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Rendered manifest diff — this PR vs main (desired state)

No changes to the rendered desired state. ✅

`notify-main-broken` runs `if: failure() && github.event_name == 'push'`, so a
healthy repository never runs it and the first run that matters is also the
first run ever. It shipped broken in #2052 for exactly that reason -- no
checkout step, so every `gh` call died with

    failed to run git: fatal: not a git repository

and a red `main` went unreported, the one outcome the job exists to prevent.
#2053 fixed it with GH_REPO, but nothing proves it stays fixed: the job still
cannot run until `main` actually breaks.

This suite runs it offline. It extracts the step's `run:` block as the runner
sees it -- after YAML block-scalar de-indentation, which is why it parses YAML
rather than slicing with sed, since the body holds a heredoc whose terminator
must land at column zero -- and drives it from a directory that is not a git
repository, against a `gh` stub that refuses exactly as the real one does.

It takes the step's `env:` FROM THE WORKFLOW rather than supplying its own, and
that is the whole design. Two earlier versions of this test exported GH_REPO
themselves and asserted only the branch logic; both passed against a workflow
with no GH_REPO at all -- the same "tested the logic, not the invocation
context" gap as the defect they were written for. Verified by mutation:
removing the GH_REPO line from ci.yaml fails the suite with the production
error message, and restoring it passes.

Runs in the `links` job, which already installs the pyyaml it needs; the
shellcheck job installs only shellcheck, and this repo does not treat "it
happens to be in the runner image" as a dependency declaration.
@Smana
Smana force-pushed the test/ci-notify-main-broken branch from 8810cf0 to ef310ca Compare September 17, 2026 19:43
@Smana
Smana merged commit c45fc02 into main Sep 17, 2026
11 checks passed
@Smana
Smana deleted the test/ci-notify-main-broken branch September 17, 2026 19:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant