Skip to content

fix(ci): skip the live suite without a key, and say the run measured nothing (#794) - #30

Merged
Birfy merged 2 commits into
mainfrom
fix/794-live-e2e-skip-without-key
Oct 23, 2026
Merged

Birfy merged 2 commits into
mainfrom
fix/794-live-e2e-skip-without-key

Conversation

@Birfy

@Birfy Birfy commented Oct 23, 2026

Copy link
Copy Markdown
Owner

Reproduce

live-e2e.yml reads the repository secret DEEPSEEK_API_KEY, and this repository has none (GET /actions/secrets → total_count: 0). Every scheduled run therefore died in Preflight before one check ran — five runs, same step, no evidence bundle:

##[error]DEEPSEEK_API_KEY is not configured as a repository secret
##[error]Process completed with exit code 1.

The step ran [ -n "$DEEPSEEK_API_KEY" ] || { echo "::error::..."; exit 1; }, and no step in the job carried a condition, so a keyless run could only be red. Reproduced locally by running the old step body with an empty environment: exit 1, and 0 gated steps in the file.

What changed

Five files, and the decision moved into a script so it can be tested:

  • .github/scripts/live-e2e-preflight.mjs — reads DEEPSEEK_API_KEY, publishes key=true|false to $GITHUB_OUTPUT. With no key it prints one ::warning and appends a summary saying the run measured nothing; it never fails the step.
  • .github/scripts/live-e2e-preflight.test.mjs — four cases (key present, empty, unset, and the script executed as the workflow runs it).
  • .github/workflows/live-e2e.yml — the preflight step calls the script; the six steps that need the key (npm ci, install DSH, clone the harness, start the tap, start the bench, run the four checks) plus the cleanup are gated on steps.preflight.outputs.key == 'true'; the header comment says why.
  • docs/subsystems/live-e2e.md — the invariant now separates the runner (still fails closed on a mock key, a loopback endpoint or the user's own home) from the workflow (skips when the key is absent).
  • changelog.d/794-live-e2e-skips-without-key.changed.md.

Evidence gate and Upload evidence needed no edit: they key off steps.run.outcome, which is skipped in a keyless run, so no artifact is published and no gate can pass on nothing.

What I ran

  • node --test ".github/scripts/*.test.mjs" → 246/246, including the four new cases
  • the preflight both ways, executed as the workflow does it: no key → exit 0, stdout one ::warning title=Live E2E skipped::, output key=false, five-line summary; key set → exit 0, no stdout, key=true, empty summary
  • the workflow parsed as YAML and asserted: 7 gated steps, no ungated step maps DEEPSEEK_API_KEY, cron 30 16 * * * and permissions: contents: read unchanged
  • node .github/scripts/testing-layers.mjs --check → 319 test file(s) in 12 workflow(s), every one classified
  • node .github/scripts/changelog.mjs check → 7 fragment(s) well formed
  • ARCH_DOCS_BASE=main node core/scripts/check-arch-docs.mjs → OK (5 changed files)

Red without the source change

  • On 10e26bb6, the preflight body with an empty key exits 1 with ::error:: — that is the five failed runs in the issue — and the file has 0 gated steps.
  • Exit 1 on a missing key again → only #794: the step exits 0 without a key… fails (3 pass, 1 fail).
  • ::warning changed back to ::error → two cases fail (2 pass, 2 fail), including the one that forbids an ::error::.
  • Removing the if: from a key-dependent step would let it run keyless and fail at Run the four checks, which is exactly what the gates exist to prevent.

Not run

  • actionlint — not installed on this machine; the workflow is checked by parsing it and by CI's own Lint the workflows step on this tip.
  • The suite itself: no key here, and that is the whole point of the change.
  • GitHub's own evaluation of the new if:s — only a run can show it. After this merges I will dispatch the workflow once on main and report the run: it should be green, carry the Live E2E skipped warning, produce no evidence artifact, and be reported as "measured nothing".

Risk

A keyless run is green while proving nothing. Three things keep that honest: the ::warning annotation, the step summary that says so in words, and no evidence artifact. A red still means the suite failed. The remaining downside is that losing the secret later would quiet the suite rather than shout — that is visible in every run summary, and ThinkFlowLab#794 stays open until a keyed run exists. The issue's own acceptance was "preflight passes with a real key, or the schedule is turned off"; this is a third path that keeps the schedule and makes the absence visible, so it is the owner's call to accept it.

Fixes ThinkFlowLab#794

…nothing (ThinkFlowLab#794)

`live-e2e.yml` reads DEEPSEEK_API_KEY, which this repository does not have, so every
scheduled run failed in Preflight before a single check ran: five runs, no evidence
bundle, and a red nobody could act on. The preflight now exits 0 with a warning,
publishes `key=false`, and the six steps that need the key are gated on it; a keyless
run does nothing and its summary says the run measured nothing. A failure inside the
suite still fails the run.
@Birfy

Birfy commented Oct 23, 2026

Copy link
Copy Markdown
Owner Author

Verdict: PASS at b6cdfbd
Written-by: Reviewer2

Ran:

  • CI at this tip: Test run 39905303492 success — ubuntu-latest · Node 24 · DSH 0.2.0-rc.2 success, package success (inside it Lint the workflows (actionlint) success and Tests of the repo scripts (risk tier, labels) success), tests-ok success, plugins (social/tree/timeline) success, merge-gate, reviewed tip, risk tier success — 9/9, all completed.
  • package job log: the four new cases ran for real in CI — #794: a configured key runs the suite and says nothing 1.18 ms, #794: a missing key published as an empty string skips the suite and warns 1.22 ms, #794: the step exits 0 without a key, writes key=false and appends the summary 41.18 ms, #794: with a key the step writes key=true and adds no warning or summary 33.85 ms.
  • Local: cd .github/scripts && node --test live-e2e-preflight.test.mjs → 4/4.
  • Kill 1 — make the step exit 1 when the key is missing: 3/4, only the step exits 0 without a key… red.
  • Kill 2 — WARNING changed from ::warning to ::error: 2/4, cases 2 and 3 red (the ::error spelling is what they forbid).
  • Kill 3 — remove the if: from Run the four checks, the step that maps the secret: 4/4, still green (see the first note).
  • Restored: 4/4.

What I checked:

  • Secret surface, read line by line: .github/workflows/live-e2e.yml maps secrets.DEEPSEEK_API_KEY exactly three times — the Preflight step (that is the decision step, so it has to read the key) and Start the real-model bench (line 128) and Run the four checks (line 136), both carrying if: steps.preflight.outputs.key == 'true'. Six keyed steps plus the always() && …key == 'true' cleanup carry the gate, 7 in total. No other step maps, echoes or reads the secret.
  • "Nothing ran" is not recorded as "ran": with key=false the run step is skipped, so Evidence gate (steps.run.outcome != 'skipped') is skipped too, and Upload evidence requires that gate's success — a keyless run cannot produce an artifact. The annotation ::warning title=Live E2E skipped:: and the step summary say in words that nothing was measured, and the body keeps Live E2E has failed on every scheduled run since it landed: the repository secret DEEPSEEK_API_KEY is not configured ThinkFlowLab/FlyBot#794 open until a keyed run exists.
  • The preflight only tests presence (typeof key === 'string' && key.length > 0) and never prints the value; the secret stays step-scoped, permissions: contents: read is unchanged, and the cron is unchanged.
  • A real failure still fails the run: the change replaces only the "no key" hard error; the bench, the checks and the evidence gate keep their behaviour, so a failing suite is still red.

Non-blocking:

  • The gating itself is not pinned by a committed test: deleting the if: from Run the four checks leaves all four tests green (kill 3). The body's "the workflow parsed as YAML and asserted: 7 gated steps, no ungated step maps DEEPSEEK_API_KEY…" is a check that was run, not one that lives in the repository. A small textual assertion in the style of test-workflow.test.mjs (every step whose env maps the secret, except the preflight, carries the gate) would close it. Not blocking, because the failure mode of a slipped gate is a visible red at that step, never a silent pass.
  • Green on this workflow now means "there was nothing to run", not "the suite passes". Anything that reads this check as suite health (a release checklist, a dashboard) is wrong until a keyed run exists.

@github-actions github-actions Bot added the pass label Oct 23, 2026
@Birfy
Birfy merged commit 5d25e71 into main Oct 23, 2026
9 checks passed
@Birfy
Birfy deleted the fix/794-live-e2e-skip-without-key branch October 23, 2026 05:29
Birfy added a commit that referenced this pull request Oct 23, 2026
…inkFlowLab#811) (#32)

`live-e2e.yml` skips every step that needs `DEEPSEEK_API_KEY` when the preflight publishes
`key=false`. Nothing tested that: on #30, deleting the `if:` from `Run the four checks` left
every test green. This reads the workflow as text, per step block, and fails when a step that
maps a secret loses its gate, when one of the seven key-consuming steps loses it, or when the
preflight itself becomes conditional. `live-e2e.yml` is unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Live E2E has failed on every scheduled run since it landed: the repository secret DEEPSEEK_API_KEY is not configured

1 participant