Skip to content

fix(ci): restore changesets version PR flow#462

Merged
tannerlinsley merged 1 commit into
mainfrom
taren/restore-changesets-version-pr
Jun 5, 2026
Merged

fix(ci): restore changesets version PR flow#462
tannerlinsley merged 1 commit into
mainfrom
taren/restore-changesets-version-pr

Conversation

@tannerlinsley
Copy link
Copy Markdown
Member

@tannerlinsley tannerlinsley commented Jun 5, 2026

Switches the release workflow back to changesets/action so pushes with pending changesets create or update a version PR, and merging that PR publishes packages. Removes the direct git push helper path that failed because checkout credentials were disabled.

Also brings the release pipeline closer to Router/Query parity:

  • supports main, alpha/beta/rc, vN, *-pre, and *-maint release branches
  • derives npm dist-tags in the workflow like Router/Query
  • enters Changesets prerelease mode for prerelease branches
  • creates a GitHub Release after packages publish

Validation:

  • node --check scripts/create-github-release.mjs
  • git diff --check
  • commit hook: pnpm build, pnpm test:unit, pnpm test:e2e

Summary by CodeRabbit

  • Chores

    • Refactored the release workflow and updated GitHub Actions concurrency, permissions, and credential handling
    • Removed legacy release helper scripts in favor of the new flow
  • New Features

    • Added automated release publishing and GitHub Release creation, including generated release notes and prerelease/tag handling

@tannerlinsley tannerlinsley requested a review from a team as a code owner June 5, 2026 19:56
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 5, 2026

Wondering what really moved? Review this PR in Change Stack to inspect semantic changes, definitions, and references.

Review Change Stack

📝 Walkthrough

Walkthrough

The PR refactors release automation: workflow concurrency/permissions and checkout behavior are updated; changeset-based versioning/publishing replaces custom prepare/detect/commit scripts; a new Node script builds and publishes annotated GitHub releases with generated changelogs.

Changes

Release Automation Refactor

Layer / File(s) Summary
Workflow concurrency and permissions configuration
.github/workflows/release.yml
Top-level concurrency grouped by workflow+ref with cancel-in-progress disabled; top-level permissions set to contents: read; release job condition simplified and job permissions updated; checkout persists credentials.
Changesets publishing flow & package.json cleanup
.github/workflows/release.yml, package.json
Replaces prior prepare/detect/commit/publish sequence with conditional pre-release, dist-tag determination, and changesets/action@v1.8.0 steps that run pnpm run changeset:version and pnpm run changeset:publish. Removed root release:* scripts.
Release script — setup & helpers
scripts/create-github-release.mjs
Adds a new Node release script with imports, token/config setup, and GitHub API helpers to resolve usernames and PR authors.
Release script — range detection & bumped packages
scripts/create-github-release.mjs
Detects current/previous CI release commits, determines bumped workspace packages by comparing package.json across commits, and sorts package list.
Release script — changelog generation
scripts/create-github-release.mjs
Generates grouped Markdown changelog from git log between releases: parses commit types/scopes/breaking flags, extracts PR numbers, and resolves usernames.
Release script — tag and GH release creation
scripts/create-github-release.mjs
Creates annotated tag if missing, writes notes to a temp file, invokes gh release create with --prerelease/--latest flags, and cleans up tags on failure; temp file always removed.

Sequence Diagram

sequenceDiagram
  participant GitHubActions
  participant ChangesetsAction
  participant ReleaseScript
  participant GH_CLI
  GitHubActions->>ChangesetsAction: run pnpm changeset:version & publish (with npm tag)
  ChangesetsAction->>GitHubActions: outputs published, dist-tag info
  GitHubActions->>ReleaseScript: invoke scripts/create-github-release.mjs (prerelease/latest flags)
  ReleaseScript->>GH_CLI: gh release create --notes-file --prerelease/--latest
  ReleaseScript->>GitHubActions: push annotated tag (if created)
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I hopped through commits and tags so neat,

nibbling changelogs in tidy little sheets,
Scripts once scattered, now dance in one file,
Releases roll smooth and make me smile,
🥕 Happy hops for CI that’s fleet!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: restoring the changesets version PR flow in the CI workflow, which is the core objective reflected throughout the refactored release.yml.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch taren/restore-changesets-version-pr

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 22-31: The checkout step currently sets persist-credentials: true
while the job has contents/id-token/pull-requests write permissions, so change
the actions/checkout@... step to set persist-credentials: false to avoid
exposing write-capable creds to intermediate steps, and then remove global
exposure by explicitly injecting the GITHUB_TOKEN env only into the
changesets/action step (i.e., add env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
to the specific changesets/action step) so write credentials are scoped to that
release step; reference the actions/checkout use block and the changesets/action
step when making these changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4afe44a2-e4b7-4ff4-850d-a8c4b2cf85c7

📥 Commits

Reviewing files that changed from the base of the PR and between 8f4d144 and b574b4c.

📒 Files selected for processing (4)
  • .github/workflows/release.yml
  • package.json
  • scripts/release-commit-and-push.mjs
  • scripts/release-detect-changes.mjs
💤 Files with no reviewable changes (3)
  • scripts/release-detect-changes.mjs
  • package.json
  • scripts/release-commit-and-push.mjs

Comment on lines 22 to +31
permissions:
contents: write
id-token: write
pull-requests: read
statuses: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: false
persist-credentials: true # changesets/action pushes version PR commits
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does actions/checkout with persist-credentials: true store the workflow token in local git config for later steps, and what do the changesets/action docs recommend when only the final push step needs git authentication?

💡 Result:

The actions/checkout action, with persist-credentials set to true (the default), provides the workflow token (or a specified PAT/SSH key) to git so that later steps in the same job can perform authenticated git operations [1][2]. Regarding how this is implemented: - In older versions (v5 and earlier), the authentication token was directly stored in the local.git/config file [3][4]. - In v6 and later, the action was improved to store credentials in a separate, more secure file under $RUNNER_TEMP rather than directly in.git/config [5]. Git is configured to point to this secure file, maintaining compatibility with git commands like push and fetch without requiring changes to your workflow scripts [5]. Recommendation for workflows where only a final step needs git authentication: If you are concerned about security or want to follow the principle of least privilege, you can set persist-credentials: false to opt-out of this behavior [1][6]. If you do this, the git configuration will not be automatically populated with the workflow token. When you reach the step that requires authentication (e.g., a git push), you will need to manually authenticate the git client using the token or secret, typically by providing the credentials in the environment or using a command like git config to inject them only at the necessary time [1][2]. Many users prefer this approach to avoid having active credentials available throughout the entire job's duration [3][7].

Citations:


🏁 Script executed:

cat -n .github/workflows/release.yml | head -60

Repository: TanStack/cli

Length of output: 2111


🌐 Web query:

changesets/action github authentication requirements persist-credentials false

💡 Result:

When using persist-credentials: false with the actions/checkout step in a workflow that includes changesets/action, you must manually provide the necessary GitHub authentication token to the changesets/action step [1][2][3]. By default, actions/checkout automatically persists a GitHub token in the local git configuration to allow authenticated git operations [4]. Setting persist-credentials: false disables this behavior, which is often done for security reasons or to use a specific Personal Access Token (PAT) that has elevated permissions (e.g., to trigger further workflow actions that the default GITHUB_TOKEN would ignore) [5][1][2]. If you disable credential persistence, changesets/action will fail to push changes or create release pull requests unless it has access to a valid authentication token [1][2][6]. You must explicitly provide this token by configuring the GITHUB_TOKEN environment variable within the changesets/action step, typically using a secret [1][2][3]. Example configuration: - name: Checkout Repo uses: actions/checkout@v4 with: persist-credentials: false - name: Run Changesets uses: changesets/action@v1 env: GITHUB_TOKEN: ${{ secrets.YOUR_PAT_SECRET }} Recent updates to changesets/action have introduced an explicit github-token input (defaulting to the GitHub-provided token), but if you have explicitly disabled persistence in your checkout step, ensuring that an appropriate token (like a PAT) is passed via the environment variable or input remains a critical requirement for successful git operations [7]. Additionally, ensure your workflow job has the necessary permissions (such as contents: write) to perform git pushes [1][8].

Citations:


Scope the write-capable git credentials to the release step.

Line 31 persists the job token before setup, build, and test commands run. Combined with the write permissions on lines 23–25, any compromised install or test script gains repo-write access throughout the entire job. Although actions/checkout v6.0.2 stores credentials in a secure file rather than .git/config, the token remains available to all intermediate steps; set persist-credentials: false and explicitly provide the token only to the changesets/action step via the GITHUB_TOKEN environment variable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml around lines 22 - 31, The checkout step
currently sets persist-credentials: true while the job has
contents/id-token/pull-requests write permissions, so change the
actions/checkout@... step to set persist-credentials: false to avoid exposing
write-capable creds to intermediate steps, and then remove global exposure by
explicitly injecting the GITHUB_TOKEN env only into the changesets/action step
(i.e., add env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} to the specific
changesets/action step) so write credentials are scoped to that release step;
reference the actions/checkout use block and the changesets/action step when
making these changes.

@tannerlinsley tannerlinsley force-pushed the taren/restore-changesets-version-pr branch from b574b4c to e49fe35 Compare June 5, 2026 20:52
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/create-github-release.mjs`:
- Around line 17-19: The fetch call building the GitHub search URL uses the raw
email variable and can produce invalid/unescaped query strings; update the URL
construction in the fetch that assigns to res so the email is URL-encoded (e.g.,
use encodeURIComponent on the email variable before inserting into `q=`) to
ensure reserved characters are escaped and the search works reliably, keeping
the existing headers/ghToken logic unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2e0b3395-afb3-42e4-84e7-87f0eee71ce0

📥 Commits

Reviewing files that changed from the base of the PR and between b574b4c and e49fe35.

📒 Files selected for processing (6)
  • .github/workflows/release.yml
  • package.json
  • scripts/create-github-release.mjs
  • scripts/prepare-release.mjs
  • scripts/release-commit-and-push.mjs
  • scripts/release-detect-changes.mjs
💤 Files with no reviewable changes (4)
  • scripts/release-detect-changes.mjs
  • scripts/prepare-release.mjs
  • scripts/release-commit-and-push.mjs
  • package.json

Comment on lines +17 to +19
const res = await fetch(`https://api.github.com/search/users?q=${email}`, {
headers: { Authorization: `token ${ghToken}` },
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

URL-encode the email search query.

This request builds q=... from the raw email string. Reserved URI characters are not escaped in that form, and MDN explicitly recommends encoding dynamic URL components with encodeURIComponent() instead of inserting them directly. That can make fallback attribution miss valid authors. (developer.mozilla.org)

💡 Proposed fix
-    const res = await fetch(`https://api.github.com/search/users?q=${email}`, {
+    const q = new URLSearchParams({ q: email })
+    const res = await fetch(`https://api.github.com/search/users?${q}`, {
       headers: { Authorization: `token ${ghToken}` },
     })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const res = await fetch(`https://api.github.com/search/users?q=${email}`, {
headers: { Authorization: `token ${ghToken}` },
})
const q = new URLSearchParams({ q: email })
const res = await fetch(`https://api.github.com/search/users?${q}`, {
headers: { Authorization: `token ${ghToken}` },
})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/create-github-release.mjs` around lines 17 - 19, The fetch call
building the GitHub search URL uses the raw email variable and can produce
invalid/unescaped query strings; update the URL construction in the fetch that
assigns to res so the email is URL-encoded (e.g., use encodeURIComponent on the
email variable before inserting into `q=`) to ensure reserved characters are
escaped and the search works reliably, keeping the existing headers/ghToken
logic unchanged.

@tannerlinsley tannerlinsley merged commit 2b38196 into main Jun 5, 2026
7 checks passed
@tannerlinsley tannerlinsley deleted the taren/restore-changesets-version-pr branch June 5, 2026 21:09
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.

2 participants