mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #127] [MERGED] ci(cursor-review): scheduled bump workflow for the Cursor CLI version pin (BE-5870) #136
Labels
No labels
cursor-review-catalog-drift
groom
groom
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Comfy-Org/github-workflows#136
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/Comfy-Org/github-workflows/pull/127
Author: @mattmillerai
Created: 8/4/2026
Status: ✅ Merged
Merged: 8/4/2026
Merged by: @mattmillerai
Base:
main← Head:matt/be-5870-bump-cursor-cli-pin📝 Commits (1)
e2752c1ci(cursor-review): scheduled bump workflow for the Cursor CLI version pin (BE-5870)📊 Changes
2 files changed (+378 additions, -0 deletions)
View changed files
➕
.github/workflows/bump-cursor-cli-pin.yml(+372 -0)📝
AGENTS.md(+6 -0)📄 Description
ELI-5
Last week we stopped installing the Cursor CLI from a script that could change under us, and started installing one exact, checksummed version instead. That's safer, but nobody moves that version — so left alone the review panel would run an ever-older CLI forever. This adds a robot that checks once a week: if Cursor shipped a newer CLI, it downloads it, fingerprints it, asks a second source whether it got the same fingerprint, installs it to prove it actually works, and then opens a small two-line PR asking a human to approve moving the pin. Merging that PR automatically rolls the pin out to every repo that uses our review workflow.
What this adds
.github/workflows/bump-cursor-cli-pin.yml— a scheduled (Mondays 14:00 UTC) +workflow_dispatchjob that:https://cursor.com/installas data (there is deliberately nobash "$installer"anywhere in the file) and extracts the shipped version from itsdownloads.cursor.com/lab/<version>URL. An empty extraction is a hard::error::+exit 1, not a silent no-op — an installer-format change is exactly the vendor drift BE-5869 wants early warning about.^ CURSOR_CLI_VERSION:; equal → logs and exits 0 (no token minted, no branch touched).linux/x64/agent-cli-package.tar.gzfor the new version and computes its sha256.pkgs/by-name/cu/cursor-cli/package.nix), best-effort: same version + different hash → hard fail (a CDN-tamper signal is the whole point of the pin); nixpkgs on an older version → log "not yet updated, proceeding TOFU" and continue; fetch failure → log and continue. It is never a gate — nixpkgs lags releases..github/cursor-review/install-cursor-cli.sh(see judgment calls).sed -i, failing if either substitution changed nothing.ci/bump-cursor-cli-pin, and opens-or-updates a PR tomaintitledci(cursor-review): bump Cursor CLI pin to <version>.Structure, guards and comment style follow
bump-cursor-review-callers.yml:contents: readat workflow level,if: github.ref == 'refs/heads/main'job guard,concurrency: {group: bump-cursor-cli-pin, cancel-in-progress: false}around the stable branch,actions/create-github-app-token@d72941d… # v1.12.0withapp-id: ${{ vars.APP_ID }}+private-key: ${{ secrets.CLOUD_CODE_BOT_PRIVATE_KEY }}— verified byte-identical references to the bump fleet's.Also adds a 6-line entry to the AGENTS.md workflow catalog (the file was already over the aspirational 150-line target on
main; the checker still passes — warnings only, no new class of warning).Verification — the live pipeline, run for real
actionlint(which runsshellcheckover everyrun:block) is clean on the new file. The repo's four suites — cursor-review, agents-md-integrity, groom, bump-callers (+shellcheck -x) — all pass, andcheck_agents_md.py --root .passes.Beyond that I extracted every
run:block from the workflow verbatim and executed them inubuntu:24.04(--platform linux/amd64) against the live installer, the live CDN artifact and the live nixpkgs expression, with the pin seeded stale so the changed-path runs end to end. Transcript, abridged:Two things that transcript establishes beyond "the extraction parses today's format": the digest the workflow computes for the currently-shipped version is byte-identical to the pin BE-5869 landed (
702ad595…), and the SRI it derives is byte-identical to what nixpkgs independently recorded (sha256-cCrVlSE7…) — so the cross-check is genuinely comparing two independent fetches of the same URL, not comparing a value to itself. I also ran the discover step against a URL with nodownloads.cursor.com/lab/string and confirmed it fails loudly rather than no-opping:The two paths the sim can't cover are the App-token mint and the real
git push/gh pr create(stubbed, with their arguments asserted). Those are the parts copied verbatim from the bump fleet.Judgment calls (all deviations from the ticket, flagged)
ref: mainon the checkout (ticket said only "checkout …persist-credentials: false"). Without it, a re-run of an older scheduled run checks out that run's now-stalegithub.sha, and the force-push would publish a branch that reverts everything merged since. The bump fleet solves the same hazard by aborting on a stale tip; that would be wrong here — this job has no successor run to do the work, so a skip loses the week. Resolving the ref at run time keeps the bump correct instead of skipping it.--retry(not--retry-all-errors) on the artifact download. The ticket said "same curl hygiene"; I followedinstall-cursor-cli.sh's reasoning instead — a 404 there means the discovered version has no linux/x64 artifact, which is permanent, and retrying turns a clear error into an opaque one. The installer curl keeps--retry-all-errorsexactly as specified.install-cursor-cli.shagainst the proposed pin. A digest tells a reviewer nothing about whether the archive layout changed or whether the binary self-reports the pinned version — and a bad pin merged here breaks every caller's review. It reuses the single source of truth rather than forking a check, and runs after the nixpkgs cross-check on purpose, since it executes the downloaded binary.owner:on the token; addedpermission-contents: write+permission-pull-requests: write. Unlike the caller-bumping fleet this only writes to this repo, so the default repo-scoped installation token is both sufficient and narrower.groom.yml'sbuild_prjob already pushes a branch and opens a PR here with the same app, so the installation is known to cover this repo; I confirmed bothpermission-*inputs exist in the pinned v1.12.0 action manifest.cursor-review. A weekly two-line pin change doesn't warrant an 8-cell model panel; the human reviewer is the trust anchor and is the point. Easy to add later if wanted.not-yet-available/fetch-failed/not-availableall land in the PR body's table so the reviewer knows exactly how much corroboration this particular digest got.Risk
The riskiest line is the
sed -ipair that rewritescursor-review.yml, since a bad rewrite would break the review workflow for every consumer. It is guarded three ways: each key must match exactly one^ KEY:line before any edit (a restructured file aborts), each substitution must actually change the file, and the interpolated values are validated first (^[0-9A-Za-z][0-9A-Za-z._-]{0,63}$for the version,^[0-9a-f]{64}$for the digest) so nothing from a remote file reachessedunshaped. And the output is a PR, never a push tomain.Nothing here auto-merges, and no capability is denied or removed — the change is purely additive (one new workflow file + a catalog entry).
Closes BE-5870.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.