Update release workflow for NPM OIDC#28
Conversation
WalkthroughThe pull request upgrades GitHub Actions and yarn versions across CI/CD workflows (v4→v5 for standard actions, v1→v2 for Discord), restructures the publishing pipeline by consolidating separate prerelease and release workflows into a unified publish workflow, removes npm-token inputs from custom actions, and updates yarn configuration to version 4.12.0. Changes
Sequence Diagram(s)sequenceDiagram
participant GitHub
participant Workflow as publish.yml
participant Setup as Setup & Detect<br/>Changes
participant Release as Release Publish<br/>Job
participant Prerelease as Prerelease Publish<br/>Job
participant NPM as npm Registry
participant Repo as Repository
GitHub->>Workflow: Push to main
Workflow->>Workflow: Pre-CI: Extract commit message
Workflow->>Setup: Checkout & detect changes<br/>(types, common-solana, node)
Setup-->>Workflow: Expose changed flags
alt Commit message starts with [release]
Workflow->>Release: Condition: is release & repo matches
Release->>Release: Setup Node.js + build
Release->>NPM: Publish changed packages
NPM-->>Release: Published
else Normal commit
Workflow->>Prerelease: Condition: not release & repo matches
Prerelease->>Prerelease: Setup Node.js + build
Prerelease->>NPM: Bump & deploy prerelease
NPM-->>Prerelease: Deployed
Prerelease->>Repo: Commit with [SKIP CI] tag
Repo-->>Prerelease: Committed
end
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Comment |
Coverage reportCaution Test run failed
Test suite run failedFailed tests: 4/54. Failed suites: 1/8.Report generated by 🧪jest coverage report action from b200f42 |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/gh-release.yml (1)
23-36: Perfect! I've completed the verification. The review comment is correct - the gh-release.yml workflow is missing critical OIDC authentication configuration that is present in the publish.yml workflow.Key Findings:
publish.yml has OIDC permissions (lines 9-11):
permissions: id-token: write # Required for OIDC contents: readgh-release.yml is missing these permissions - it has no permissions block at all
Both workflows use the same create-release action that calls
yarn npm publish, but only publish.yml can provide OIDC tokens to authenticate with npmImpact: The gh-release.yml workflow will fail during npm publishing with authentication errors because it lacks the
id-token: writepermission needed for OIDC
Add OIDC permissions to the gh-release.yml workflow.
The workflow lacks the
id-token: writepermission required for OIDC authentication with npm. Add the permissions block after the trigger section:permissions: id-token: write # Required for OIDC contents: readThis matches the configuration in publish.yml and enables the create-release action to authenticate with npm via OIDC when executing
yarn npm publish.
🧹 Nitpick comments (1)
.github/workflows/benchmark.yml (1)
82-83: Consider updating deprecated GitHub Actions commands.Lines 82–83 use the deprecated
::set-outputand::add-masksyntax. While not changed in this PR, consider a follow-up refactor to use modern equivalents:- echo "::set-output name=network-endpoint::${NETWORK_ENDPOINT}" - echo "::add-mask::${NETWORK_ENDPOINT}" + echo "network-endpoint=${NETWORK_ENDPOINT}" >> $GITHUB_OUTPUT + echo "::add-mask::${NETWORK_ENDPOINT}"(Note:
add-maskdoes not have a direct replacement yet; this is a GitHub Actions limitation.)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (7)
.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjsis excluded by!**/.yarn/**.yarn/plugins/@yarnpkg/plugin-typescript.cjsis excluded by!**/.yarn/**.yarn/plugins/@yarnpkg/plugin-version.cjsis excluded by!**/.yarn/**.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjsis excluded by!**/.yarn/**.yarn/releases/yarn-3.1.1.cjsis excluded by!**/.yarn/**.yarn/releases/yarn-4.12.0.cjsis excluded by!**/.yarn/**yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (13)
.github/actions/create-prerelease/action.yml(2 hunks).github/actions/create-release/action.yml(1 hunks).github/workflows/benchmark.yml(2 hunks).github/workflows/discord.yml(1 hunks).github/workflows/gh-release.yml(1 hunks).github/workflows/node-docker.yml(2 hunks).github/workflows/pr.yml(2 hunks).github/workflows/prerelease.yml(0 hunks).github/workflows/publish.yml(1 hunks).github/workflows/release.yml(0 hunks).github/workflows/sync-deps.yml(1 hunks).yarnrc.yml(2 hunks)package.json(1 hunks)
💤 Files with no reviewable changes (2)
- .github/workflows/prerelease.yml
- .github/workflows/release.yml
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/publish.yml
31-31: "github.event.head_commit.message" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details
(expression)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Coverage report
🔇 Additional comments (13)
.github/workflows/benchmark.yml (2)
68-71: Approved: checkout action upgrade to v5.The upgrade from
actions/checkout@v4toactions/checkout@v5is in scope with the PR objectives. The configuration (fetch-depth, token) remains compatible and unchanged.
85-90: Approved: environment variable export and formatting.Line 85 correctly uses the modern
$GITHUB_ENVapproach for exportingNETWORK_ENDPOINT. The formatting adjustment to line 90 is a minor whitespace normalization with no semantic impact..github/workflows/sync-deps.yml (1)
18-20: Standard actions maintenance.Routine version bumps for checkout@v5 and setup-node@v5 maintain API compatibility. The jump from setup-node@v3→v5 is larger, but v5 is backwards-compatible with the current invocation pattern.
.github/workflows/node-docker.yml (1)
19-19: Standard actions maintenance in Docker build workflow.The upgrade to actions/checkout@v5 is routine and maintains compatibility with the current parameter usage (fetch-depth and token handling).
Also applies to: 42-42
.github/workflows/gh-release.yml (1)
11-11: Standard actions maintenance.The upgrade to actions/checkout@v5 and actions/setup-node@v5 maintains API compatibility and is routine maintenance.
Also applies to: 16-16
.github/workflows/pr.yml (1)
15-17: I'll verify the GitHub Actions version upgrades by examining the workflow file and researching the changes in v5.
<function_calls>
GitHub Actions checkout@v5 changes release notes
</function_calls><function_calls>
GitHub Actions setup-node@v5 breaking changes
</function_calls><function_calls>
#!/bin/bashExamine the workflow file to confirm the changes
if [ -f .github/workflows/pr.yml ]; then
echo "=== Lines 10-20 (around line 15-17) ==="
sed -n '10,20p' .github/workflows/pr.yml
echo ""
echo "=== Lines 45-55 (around line 49-52) ==="
sed -n '45,55p' .github/workflows/pr.yml
else
echo "Workflow file not found"
fi
</function_calls>Please wait while I gather information about the GitHub Actions upgrades and examine the workflow file.
.yarnrc.yml (1)
5-22: <function_calls>
``` "yarn version" command Yarn 4 how to bump version without plugin ```Yarn 4.0 release notes changelog version command plugin removalpackage.json (1)
60-60: Yarn 4 upgrade appears properly configured; no breaking change violations detected.The upgrade from yarn@3.1.1 to yarn@4.12.0 is well-implemented in this repository. Verification confirms:
- .yarnrc.yml is properly configured with
nodeLinker: node-modules(avoiding PnP complexity) and correctyarnPathpointing to yarn-4.12.0.cjs- Node version: All workflows use
lts/*(Node 20+), meeting Yarn 4's Node 18+ minimum requirement- Yarn commands: No deprecated Yarn 3 flags (e.g.,
--frozen-lockfile) are used in workflows; all commands (yarn install,yarn build,yarn workspaces foreach) are compatible with Yarn 4- No custom plugins: No evidence of plugins requiring API updates
The repository's Yarn 4 migration follows recommended practices and no actionable issues remain.
.github/workflows/discord.yml (1)
14-14: API compatibility confirmed — no action required.The upgrade to
rjstone/discord-webhook-notify@v2is backward-compatible. Version 2 maintains support for all current input parameters (webhookUrl, color, avatarUrl, details, description, footer), so no workflow modifications are needed. The action's maintainers confirm that v2 is stable for existing users, with breaking changes expected only in future major versions (v3+)..github/actions/create-release/action.yml (1)
16-18: Verify npm OIDC authentication is properly configured end-to-end.With the removal of the
NPM_TOKENenvironment variable, this action now relies on npm CLI automatically detecting OIDC environments and using them for authentication. However, successful OIDC authentication requires npm CLI version 11.5.1 or later and that each package has a trusted publisher configured on npmjs.com.The workflow calling this action (publish.yml) correctly sets the required
id-token: writepermission, but ensure:
- The npm/yarn version in use includes npm CLI >= 11.5.1
- Each package (types, common-solana, node) has a trusted publisher configured on npmjs.com matching the workflow name
- The workflow filename in npmjs.com settings exactly matches
publish.yml(filename is case-sensitive).github/workflows/publish.yml (3)
122-173: Verify prerelease action also doesn't require npm credentials.The prerelease job similarly relies on OIDC authentication via the
create-prereleaseaction (which the AI summary indicates also had npm-token removed). Ensure the same npm >= 11.5.1 requirement is met, and that each package has trusted publisher configuration allowing prerelease publishing from thepublish.ymlworkflow.The overall structure of consolidating prerelease and release jobs into a single workflow is good, and the use of change detection flags to conditionally publish only modified packages is sound. Pending verification of npm versions and OIDC setup.
9-11: LGTM: OIDC permissions correctly configured.The workflow properly declares
id-token: writepermission, which is the critical requirement that allows GitHub Actions to generate OIDC tokens for npm package publishing. The prerelease job correctly uses an explicitsecrets.REPO_TOKENfor git operations.
74-120: Based on my verification, I can now provide the rewritten review comment:
The npm version concern is unfounded—the workflow explicitly updates npm to the latest version.
The release job (line 93) runs
npm install -g npm@latest, which ensures npm is updated to the latest version after Node.js setup. Node.js LTS v24 bundles npm v11.6.2, and the explicit upgrade tonpm@latestguarantees the version will exceed the minimum v11.5.1 required for OIDC trusted publishing. Yarn 4.12.0 does not bundle npm; it uses the system npm, so the OIDC authentication will work correctly with this setup.Likely an incorrect or invalid review comment.
| description: 'token to push to npm registry' | ||
| required: true | ||
|
|
||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
Script executed:
#!/bin/bash
# Find workflows calling create-prerelease or create-release actions
echo "=== Searching for workflows calling create-prerelease or create-release ==="
fd -t f '\.(yml|yaml)$' '.github/workflows' | while read workflow; do
if grep -l 'create-prerelease\|create-release' "$workflow" 2>/dev/null; then
echo "Found workflow: $workflow"
fi
done
echo ""
echo "=== Full content of workflows calling these actions ==="
fd -t f '\.(yml|yaml)$' '.github/workflows' -x grep -l 'create-prerelease\|create-release' {} \; | while read workflow; do
echo "--- File: $workflow ---"
cat -n "$workflow"
echo ""
doneRepository: subquery/subql-solana
<shell_result>
Repository: subquery/subql-solana
Exit code: 0
stdout:
=== Searching for workflows calling create-prerelease or create-release ===
.github/workflows/gh-release.yml
Found workflow: .github/workflows/gh-release.yml
.github/workflows/publish.yml
Found workflow: .github/workflows/publish.yml
=== Full content of workflows calling these actions ===
--- File: .github/workflows/gh-release.yml ---
1 name: "Github Release"
2 on:
3 workflow_dispatch:
4
5 jobs:
6 github-release:
7 name: github-release
8 runs-on: ubuntu-latest
9 steps:
10 #Check out
11 - uses: actions/checkout@v5
12 with:
13 fetch-depth: 100
14
15 - name: Setup Node.js environment
16 uses: actions/setup-node@v5
17 with:
18 node-version: lts/*
19
20 - run: yarn install
21
22 #Create github releases
23 - uses: ./.github/actions/create-release
24 with:
25 package-path: packages/common-solana
26 repo-token: ${{ secrets.REPO_TOKEN }}
27
28 - uses: ./.github/actions/create-release
29 with:
30 package-path: packages/node
31 repo-token: ${{ secrets.REPO_TOKEN }}
32
33 - uses: ./.github/actions/create-release
34 with:
35 package-path: packages/types
36 repo-token: ${{ secrets.REPO_TOKEN }}
--- File: .github/workflows/publish.yml ---
1 name: "Publish"
2 on:
3 push:
4 branches:
5 - main
6 paths-ignore:
7 - ".github/workflows/**"
8
9 permissions:
10 id-token: write # Required for OIDC
11 contents: read
12
13 concurrency:
14 group: publish
15 cancel-in-progress: false
16
17 jobs:
18
19 pre-ci:
20 name: Pre-CI (Extract Commit Message)
21 runs-on: ubuntu-latest
22 timeout-minutes: 1
23 outputs:
24 commit-message: ${{ steps.get_commit_message.outputs.commit-message }}
25 steps:
26 - uses: actions/checkout@v5
27 with:
28 fetch-depth: 0
29
30 - id: get_commit_message
31 run: |
32 COMMIT_MSG_TEMP="${{ github.event.head_commit.message }}"
33 if [ -n "$COMMIT_MSG_TEMP" ]
34 then
35 commit_msg="$COMMIT_MSG_TEMP"
36 echo "commit-message=${commit_msg}" | head -n 1 >> "$GITHUB_OUTPUT"
37 else
38 commit_message=$(git log -1 --pretty=%B | head -n 1)
39 echo "commit-message=$commit_message" >> "$GITHUB_OUTPUT"
40 fi
41
42 - name: Debug commit message
43 run: |
44 echo "Commit message: ${{ steps.get_commit_message.outputs.commit-message }}"
45
46 setup:
47 name: Setup & Detect Changes
48 needs: pre-ci
49 runs-on: ubuntu-latest
50 outputs:
51 changed-types: ${{ steps.changed-types.outputs.changed }}
52 changed-common-solana: ${{ steps.changed-common-solana.outputs.changed }}
53 changed-node: ${{ steps.changed-node.outputs.changed }}
54 steps:
55 - uses: actions/checkout@v5
56 with:
57 fetch-depth: 100 # Needed to detect changes by having commit history
58
59 - uses: marceloprado/has-changed-path@v1
60 id: changed-types
61 with:
62 paths: packages/types
63
64 - uses: marceloprado/has-changed-path@v1
65 id: changed-common-solana
66 with:
67 paths: packages/common-solana
68
69 - uses: marceloprado/has-changed-path@v1
70 id: changed-node
71 with:
72 paths: packages/node
73
74 release:
75 name: Release Publish
76 needs: [pre-ci, setup]
77 if: >
78 !startsWith(github.event.head_commit.message, '[SKIP CI]')
79 && startsWith(github.event.head_commit.message, '[release]')
80 && github.repository == 'subquery/subql-solana'
81 runs-on: ubuntu-latest
82 steps:
83 - uses: actions/checkout@v5
84 with:
85 fetch-depth: 0
86
87 - name: Setup Node.js environment
88 uses: actions/setup-node@v5
89 with:
90 node-version: lts/*
91
92 - name: Update npm
93 run: npm install -g npm@latest
94
95 - run: yarn
96
97 - name: build
98 run: yarn build
99
100 # Publish to npm and github releases
101 - name: Publish Types
102 if: needs.setup.outputs.changed-types == 'true'
103 uses: ./.github/actions/create-release
104 with:
105 package-path: packages/types
106 repo-token: ${{ secrets.REPO_TOKEN }}
107
108 - name: Publish Common Solana
109 if: needs.setup.outputs.changed-common-solana == 'true'
110 uses: ./.github/actions/create-release
111 with:
112 package-path: packages/common-solana
113 repo-token: ${{ secrets.REPO_TOKEN }}
114
115 - name: Publish Node
116 if: needs.setup.outputs.changed-node == 'true'
117 uses: ./.github/actions/create-release
118 with:
119 package-path: packages/node
120 repo-token: ${{ secrets.REPO_TOKEN }}
121
122 prerelease:
123 name: Prerelease Publish
124 needs: [pre-ci, setup]
125 if: >
126 !startsWith(needs.pre-ci.outputs.commit-message, '[SKIP CI]')
127 && !startsWith(needs.pre-ci.outputs.commit-message, '[release]')
128 && github.repository == 'subquery/subql-solana'
129 runs-on: ubuntu-latest
130 steps:
131 - uses: actions/checkout@v5
132 with:
133 fetch-depth: 0
134 token: ${{ secrets.REPO_TOKEN }} # Needed to push changes back to repo
135
136 - name: Setup Node.js environment
137 uses: actions/setup-node@v5
138 with:
139 node-version: lts/*
140
141 - name: Update npm
142 run: npm install -g npm@latest
143
144 - run: yarn
145
146 - name: build
147 run: yarn build
148
149 # Prerelease publish steps
150 - name: Bump types & deploy
151 if: needs.setup.outputs.changed-types == 'true'
152 uses: ./.github/actions/create-prerelease
153 with:
154 package-path: packages/types
155
156 - name: Bump common Solana & deploy
157 if: needs.setup.outputs.changed-common-solana == 'true'
158 uses: ./.github/actions/create-prerelease
159 with:
160 package-path: packages/common-solana
161
162 - name: Bump node & deploy
163 if: needs.setup.outputs.changed-node == 'true'
164 uses: ./.github/actions/create-prerelease
165 with:
166 package-path: packages/node
167
168
169 - name: Commit changes
170 uses: EndBug/add-and-commit@v9
171 with:
172 message: "[SKIP CI] Prerelease"
173 default_author: github_actions
</shell_result>
Script executed:
#!/bin/bash
# First, check the full create-prerelease action.yml file
echo "=== Full create-prerelease action.yml ==="
cat -n .github/actions/create-prerelease/action.yml
echo ""
echo "=== Searching for .npmrc or npmrc configuration files ==="
fd -t f '\.npmrc|npmrc' .
echo ""
echo "=== Checking for OIDC or getIDToken references in workflows ==="
rg -n 'getIDToken|OIDC|npm.*token|OIDC' '.github/workflows/' -i
echo ""
echo "=== Checking for npm configuration steps in publish workflow ==="
rg -n -A5 -B5 'npm.*config|\.npmrc' '.github/workflows/publish.yml'Repository: subquery/subql-solana
<shell_result>
Repository: subquery/subql-solana
Exit code: 1
stdout:
=== Full create-prerelease action.yml ===
1 # Composite action needed to access github context
2
3 # This is to compensate for yarn 3 issue https://github.com/yarnpkg/berry/issues/3868
4 name: 'Remove Stable Versions'
5 description: 'This will remove stableVersion from packages for prerelease'
6 inputs:
7 package-path:
8 description: 'package path to run action e.g. package/common'
9 required: true
10
11 runs:
12 using: "composite"
13 steps:
14 - working-directory: ${{ github.workspace }}
15 run: node ${{ github.action_path }}/remove-stable-version.js ${{ github.workspace }}/${{ inputs.package-path }}
16 shell: bash
17
18 - working-directory: ${{ inputs.package-path }}
19 run: echo "Changes exist in ${{ inputs.package-path }}" && yarn version prerelease && yarn npm publish --access public --tag dev
20 shell: bash
=== Searching for .npmrc or npmrc configuration files ===
=== Checking for OIDC or getIDToken references in workflows ===
.github/workflows/publish.yml:10: id-token: write # Required for OIDC
=== Checking for npm configuration steps in publish workflow ===
</shell_result>
Script executed:
#!/bin/bash
# Check if there are any other npm/node setup actions or scripts
echo "=== Checking actions/setup-node@v5 for OIDC capabilities ==="
rg -n 'registry-url|scope\|npm-auth' '.github/workflows/publish.yml'
echo ""
echo "=== Checking remove-stable-version.js for any env setup ==="
if [ -f '.github/actions/create-prerelease/remove-stable-version.js' ]; then
head -50 '.github/actions/create-prerelease/remove-stable-version.js'
fi
echo ""
echo "=== Check full create-release action for comparison ==="
cat -n '.github/actions/create-release/action.yml'Repository: subquery/subql-solana
<shell_result>
Repository: subquery/subql-solana
Exit code: 0
stdout:
=== Checking actions/setup-node@v5 for OIDC capabilities ===
=== Checking remove-stable-version.js for any env setup ===
const fs = require('fs');
const myArgs = process.argv.slice(2);
const pJson = require(`${myArgs[0]}/package.json`)
if (pJson.stableVersion){
delete pJson.stableVersion
fs.writeFileSync(`${myArgs[0]}/package.json`, JSON.stringify(pJson, null, 2))
}
=== Check full create-release action for comparison ===
1 # Composite action needed to access github context
2
3 name: 'Create Release'
4 description: 'This will publish to NPM registry and create Github release'
5 inputs:
6 package-path: # id of input
7 description: 'package path to run action e.g. package/common'
8 required: true
9 repo-token:
10 description: 'token to create github release'
11 required: true
12
13 runs:
14 using: "composite"
15 steps:
16 - working-directory: ${{ inputs.package-path }}
17 run: echo "Changes exist in ${{ inputs.package-path }}" && yarn npm publish --access public
18 shell: bash
19
20 - working-directory: ${{ github.workspace }}
21 run: node ${{ github.action_path }}/gh-release-script.js ${{ github.workspace }}/${{ inputs.package-path }} ${{ github.sha }}
22 env:
23 REPO_TOKEN: ${{ inputs.repo-token }}
24 shell: bash
</shell_result>
Script executed:
#!/bin/bash
echo "=== Searching for yarn config files ==="
fd -t f '\.yarnrc' .
echo ""
echo "=== Searching for .yarnrc.yml ==="
fd -t f '\.yarnrc\.yml' .
echo ""
echo "=== Full content if found ==="
if [ -f '.yarnrc.yml' ]; then
cat -n '.yarnrc.yml'
fi
echo ""
echo "=== Checking for any npmrc or yarnrc in .github directory ==="
find .github -type f -name '.*rc*' 2>/dev/null
echo ""
echo "=== Check package.json scripts for npm config ==="
rg -n '"version|"publish' package.json -A2 -B2Repository: subquery/subql-solana
<shell_result>
Repository: subquery/subql-solana
Exit code: 1
stdout:
=== Searching for yarn config files ===
=== Searching for .yarnrc.yml ===
=== Full content if found ===
1 changesetBaseRefs:
2 - main
3 - origin/main
4
5 changesetIgnorePatterns:
6 - .yarn/**/*
7
8 compressionLevel: mixed
9
10 enableGlobalCache: false
11
12 enableImmutableInstalls: false
13
14 enableProgressBars: false
15
16 nodeLinker: node-modules
17
18 npmAuthToken: "${NPM_TOKEN:-}"
19
20 npmPublishRegistry: "https://registry.npmjs.org"
21
22 yarnPath: .yarn/releases/yarn-4.12.0.cjs
=== Checking for any npmrc or yarnrc in .github directory ===
=== Check package.json scripts for npm config ===
</shell_result>
Perfect. Now I have all the information needed. The verification reveals a critical issue: The .yarnrc.yml file expects NPM_TOKEN environment variable (line 18), but the workflow never sets it despite having the id-token permission.
Here's the final rewritten review comment:
Verify OIDC token is exported to NPM_TOKEN environment variable before calling create-prerelease.
The npm-token input has been removed, aligning with the PR objective to migrate to NPM OIDC. However, the migration is incomplete: .yarnrc.yml (line 18) requires npmAuthToken: "${NPM_TOKEN:-}" to be set, but the publish.yml workflow never exports the OIDC token.
Current state:
publish.ymlhaspermissions: id-token: write(line 10) ✓- Missing: No step calls
core.getIDToken()to retrieve and export the OIDC token asNPM_TOKEN create-prereleaseaction receives no authentication mechanismyarn npm publishwill fail with 401 Unauthorized whenNPM_TOKENevaluates to empty
Required fix: Add a step in the prerelease job to export the OIDC token:
- name: Get OIDC token
id: oidc
run: echo "NPM_TOKEN=$(curl -s -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "${ACTIONS_ID_TOKEN_REQUEST_URL}?audience=npm")" >> $GITHUB_ENV
env:
ACTIONS_ID_TOKEN_REQUEST_URL: ${{ env.ACTIONS_ID_TOKEN_REQUEST_URL }}
ACTIONS_ID_TOKEN_REQUEST_TOKEN: ${{ env.ACTIONS_ID_TOKEN_REQUEST_TOKEN }}Or use an action like actions/create-github-app-token that exports NPM_TOKEN before calling create-prerelease.
Also applies to: 19-19
🤖 Prompt for AI Agents
.github/actions/create-prerelease/action.yml around lines 10 and 18-19: the
workflow sets id-token permission but never exports the OIDC token into the
NPM_TOKEN env var required by .yarnrc.yml (npmAuthToken: "${NPM_TOKEN:-}"),
causing publish to 401; add a step in the prerelease job before calling
create-prerelease that retrieves the OIDC token and writes it to GITHUB_ENV as
NPM_TOKEN (either by using core.getIDToken() or the documented curl call with
ACTIONS_ID_TOKEN_REQUEST_URL/TOKEN, or a maintained action like
actions/create-github-app-token) so create-prerelease and yarn npm publish
receive a populated NPM_TOKEN.
| - id: get_commit_message | ||
| run: | | ||
| COMMIT_MSG_TEMP="${{ github.event.head_commit.message }}" | ||
| if [ -n "$COMMIT_MSG_TEMP" ] | ||
| then | ||
| commit_msg="$COMMIT_MSG_TEMP" | ||
| echo "commit-message=${commit_msg}" | head -n 1 >> "$GITHUB_OUTPUT" | ||
| else | ||
| commit_message=$(git log -1 --pretty=%B | head -n 1) | ||
| echo "commit-message=$commit_message" >> "$GITHUB_OUTPUT" | ||
| fi |
There was a problem hiding this comment.
Fix potential shell injection vulnerability in commit message handling.
Line 32 directly uses github.event.head_commit.message in an inline script without proper escaping, creating a script injection vulnerability. Per GitHub's secure scripting guidelines, untrusted context values should be passed through environment variables instead.
Apply this diff to fix the injection vulnerability:
- id: get_commit_message
run: |
- COMMIT_MSG_TEMP="${{ github.event.head_commit.message }}"
- if [ -n "$COMMIT_MSG_TEMP" ]
+ if [ -n "$COMMIT_MSG_TEMP" ]
then
- commit_msg="$COMMIT_MSG_TEMP"
- echo "commit-message=${commit_msg}" | head -n 1 >> "$GITHUB_OUTPUT"
+ echo "commit-message=$(echo "$COMMIT_MSG_TEMP" | head -n 1)" >> "$GITHUB_OUTPUT"
else
commit_message=$(git log -1 --pretty=%B | head -n 1)
echo "commit-message=$commit_message" >> "$GITHUB_OUTPUT"
fi
+ env:
+ COMMIT_MSG_TEMP: ${{ github.event.head_commit.message }}This approach passes the untrusted value through an environment variable, then uses proper quoting to ensure it cannot break out of the script context.
📝 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.
| - id: get_commit_message | |
| run: | | |
| COMMIT_MSG_TEMP="${{ github.event.head_commit.message }}" | |
| if [ -n "$COMMIT_MSG_TEMP" ] | |
| then | |
| commit_msg="$COMMIT_MSG_TEMP" | |
| echo "commit-message=${commit_msg}" | head -n 1 >> "$GITHUB_OUTPUT" | |
| else | |
| commit_message=$(git log -1 --pretty=%B | head -n 1) | |
| echo "commit-message=$commit_message" >> "$GITHUB_OUTPUT" | |
| fi | |
| - id: get_commit_message | |
| run: | | |
| if [ -n "$COMMIT_MSG_TEMP" ] | |
| then | |
| echo "commit-message=$(echo "$COMMIT_MSG_TEMP" | head -n 1)" >> "$GITHUB_OUTPUT" | |
| else | |
| commit_message=$(git log -1 --pretty=%B | head -n 1) | |
| echo "commit-message=$commit_message" >> "$GITHUB_OUTPUT" | |
| fi | |
| env: | |
| COMMIT_MSG_TEMP: ${{ github.event.head_commit.message }} |
🧰 Tools
🪛 actionlint (1.7.8)
31-31: "github.event.head_commit.message" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details
(expression)
🤖 Prompt for AI Agents
.github/workflows/publish.yml lines 30-40: the inline script directly
interpolates github.event.head_commit.message into shell (possible shell
injection); instead expose that value via a step env variable and reference it
quoted inside the script. Update the step to set an env key (e.g.,
COMMIT_MSG_ENV: "${{ github.event.head_commit.message }}") and in the run block
read and test "$COMMIT_MSG_ENV" (always quoted), assign to commit_msg if
non-empty, otherwise fall back to git log; ensure no unquoted expansions or eval
are used so the untrusted value cannot break out of the script context.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.