Skip to content

fix(ci): one-click release — go green when prepared; auto-PR is best-effort - #978

Merged
ranxianglei merged 2 commits into
masterfrom
2026-09-19_oneclick-green-on-prepared-fallback
Sep 19, 2026
Merged

ranxianglei merged 2 commits into
masterfrom
2026-09-19_oneclick-green-on-prepared-fallback

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

Part of #772

Problem

Run 35419218831 did everything right — version resolution, drift guard, bump, diff verify, full pre-flight gate, fallback branch push — and still ended as a red X because the final best-effort call (POST /pulls) hit the known account-level restriction ("GitHub Actions is not permitted to create or approve pull requests."). A red failure for a run whose actual deliverable (a gated, ready-to-merge release branch) succeeded invites panic loops and duplicate manual work.

Change (.github/workflows/release-manual.yml only, + AGENTS.md §5 doc sync)

Split the old monolithic "Commit and push to master" tail into two steps:

  1. Commit and push to master (id: push, strict): commit → direct push attempt → on block, push the fallback release branch. A failed branch push still exits 1 (red = real breakage). On success it sets needs_pr / pr_branch outputs and exits 0. The "direct push blocked" line downgrades from ::error:: to ::warning:: — it is now an expected, handled path.
  2. Open fallback PR (best effort) (continue-on-error: true, runs only when needs_pr): same API call as before, but the outcome no longer fails the job:
    • success → job summary + notice with the opened PR URL ("merge it to publish");
    • HTTP failure → job summary "NOTHING PUBLISHED YET" with the full response body plus a one-click /pull/new/<branch> link, mirrored as ::warning:: annotations.

The job summary renders on the run page itself, so the state is unmissable without opening logs. Red is now reserved for guard trips, gate failures, or a failed branch push — i.e. states where the release is NOT prepared.

Why green is honest here

The workflow's deliverable is a pre-flight-gated release commit sitting on a merge-ready branch. Auto-PR is convenience automation on top of it; its failure loses nothing (the branch persists, nothing publishes until a human merges). Green + loud "NOTHING PUBLISHED YET" summary beats a red X that hides the fact that preparation succeeded.

Verified

  • YAML parses (pyyaml): 13 steps, new step wired via steps.push.outputs.
  • bash -n clean on both modified scripts (Actions expressions substituted with literals).
  • Happy path untouched: direct-push-to-master exits before the new step, which skips on missing needs_pr.

If the account-level restriction is ever lifted, this same step auto-opens the PR and the run goes green with the PR URL — zero code changes needed.

@github-actions

github-actions Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

📦 Built Package Artifact

Branch: 2026-09-19_oneclick-green-on-prepared-fallback (f3895c4)

Option A — Install from npm PR tag (recommended)

npm install -g billion-context@pr-978

Each push to this PR publishes a new version under the pr-978 npm tag.

Option B — Download artifact

  1. Download the artifact from the Actions run
  2. Extract the tarball and install:
tar xzf billion-context-pr978.tgz
npm install -g package

Install instructions are refreshed on each push.

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

Reviewed the PR (verified the code against the description, checked CI) — found one critical gap in the first pass, which I fixed directly on the branch (commit f3895c4).

Verified as described

  • Diff matches the issue exactly: the monolithic tail split into a strict push step (id: push; "direct push blocked" downgraded ::error::::warning::; failed fallback-branch push still exits 1; sets needs_pr/pr_branch outputs) plus a best-effort PR step (continue-on-error: true, runs only when needs_pr == 'true', success and failure both render a job summary and exit 0). AGENTS.md §5 doc sync is accurate.
  • YAML parses (pyyaml): 13 steps, new step wired via steps.push.outputs.
  • Branch is 2 commits behind master (release v0.1.121 + its merge), but master touched neither file since the base — clean merge, GitHub reports mergeable: true.
  • CI was fully green on the original head (tests ×4 ubuntu/windows × node 22/24, codex e2e checks, version-guard, build-artifact).

Critical gap found (now fixed)
As written, the fallback path publishes directly, bypassing the human-merge gate. On master, the old step ended the fallback with exit 1, which silently short-circuited the four tail steps (Check if prereleaseCreate tagPublishCreate GitHub Release) — they carry no if: guards and were protected only by that failure. With the push step now exiting 0, those steps run in the same run: the tag is pushed, npm publish --tag latest fires from the runner, and a GitHub Release is created — while the job summary says "merge it to publish via CI". That contradicts the issue's own premise ("nothing publishes until a human merges") and leaves the repo worse off afterwards: master's package.json stays stale vs npm latest (the drift guard trips every subsequent one-click run), and merging the auto-opened PR later re-triggers release.yml, which fails trying to republish an already-published version.

Fix (commit f3895c4 on the PR branch)
Fail-closed positive gate instead of relying on step ordering:

  • the push step sets a direct=true output only when the direct push to master succeeded;
  • all four tail steps now carry if: steps.push.outputs.direct == 'true'.

Path check: direct push → tail runs (happy path unchanged); fallback → best-effort PR runs, tail skipped, green run, nothing published; failed branch push → red, nothing after. If the output were ever missing for any reason, the workflow fails closed (no publish). YAML re-validated: 13 steps, gates wired.

CI on the new head is running — I'll confirm in a follow-up.

中文摘要:发现并修复了一个关键缺陷——回退路径(直推被拒)下,原代码靠 exit 1 短路尾部的 tag/publish/release 步骤;本 PR 改成 exit 0 后未加门控,导致回退运行会绕过人工合并直接 npm publish 并打 tag、建 Release,与 issue 声称的"合并前不发布"矛盾,还会让后续 drift guard 和 release.yml 连环失败。已用 direct=true 输出对四个发布步骤做 fail-closed 门控并推回分支(f3895c4),其余改动与描述一致、原 head CI 全绿,新 head CI 确认后即可合并。

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 Powered by ework · qwen3.8-27b

CI confirmed on the fixed head (f3895c4): all 8 checks green — test matrix (ubuntu/windows × node 22/24), codex e2e (fake upstream + CODEX_HOME overlay), version-guard, build-artifact. PR is mergeable: true against current master.

Ready for you to merge — merging is human-only per repo rules: #978

中文摘要:修复提交(f3895c4)的 CI 已全部通过(8/8 绿),分支与当前 master 可干净合并,可以合并发布。

@ranxianglei
ranxianglei merged commit 94959ca into master Sep 19, 2026
8 checks passed
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.

1 participant