fix(release): stop smoke_beta silently skipping on promote-mode betas (#11582)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The release channel system re-smokes every published beta as post-publish verification (`smoke_beta`) > - The candidate-branch beta lane (#11209) added `verify_beta_candidate` to `publish_beta`'s needs; that job is skipped on every normal promote-mode beta > - `smoke_beta`'s condition has no status-check function, so GitHub attaches an implicit `success()` that evaluates the needs chain transitively — a skipped ancestor makes it false > - This pull request makes the condition explicit so promote-mode betas smoke again, and pins the shape in the workflow wiring test > - The benefit is that the post-publish beta gate actually runs instead of silently skipping ## Linked Issues or Issue Description **What happened?** Beta `2026.818.0-beta.0` (run 32082007439) published successfully, but its post-publish `smoke_beta` job was skipped. No configuration or input asked for that: the run was a plain `channel: beta` dispatch with `dry_run` at its default `false`, and the same expression `!inputs.dry_run` evaluated true inside `publish_beta`'s own steps (the Docker dispatch step ran). **Expected behavior** Every non-dry-run beta publish is followed by the release smoke suite against the exact published version, as documented in `doc/RELEASING.md` and `doc/RELEASE-CHECKLIST.md`. **Steps to reproduce** Dispatch `release.yml` with `channel: beta` promoting a nightly (promote mode). `verify_beta_candidate` is skipped by design; `publish_beta` runs through its explicit `!cancelled()` condition; `smoke_beta` then skips because its implicit `success()` sees the skipped ancestor in the transitive needs chain (actions/runner#2205 semantics). The beta published on 2026-08-11 predated #11209, so this never surfaced before. **Paperclip version or commit** master at `43ab441f0` (workflow file, current head). Related (not duplicates): #11209 introduced the candidate lane whose skipped job triggers this; #11208 covers the adjacent tag-push failure playbooks. ## What Changed - `smoke_beta`'s condition becomes `!cancelled() && needs.publish_beta.result == 'success' && !inputs.dry_run` — an explicit status-check function suppresses the implicit `success()`, and the result check keeps the dependency on a successful publish. - A comment above the job records why the explicit form is load-bearing. - `scripts/__tests__/release-verify-workflow.test.mjs` pins the new shape so the implicit form cannot silently return. ## Verification - `node --test scripts/__tests__/release-verify-workflow.test.mjs` — 8 pass, including the new assertion. - `release.yml` re-parsed as YAML. - The exact skip is visible on run 32082007439 (`smoke_beta: skipped` after `publish_beta: success`); the coverage gap for that beta was closed manually by dispatching `release-smoke.yml` with `paperclip_version: beta` (run 32084880767). - Not exercised end-to-end: the corrected condition needs the next real promote-mode beta to demonstrate; the expression change is minimal and the semantics are the documented actions/runner behavior. ## Risks - Low risk: condition-only change on one job plus a test. Dry runs still skip the smoke (`!inputs.dry_run` retained). Candidate-mode betas, where `verify_beta_candidate` actually runs, behave as before. ## Model Used Claude Fable 5 (Claude Code) ## Pre-submission checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template
This commit is contained in:
parent
4af55ba6bd
commit
2ec984502a
|
|
@ -623,9 +623,16 @@ jobs:
|
|||
|
||||
# Post-publish verification: run the release smoke suite against the exact
|
||||
# beta version that was just published.
|
||||
#
|
||||
# The condition must carry an explicit status-check function: without one,
|
||||
# GitHub attaches an implicit success(), which evaluates the needs chain
|
||||
# transitively — and publish_beta's chain contains verify_beta_candidate,
|
||||
# which is skipped on every promote-mode beta. The implicit form silently
|
||||
# skipped this job on the first promote-mode beta after the candidate
|
||||
# lane landed.
|
||||
smoke_beta:
|
||||
needs: publish_beta
|
||||
if: ${{ !inputs.dry_run }}
|
||||
if: ${{ !cancelled() && needs.publish_beta.result == 'success' && !inputs.dry_run }}
|
||||
uses: ./.github/workflows/release-smoke.yml
|
||||
with:
|
||||
paperclip_version: ${{ needs.publish_beta.outputs.beta_version }}
|
||||
|
|
|
|||
|
|
@ -60,6 +60,19 @@ test("candidate-branch betas are validated and fully verified before publish", (
|
|||
assert.match(releaseWorkflow, /needs\.verify_beta_candidate\.result == 'success'/);
|
||||
});
|
||||
|
||||
test("post-publish beta smoke survives the skipped candidate-verification ancestor", () => {
|
||||
const releaseWorkflow = readWorkflow("release.yml");
|
||||
|
||||
// publish_beta's needs chain contains verify_beta_candidate, which is
|
||||
// skipped on promote-mode betas. An `if:` without a status-check function
|
||||
// gets an implicit success() that evaluates that chain transitively and
|
||||
// silently skips the smoke. The condition must stay explicit.
|
||||
assert.match(
|
||||
releaseWorkflow,
|
||||
/smoke_beta:\n\s+needs: publish_beta\n\s+if: \$\{\{ !cancelled\(\) && needs\.publish_beta\.result == 'success' && !inputs\.dry_run \}\}/,
|
||||
);
|
||||
});
|
||||
|
||||
test("every lane's tag push degrades to recovery instructions when rejected", () => {
|
||||
const releaseWorkflow = readWorkflow("release.yml");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue