Skip to content

fix(ci): standing-PR templates — publish concurrency, LLM on publish, pnpm setup - #753

Merged
goosewobbler merged 15 commits into
mainfrom
fix/739-standing-pr-workflows
Oct 24, 2026
Merged

goosewobbler merged 15 commits into
mainfrom
fix/739-standing-pr-workflows

Conversation

@goosewobbler

@goosewobbler goosewobbler commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Fixes #739

  • Concurrency: in the template, ci-setup snippet and example, the standing PR's publish on merge and its retry label get a group per PR, so no other run can replace or cancel a queued publish. A merged release:immediate PR stays in the shared group with the updates, so the two don't write release/next at once. Other events on a closed PR run no job, so each gets a group of its own. Only a maintainer's edit on an open PR cancels.
  • Branch-delete guard: publish deletes the branch with --force-with-lease pinned to the merged PR's head commit, so the remote refuses the delete if an update has force-pushed it since. If the head can't be read, publish keeps the branch and warns. Cleanup errors stay warnings. GitPushOptions.forceWithLease accepts a { ref, expect } lease, and the forge's PullRequestDetails carries headSha.
  • immediate-release added to the ci-setup snippet and the example, reconciling with refresh-after-release.
  • LLM keys move to the publishing jobs; update-release-pr needs one only for release:preview-notes. Docs and troubleshooting say so.
  • Templates set up pnpm and use Node 24 (OIDC trusted publishing needs the newer npm), as does the release README's preview snippet. The npm hints say to drop pnpm/action-setup.
  • immediate-release skips the standing PR itself (head release/next, hardcoded like the label names), so a standing PR carrying release:immediate doesn't publish twice. The in-step check for a renamed branch is Release gate: a merged standing PR carrying release:immediate is released twice #792.
  • The example's immediate-release job removes the token .npmrc like its other publish jobs (whether that step is needed at all is Examples: drop the rm -f .npmrc step, which deletes the repo's own .npmrc rather than setup-node's #791). The ci-setup and example README text matches the new jobs.
  • deleteBranchOnMerge's description says when publish keeps the branch.

The standing PR's publish and updates no longer wait for each other, so an update during a publish can double-bump until the next update. Tracked in #790.

Made with Cursor

RetriggerView in GreptileConfidence Score: 3/5

The PR still needs changes before merging because branch cleanup can race an update and pending releases can still be dropped.

Summary

Updates the standing-PR workflows and adds a branch-tip check before publish cleanup.

  • Publishing skips deleting a release branch that has moved since the manifest was written.
  • Merged feeder pull requests can publish immediately and refresh the standing PR.
  • Release workflow templates set up pnpm and run on newer Node versions.
  • Workflow examples show where provider keys go for release-note generation.
  • The workflow examples explain how publish and update runs share a queue.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Update release branch] --> B[Commit and push]
  B --> C[Read releaseBranchSha]
  C --> D[Save manifest in PR comment]
  D --> E[Publish from manifest]
  E --> F[Fetch origin]
  F --> G{Fetched tip matches saved SHA?}
  G -->|No| H[Keep branch]
  G -->|Yes| I[Push branch deletion]
Loading

Reviews (2) · Last reviewed commit: "fix(release): guard release branch delet..." · Reviewed by Greptile

… pnpm setup

Fixes #739

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Standing release PR: #730 · v0.42.1 queued (4 packages) · open 9h 25m · ✅ ready to merge

Release Preview — v0.42.0 → v0.42.1

Note: Labels on this PR are advisory in standing-pr mode. Bumps come from conventional commits in the standing PR; override by editing labels on the standing PR itself. Add release:immediate to bypass the standing PR and release this PR directly.

These changes will be added to the release PR (#730) when merged:

Changelog

monorepo 0.42.0 → 0.42.1

Changed

  • move the setupGit ref seeds away from #729's status seed (release)
  • list every job in the standing-PR secrets table (ci)
  • pass LLM provider keys on immediate releases (ci)

Fixed

  • fall back to the event's head commit for the delete lease (release)
  • match the standing branch exactly, and harden the lease checks (ci)
  • keep immediate-release off the standing PR, and tidy hints (ci)
  • refuse a push lease whose expect isn't a commit SHA (git)
  • keep immediate releases queued with updates (ci)
  • lease the branch delete on the merged PR's head (release)
  • stop closed-PR events cancelling or replacing a publish (ci)
  • delete the release branch under a lease (release)
  • give closed-PR runs a group per PR so a queued publish isn't replaced (ci)
  • guard release branch delete against concurrent updates (release)
  • standing-PR templates — publish concurrency, LLM on publish, pnpm setup (ci) (#739)

All packages → 0.42.1 (sync versioning)

  • @releasekit/version
  • @releasekit/notes
  • @releasekit/publish
  • @releasekit/release

After merge — predicted release

No version escalation — this PR's changes will be included in the queued release without affecting the projected versions.

Package Standing PR This PR After merge
monorepo 0.42.1 0.42.1 0.42.1

Updated automatically by ReleaseKit

Comment thread templates/workflows/standing-pr.yml Resolved
Comment thread examples/ci/standing-pr/standing-pr.yml Resolved
Comment thread examples/ci/standing-pr/standing-pr.yml Resolved
Co-authored-by: Cursor <cursoragent@cursor.com>
@goosewobbler

Copy link
Copy Markdown
Owner Author

@greptile review

Co-authored-by: Cursor <cursoragent@cursor.com>
@goosewobbler

Copy link
Copy Markdown
Owner Author

@greptile review

github-actions Bot and others added 6 commits October 23, 2026 22:31
… replaced

The workflows had gone back to one shared group for push, schedule and
merge runs, which is the bug #739 reports: GitHub keeps one pending run
per group, so a newer push or schedule run replaced a queued publish. A
shared closed-PR group has the same flaw, since an ordinary PR closing
could replace it. Events on a closed PR (publish on merge, a retry label)
now each get a group per PR. The branch-delete guard already in this PR
covers the update that can now run alongside a publish.

Also:
- troubleshooting.md and the ci-setup troubleshooting row point the LLM
  key at the publishing jobs, not update-release-pr;
- the ci-setup update job lists all three provider keys again;
- a test checks the guard still deletes a branch whose tip matches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The table said "both jobs" for GITHUB_TOKEN and left retry-publish off
the NPM_TOKEN row, but the workflow now has four jobs and retry-publish
publishes too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both PRs added fields at the same spot in setupGit, so whichever merged
second conflicted. These seeds now sit elsewhere in the helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tip check and the delete were separate steps, so an update's
force-push landing between them was still deleted, and a failed fetch
left the check comparing stale data. Delete with --force-with-lease
pinned to the manifest's releaseBranchSha instead, which the remote
checks atomically, and keep cleanup errors as warnings so they can't
fail a finished publish. Drops Git.resolveRef, which only the old check
used, and validates releaseBranchSha in the manifest schema.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A maintainer's edit on a merged PR landed in the per-PR closed group
with cancel-in-progress on, so it cancelled a running publish. Only the
publish on merge and the retry label now use that group, events on a
closed PR that run no job get a group of their own, and only edits on
an open PR cancel.

The publish jobs now end with refresh-after-release, so an update that
ran during the publish is rebuilt once the tags exist. Also adds the
example immediate-release job's .npmrc step, restores the preview-notes
keys on the example update job, adds LLM keys to the ci-setup retry
job, and brings ci-setup, the example README and the release README's
preview snippet in line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
github-actions Bot and others added 2 commits October 24, 2026 03:58
The merged PR's head commit is what was merged, so lease the delete on
it instead of a manifest field. That also covers manifests written
before this change and a hand push to release/next before the merge.
If the head can't be read, or isn't a commit SHA, keep the branch and
warn. Adds headSha to the forge's PullRequestDetails and drops the
manifest's releaseBranchSha. A null lease no longer crashes the push.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only the standing PR's own merge and retry runs get a per-PR group. A
merged release:immediate PR goes back to the shared group, so it no
longer writes release/next at the same time as the update from its own
merge. Drops the reconcile step added to the publish jobs: it checks
the job's checkout, the tagged merge commit, before fetching main, so
it closed a standing PR an update had just opened.

The template moves to Node 24 like the example, since OIDC trusted
publishing needs a newer npm than Node 22 ships. The npm hints now say
to drop pnpm/action-setup, and the retry label notes mention the
concurrency group.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
github-actions Bot and others added 2 commits October 24, 2026 04:13
An empty expect means "only if the ref is absent" to git, and a symbolic
one is resolved locally, so either silently changes what the lease
checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
immediate-release now skips the standing PR itself, so a standing PR
carrying release:immediate doesn't publish twice. The npm hints also
swap `pnpm exec` for `npx`, the templates say pnpm/action-setup needs a
`packageManager` field or a `version`, and deleteBranchOnMerge says when
publish keeps the branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
github-actions Bot and others added 2 commits October 24, 2026 04:36
The immediate-release guard and the concurrency group matched any
`release/*` head, so a release:immediate hotfix from `release/hotfix-x`
was skipped and shipped nothing. Both now match `release/next`, the
hardcoded default like the label names.

The lease check is shared as isCommitSha from @releasekit/git, a lease
the remote refuses mid-update counts as a moved branch rather than a
failed delete, and the warning says whether the head was unreadable or
not a SHA. The deleteBranchOnMerge: false tests seed a head commit, so
they now fail if the flag is ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
If reading the merged PR from GitHub fails, the event payload that
triggered the publish already holds the same head commit, so use it
rather than keeping the branch. Also treats GitHub's "incorrect old
value provided" as a refused lease, not a failed delete.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@goosewobbler
goosewobbler merged commit 3d5bfb7 into main Oct 24, 2026
33 checks passed
@goosewobbler
goosewobbler deleted the fix/739-standing-pr-workflows branch October 24, 2026 03:55
@github-actions github-actions Bot mentioned this pull request Oct 24, 2026
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.

Standing-PR workflows: a queued publish can be dropped, immediate-release is missing, and the LLM key is on the wrong job

1 participant