mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #110] [MERGED] ci(cursor-review): install the Cursor CLI from a sha256-pinned versioned artifact (BE-5869) #119
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#119
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/110
Author: @mattmillerai
Created: 8/3/2026
Status: ✅ Merged
Merged: 8/4/2026
Merged by: @mattmillerai
Base:
main← Head:matt/be-5869-pin-cursor-cli📝 Commits (3)
83902ffci(cursor-review): install the Cursor CLI from a sha256-pinned versioned artifact (BE-5869)140c4fdfix(cursor-review): harden + de-duplicate the pinned CLI installer (BE-5869)c98bd09Merge remote-tracking branch 'origin/main' into matt/be-5869-pin-cursor-cli📊 Changes
4 files changed (+132 additions, -161 deletions)
View changed files
📝
.github/cursor-review/README.md(+1 -0)➕
.github/cursor-review/install-cursor-cli.sh(+91 -0)📝
.github/workflows/cursor-review.yml(+33 -160)📝
.github/workflows/test-cursor-review-scripts.yml(+7 -1)📄 Description
ELI-5
Every Cursor review job used to install the Cursor CLI by piping a web page straight into
bash— whatevercursor.com/installserved at that moment ran on the runner, unverified. This PR downloads a specific, versioned Cursor release file instead, checks its sha256 against a hash written into the workflow, and only then unpacks it. If the file ever comes back different from what we pinned, the job goes red instead of quietly running unknown code.What changed
Single file:
.github/workflows/cursor-review.yml.enventries —CURSOR_CLI_VERSION(2026.07.23-e383d2b) andCURSOR_CLI_SHA256— so the pin is one place, moved only by a reviewed PR (or, later, the scheduled bump workflow from phase 2).Install Cursor agent CLIstep bodies (preflight, review matrix, consolidate) now downloadhttps://downloads.cursor.com/lab/${CURSOR_CLI_VERSION}/linux/x64/agent-cli-package.tar.gz, verify it withsha256sum -c, extract to~/.local/share/cursor-agent/versions/<version>, symlink~/.local/bin/cursor-agent, run--versionas a liveness assertion, and put~/.local/binon$GITHUB_PATH. The vendor installer script never executes.Log Cursor agent versioncomment in the review job was rewritten — it used to explain that the install was unpinned; it now states the install is pinned + checksum-verified and that the step exists for run forensics. The step itself is unchanged.The three step bodies are byte-identical apart from the preflight's existing
CURSOR_API_KEYskip guard (verified programmatically, not by eye — see below).Supersedes #105
#105 is still open at the time of writing. It rewrites these same three step bodies to download-then-execute the installer script. This PR supersedes those blocks entirely — the installer script no longer runs at all, so there is nothing left for #105's download-then-execute hardening to protect. Recommendation: merge this and close #105 (or drop its install-step hunks if it carries anything else). This PR is branched off
main, not stacked on #105, per the ticket.Why
cursor.com/installitself is not pinnedThat URL is mutable and regenerated on every Cursor release, so pinning its bytes would hard-red the review panel across every consumer repo the next time Cursor ships. Only the immutable, versioned
downloads.cursor.com/lab/...artifact is pinned. Old versioned URLs stay retained (spike BE-5864 probed back to 2026-06-04), so a routine Cursor release cannot break this — the pin only moves deliberately.Verification
curl -fsSL https://downloads.cursor.com/lab/2026.07.23-e383d2b/linux/x64/agent-cli-package.tar.gz | sha256sum→702ad595213bee5df0268be9f80a19f29fcceaa2a42fc55e39f2b5199051f0c4. Matches the pin. Artifact size 82,521,188 bytes (~83 MB), consistent with the--max-time 120sizing note in the step.actionlintclean on.github/workflows/cursor-review.yml, run with-shellcheckso everyrun:body is shellchecked too — clean.check_agents_md.pypasses (its one warning — no CODEOWNERS — is pre-existing onmain).--strip-components=1and the symlink are the load-bearing lines: the tarball has exactly one top-level entry,dist-package/, so--strip-components=1putscursor-agentdirectly in$dest.dist-package/cursor-agentships mode0755.cursor-agentis a 1,074-byte bash launcher thatexecs a bundlednodesibling in its own directory. It resolves that directory withdirname "$(realpath "$0")"under an explicit# handles symlinkscomment, so invoking it through~/.local/bin/cursor-agentfinds the bundled node correctly. This is the same versions-dir + symlink layout the vendor installer produces. The--versioncall in the same step is a belt-and-braces runtime proof before any later step depends on the binary.Judgment calls
2026.07.23-e383d2bverified clean against its recorded digest today, and shipping the version the spike cross-checked against nixpkgs is the lower-risk option. A bump is a one-line follow-up whenever it's wanted.agentsymlink — nothing in this workflow invokes that name, per the ticket.--max-time 120with--retry 3 --retry-max-time 300bounds the download at 300s, comfortably inside preflight'stimeout-minutes: 10(the tightest of the three jobs). The other two jobs are 30 and 15 minutes.Rollout
No new secrets, inputs, or caller-side changes. Consumers pick this up through the normal
bump-cursor-review-callersSHA bump after merge.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.