Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 13 additions & 45 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,53 +20,21 @@ permissions:
jobs:
release:
name: Release
if: "!contains(github.event.head_commit.message, 'ci: changeset release')"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
persist-credentials: true # release job pushes version changes
- name: Check for changesets
id: changesets
run: |
CHANGESET_FILES=$(ls .changeset/*.md 2>/dev/null | grep -v README.md || true)
if [ -z "$CHANGESET_FILES" ]; then
echo "has_changesets=false" >> "$GITHUB_OUTPUT"
else
echo "has_changesets=true" >> "$GITHUB_OUTPUT"
fi
- name: Start Nx Agents
if: steps.changesets.outputs.has_changesets == 'true'
run: npx nx-cloud start-ci-run --distribute-on=".nx/workflows/dynamic-changesets.yaml"
persist-credentials: true # changesets/action pushes Release PR commits
- name: Setup Tools
uses: TanStack/config/.github/setup@e4b48f16568324f76f467aa4c2aac2f05db632c3 # main
- name: Run Tests
if: steps.changesets.outputs.has_changesets == 'true'
run: pnpm run test:ci --parallel=3
- name: Stop Nx Agents
if: ${{ always() && steps.changesets.outputs.has_changesets == 'true' }}
run: npx nx-cloud stop-all-agents
- name: Run Build
run: pnpm run build:all
- name: Enter Pre-Release Mode
if: "contains(github.ref_name, '-pre') && !hashFiles('.changeset/pre.json')"
run: pnpm changeset pre enter pre
- name: Version Packages
run: pnpm run changeset:version
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Commit and Push Version Changes
id: commit
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add .
if git commit -m "ci: changeset release"; then
git push origin "HEAD:${GITHUB_REF_NAME}"
echo "committed=true" >> "$GITHUB_OUTPUT"
fi
- name: Determine dist-tag
if: steps.commit.outputs.committed == 'true'
id: dist-tag
run: |
BRANCH="${GITHUB_REF_NAME}"
Expand All @@ -77,18 +45,18 @@ jobs:
else
echo "latest=true" >> "$GITHUB_OUTPUT"
fi
- name: Publish Packages
if: steps.commit.outputs.committed == 'true'
- name: Create Release Pull Request or Publish
id: changesets
uses: changesets/action@63a615b9cd06ba9a3e6d13796c7fbcb080a60a0b # v1.8.0
Comment thread
coderabbitai[bot] marked this conversation as resolved.
with:
version: pnpm run changeset:version
publish: pnpm run changeset:publish ${{ steps.dist-tag.outputs.tag && format('--tag {0}', steps.dist-tag.outputs.tag) }}
title: 'ci: Version Packages'
commit: 'ci: changeset release'
env:
DIST_TAG: ${{ steps.dist-tag.outputs.tag }}
run: |
if [ -n "$DIST_TAG" ]; then
pnpm run changeset:publish --tag "$DIST_TAG"
else
pnpm run changeset:publish
fi
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Comment on lines +48 to +57

@coderabbitai coderabbitai Bot May 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check if NPM_TOKEN secret is configured in the repository

gh secret list --repo TanStack/router | grep -i npm

Repository: TanStack/router

Length of output: 207


🏁 Script executed:

cat -n .github/workflows/release.yml

Repository: TanStack/router

Length of output: 2735


🏁 Script executed:

rg "NPM_TOKEN|NPM|changesets" --type yaml

Repository: TanStack/router

Length of output: 4663


🌐 Web query:

changesets/action v1.8.0 NPM_TOKEN authentication requirements

💡 Result:

In changesets/action v1.8.0, the handling of NPM_TOKEN has been improved to better support modern authentication methods like Trusted Publishing [1][2]. Key changes and requirements regarding NPM_TOKEN authentication: 1. Intelligent.npmrc Generation: The action now only appends the auth token to the generated.npmrc file if NPM_TOKEN is explicitly defined [1][2]. This prevents the action from writing 'undefined' to the registry configuration, which previously caused issues when using OIDC tokens for Trusted Publishing [1][2]. 2. Trusted Publishing Support: If you are using Trusted Publishing (OIDC), you do not need to provide an NPM_TOKEN secret [3]. You should ensure your workflow has the necessary permissions (specifically id-token: write) [4][3]. In this configuration, you can omit the NPM_TOKEN environment variable entirely [3]. 3. Traditional Token Authentication: If you are still using a traditional NPM access token, you must continue to provide it as a secret named NPM_TOKEN and map it to the NPM_TOKEN environment variable in your workflow [5][6][3]. 4. Legacy Behavior and Workarounds: Some users have historically reported that the action requires the NPM_TOKEN environment variable to be present even when not strictly used for authentication (e.g., when using other methods to configure auth) [7][8]. If you encounter issues where the action fails to run or publish, ensure your environment configuration aligns with your chosen authentication method (either providing the secret or ensuring the action does not attempt to use a missing one) [9][10]. For most users, the recommended approach is to migrate to Trusted Publishing if possible, as it eliminates the need to manage long-lived NPM access tokens as GitHub secrets [3]. If you must use a token, ensure it is correctly mapped in the env section of your changesets/action step [5][3].

Citations:


NPM_TOKEN may not be required if using Trusted Publishing (OIDC), which appears to be configured; however, a critical bug exists in the pre-release dist-tag logic.

The workflow has id-token: write permission set, which suggests Trusted Publishing (OIDC) is in use. changesets/action@v1.8.0 supports OIDC and does not require NPM_TOKEN when configured this way. If you are using Trusted Publishing, the current configuration is correct. However, if you are using traditional NPM token authentication instead, add NPM_TOKEN: ${{ secrets.NPM_TOKEN }} to the env section.

More critically, pre-release distributions will be published with the wrong npm tag: when a branch matches *-pre, the workflow outputs prerelease=true but does not set tag output. Line 53 only applies --tag if tag output exists, so pre-releases will be published without an explicit tag, causing npm to default to latest—which incorrectly marks pre-releases as the latest stable version. Update line 53 to conditionally apply --tag pre for pre-releases:

-          publish: pnpm run changeset:publish ${{ steps.dist-tag.outputs.tag && format('--tag {0}', steps.dist-tag.outputs.tag) }}
+          publish: pnpm run changeset:publish ${{ steps.dist-tag.outputs.tag && format('--tag {0}', steps.dist-tag.outputs.tag) || (steps.dist-tag.outputs.prerelease == 'true' && '--tag pre') }}
📝 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
- name: Create Release Pull Request or Publish
id: changesets
uses: changesets/action@63a615b9cd06ba9a3e6d13796c7fbcb080a60a0b # v1.8.0
with:
version: pnpm run changeset:version
publish: pnpm run changeset:publish ${{ steps.dist-tag.outputs.tag && format('--tag {0}', steps.dist-tag.outputs.tag) }}
title: 'ci: Version Packages'
commit: 'ci: changeset release'
env:
DIST_TAG: ${{ steps.dist-tag.outputs.tag }}
run: |
if [ -n "$DIST_TAG" ]; then
pnpm run changeset:publish --tag "$DIST_TAG"
else
pnpm run changeset:publish
fi
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create Release Pull Request or Publish
id: changesets
uses: changesets/action@63a615b9cd06ba9a3e6d13796c7fbcb080a60a0b # v1.8.0
with:
version: pnpm run changeset:version
publish: pnpm run changeset:publish ${{ steps.dist-tag.outputs.tag && format('--tag {0}', steps.dist-tag.outputs.tag) || (steps.dist-tag.outputs.prerelease == 'true' && '--tag pre') }}
title: 'ci: Version Packages'
commit: 'ci: changeset release'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
🤖 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 48 - 57, The changesets action
step (id: changesets) can publish pre-releases with the wrong npm tag because
the publish input only applies --tag when steps.dist-tag.outputs.tag exists;
update the publish input so it conditionally uses steps.dist-tag.outputs.tag
when present otherwise uses 'pre' when steps.dist-tag.outputs.prerelease ==
'true' (i.e. pass pnpm run changeset:publish ${{ steps.dist-tag.outputs.tag &&
format('--tag {0}', steps.dist-tag.outputs.tag) ||
(steps.dist-tag.outputs.prerelease && '--tag pre') }} or equivalent expression
to ensure pre-releases get --tag pre). Also, if you are not using OIDC Trusted
Publishing, add NPM_TOKEN: ${{ secrets.NPM_TOKEN }} to the env block for the
changesets step so the action can authenticate with npm.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We use pre.json and OIDC trusted publishing

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@birkskyum, thanks for the clarification! Both parts of my original concern don't apply here:

  1. OIDC Trusted Publishing — confirmed by the id-token: write permission. NPM_TOKEN is not needed.
  2. Pre-release dist-tag — when changesets is in pre-release mode (via pre.json), changeset publish automatically applies the pre-release tag recorded in pre.json without needing an explicit --tag flag. My suggested fix was unnecessary.

The workflow is correct as-is. Apologies for the noise!

🐇 ✨


✏️ Learnings added
Learnt from: birkskyum
Repo: TanStack/router PR: 7404
File: .github/workflows/release.yml:48-57
Timestamp: 2026-05-15T19:10:38.427Z
Learning: In TanStack/router, the release workflow uses OIDC Trusted Publishing (id-token: write permission) and does NOT require NPM_TOKEN for npm authentication in the changesets/action step.

Learnt from: birkskyum
Repo: TanStack/router PR: 7404
File: .github/workflows/release.yml:48-57
Timestamp: 2026-05-15T19:10:38.427Z
Learning: In TanStack/router, the release workflow uses changesets pre-release mode managed via pre.json (created by `changeset pre enter pre`). When in pre-release mode, `changeset publish` automatically applies the pre-release tag from pre.json — an explicit `--tag` flag is not needed in the publish command.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

- name: Create GitHub Release
if: steps.commit.outputs.committed == 'true'
if: steps.changesets.outputs.published == 'true'
run: node scripts/create-github-release.mjs ${{ steps.dist-tag.outputs.prerelease == 'true' && '--prerelease' }} ${{ steps.dist-tag.outputs.latest == 'true' && '--latest' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
Loading