feat(workflow): generate diff-accurate upgrade-deps PR descriptions via Claude#1402
Merged
feat(workflow): generate diff-accurate upgrade-deps PR descriptions via Claude#1402
Conversation
✅ Deploy Preview for viteplus-preview canceled.
|
Member
Author
How to use the Graphite Merge QueueAdd the label auto-merge to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
Member
Author
|
@cursor review |
Member
Author
|
@cursor review |
Member
Author
|
ci works #1405 |
…aude Previously the `Upgrade Upstream Dependencies` workflow produced a generic template commit message and PR body (see #1401) that didn't reflect what actually changed. This wires up a second claude-code-action pass whose only job is to write a diff-accurate commit message and PR body. - `.github/scripts/upgrade-deps.mjs` now captures old -> new for every dependency it touches (including rolldown/vite tag + short SHA) and writes `versions.json`, `commit-message.txt`, and `pr-body.md` to `$UPGRADE_DEPS_META_DIR` (outside the repo, so not committed). - `.github/workflows/upgrade-deps.yml`: - Exports `UPGRADE_DEPS_META_DIR` via `$GITHUB_ENV` in a setup step. - Adds an "Enhance PR description with Claude" step that reads the baseline files + `git diff` and overwrites them with a concrete summary, a dependency table, and a real code-changes section. - Adds a "Read generated PR content" step that exposes the files as multi-line step outputs. - `peter-evans/create-pull-request` now consumes those outputs instead of a static template body. - Tightens the `check-upgrade-dependencies` final check to require BOTH `just build` AND `pnpm bootstrap-cli:ci && pnpm test` to pass (with manual snap-test diff inspection). - Bumps both `claude-code-action` pins to v1.0.99 (Claude Code 2.1.112). If the enhancement step fails, `continue-on-error` keeps the workflow going and the baseline content produced by the Node script is shipped instead of a generic message.
The closing prompt instruction only pointed at `build-upstream` failures, but the step also runs lint, `just build`, `pnpm test`, and snap tests. Enumerate every error class Claude is expected to fix, and call out snap-test regressions explicitly since `pnpm test` exits 0 even when snapshot outputs diverge — the agent must inspect the snap-test git diff and fix real regressions while leaving cosmetic version-string drift in place.
Bare-return and single-line `if` statements tripped the `curly` rule, and `isFullSha` was declared inside `writeMetaFiles` even though it didn't capture any parent-scope bindings. Hoist the helper to module scope and add braces to every single-statement `if`.
- Guarantee a trailing newline on commit-message.txt and pr-body.md before piping them through the heredoc into `$GITHUB_OUTPUT`. If Claude overwrites either file without a final `\n`, `cat` leaves the last line adjacent to the closing delimiter and GitHub Actions never terminates the multi-line value — producing a garbled body/commit. - Fail fast in `updatePnpmWorkspace` when a version regex no longer matches the YAML. Previously we silently recorded `(unset) -> new` even though `.replace` was a no-op, which would ship a misleading dependency table. A stale pattern now surfaces as an explicit error so the script can be updated.
- Consolidate the `check-upgrade-dependencies` Claude prompt: the three overlapping sections (old Instructions, Final check, "Help me fix") all described the same test/build/snap-test checks and sometimes contradicted each other. Replace with a single structured prompt (Background → Fixups → Final validation → Commit rule) where each requirement appears exactly once. - `updatePnpmWorkspace` now uses a single-pass `String.replace` with a callback, so the current version is captured during the substitution instead of via a separate `match` call. Drops the redundant `replacement` field from each entry and removes the "matched once but replace didn't match" edge case. - `getLatestTag` fetches only the newest tag (`?per_page=1`) instead of the default 30. - `updateCorePackage` now early-returns when `@vitejs/devtools` is absent, skipping the no-op JSON rewrite.
…e-deps Run 24545325671 showed the `Check upgrade dependencies` step stuck for 40+ minutes in a busy-wait loop: Claude had backgrounded `just build` and was polling `ps aux | grep "just build"` / `pgrep` / `sleep` every few seconds to check if it was done. Each poll was a full model round-trip, so the session never ended even though no real work was happening. - Add a 200-turn cap via `--max-turns 200` so a runaway agent session can no longer burn an unbounded amount of Actions time. - Add an explicit "Running long commands" rule to the prompt that forbids backgrounding (`&`, `nohup`, `disown`, etc.) and forbids polling with `ps`/`pgrep`/`sleep` loops. The Bash tool's 20-minute per-call timeout is plenty for `just build` and `pnpm test`, and foreground calls give Claude the exit code and output in one shot.
…s prompt The Bash tool's maximum per-call timeout is 10 minutes (600000 ms), not 20 minutes as the previous wording stated.
…back
Cursor Bugbot caught a high-severity bug introduced by the previous
single-pass refactor. The replace callback used:
(_match, prefix, oldVersion, suffix = '') => `${prefix}${newVersion}${suffix}`
`String.prototype.replace` always passes the match offset (a number) as
the next positional argument after the captures, so for the 6 patterns
with only two captures (vitest, tsdown, @oxc-node/cli, @oxc-node/core,
oxfmt, oxlint-tsgolint), `suffix` received the offset instead of
`undefined`. The `= ''` default never kicked in, and the offset got
appended to every version. Example: `tsdown: ^0.21.8` was rewritten to
`tsdown: ^9.9.90`. The earlier smoke test missed this because it used
substring `includes()`, which still matched.
Restructure each entry to use ONE capture group (just the version) plus
a literal `replacement` string. The callback signature is now
`(_match, captured)` and ignores the trailing offset/string args, so
the positional ambiguity is gone. Verified with a byte-exact equality
test on a synthetic fixture covering non-zero offsets.
6f90169 to
f8045cf
Compare
- Drop the redundant `[ -s ]` check in `ensure_trailing_newline`. If the file is empty, `tail -c1` returns nothing and `[ -n "" ]` is already false, so the size check adds nothing. - Trim the upgrade-deps regex-table comment to the only WHY worth preserving (oxlint's trailing `\n` disambiguates from oxlint-tsgolint). The callback-signature explanation just narrated the code and added noise. - Add `timeout-minutes: 180` to the `Check upgrade dependencies` step as a belt-and-suspenders guard. With `--max-turns 200` and the no-polling rule now in place, normal runs finish well under this cap; a runaway will be killed by Actions instead of consuming the full 6-hour job budget.
Member
Author
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit f173b91. Configure here.
Brooooooklyn
approved these changes
Apr 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Previously the
Upgrade Upstream Dependenciesworkflow shipped a generictemplate commit message and PR body (see #1401) that didn't reflect what
actually changed. This PR rewires the workflow so the commit and PR
description are generated from the real diff on every run.
What's new
Diff-accurate descriptions
.github/scripts/upgrade-deps.mjsrecords old → new for every dep ittouches (including rolldown/vite tag + short SHA) and writes
versions.json,commit-message.txt, andpr-body.mdto$UPGRADE_DEPS_META_DIR(in$RUNNER_TEMP, so they aren't committed)..github/workflows/upgrade-deps.yml:Set up metadata directorystep exportsUPGRADE_DEPS_META_DIRvia
$GITHUB_ENV.Enhance PR description with Claudestep reads the baselinefiles plus
git diffand overwrites them with a Summary, adependency table, a Code-changes list, and a Build-status block.
Read generated PR contentstep exposes the files as multi-linestep outputs (with a trailing-newline guard so the heredoc
terminator always lands on its own line).
peter-evans/create-pull-requestnow consumes those outputs insteadof a static template body.
continue-on-error: truekeeps theworkflow going and the baseline content from the Node script ships
instead of a generic message.
Tightened
Check upgrade dependenciespromptFinal validation → Commit rule. The previous prompt had three
overlapping sections describing the same checks.
just buildANDpnpm bootstrap-cli:ci && pnpm testto pass, plus a manual snap-testdiff inspection (because
pnpm testalways exits 0 even on snapshotdrift, so the agent has to look at the diff itself).
Running long commandsrule forbids backgrounding (&,nohup,disown, …) and polling (ps,pgrep,sleeploops, repeatedlson build artifacts). Run 24545325671 spent 30+ minutes spinning in a
ps aux | grep "just build"loop before this rule landed.Safety bounds on the Claude session
--max-turns 200caps total tool calls so a runaway agent can'tconsume an entire job budget.
timeout-minutes: 180on the step is a belt-and-suspenders cap onwall-clock time.
anthropics/claude-code-actionpins bumped to v1.0.99(Claude Code 2.1.112).
Script hygiene
getLatestTaguses?per_page=1and the rolldown + vite fetches runin parallel via
Promise.all.updatePnpmWorkspaceis now a single-passString.replacecallbackwith one capture group per pattern (avoids the foot-gun where the
replace callback's positional
suffixarg silently received the matchoffset and corrupted versions). Throws explicitly if a pattern goes
stale instead of silently recording a no-op change.
updateCorePackageearly-exits when@vitejs/devtoolsisn't present,skipping the no-op JSON rewrite.