-
Notifications
You must be signed in to change notification settings - Fork 2
Update release workflow for NPM OIDC #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,173 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| name: "Publish" | ||||||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||||||
| push: | ||||||||||||||||||||||||||||||||||||||||||||||
| branches: | ||||||||||||||||||||||||||||||||||||||||||||||
| - main | ||||||||||||||||||||||||||||||||||||||||||||||
| paths-ignore: | ||||||||||||||||||||||||||||||||||||||||||||||
| - ".github/workflows/**" | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||
| id-token: write # Required for OIDC | ||||||||||||||||||||||||||||||||||||||||||||||
| contents: read | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| concurrency: | ||||||||||||||||||||||||||||||||||||||||||||||
| group: publish | ||||||||||||||||||||||||||||||||||||||||||||||
| cancel-in-progress: false | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| pre-ci: | ||||||||||||||||||||||||||||||||||||||||||||||
| name: Pre-CI (Extract Commit Message) | ||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||
| timeout-minutes: 1 | ||||||||||||||||||||||||||||||||||||||||||||||
| outputs: | ||||||||||||||||||||||||||||||||||||||||||||||
| commit-message: ${{ steps.get_commit_message.outputs.commit-message }} | ||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v5 | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - 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 | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+30
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix potential shell injection vulnerability in commit message handling. Line 32 directly uses 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
Suggested change
🧰 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 |
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - name: Debug commit message | ||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||
| echo "Commit message: ${{ steps.get_commit_message.outputs.commit-message }}" | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| setup: | ||||||||||||||||||||||||||||||||||||||||||||||
| name: Setup & Detect Changes | ||||||||||||||||||||||||||||||||||||||||||||||
| needs: pre-ci | ||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||
| outputs: | ||||||||||||||||||||||||||||||||||||||||||||||
| changed-types: ${{ steps.changed-types.outputs.changed }} | ||||||||||||||||||||||||||||||||||||||||||||||
| changed-common-solana: ${{ steps.changed-common-solana.outputs.changed }} | ||||||||||||||||||||||||||||||||||||||||||||||
| changed-node: ${{ steps.changed-node.outputs.changed }} | ||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v5 | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| fetch-depth: 100 # Needed to detect changes by having commit history | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - uses: marceloprado/has-changed-path@v1 | ||||||||||||||||||||||||||||||||||||||||||||||
| id: changed-types | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| paths: packages/types | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - uses: marceloprado/has-changed-path@v1 | ||||||||||||||||||||||||||||||||||||||||||||||
| id: changed-common-solana | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| paths: packages/common-solana | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - uses: marceloprado/has-changed-path@v1 | ||||||||||||||||||||||||||||||||||||||||||||||
| id: changed-node | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| paths: packages/node | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| release: | ||||||||||||||||||||||||||||||||||||||||||||||
| name: Release Publish | ||||||||||||||||||||||||||||||||||||||||||||||
| needs: [pre-ci, setup] | ||||||||||||||||||||||||||||||||||||||||||||||
| if: > | ||||||||||||||||||||||||||||||||||||||||||||||
| !startsWith(github.event.head_commit.message, '[SKIP CI]') | ||||||||||||||||||||||||||||||||||||||||||||||
| && startsWith(github.event.head_commit.message, '[release]') | ||||||||||||||||||||||||||||||||||||||||||||||
| && github.repository == 'subquery/subql-solana' | ||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v5 | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - name: Setup Node.js environment | ||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/setup-node@v5 | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| node-version: lts/* | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - name: Update npm | ||||||||||||||||||||||||||||||||||||||||||||||
| run: npm install -g npm@latest | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - run: yarn | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - name: build | ||||||||||||||||||||||||||||||||||||||||||||||
| run: yarn build | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| # Publish to npm and github releases | ||||||||||||||||||||||||||||||||||||||||||||||
| - name: Publish Types | ||||||||||||||||||||||||||||||||||||||||||||||
| if: needs.setup.outputs.changed-types == 'true' | ||||||||||||||||||||||||||||||||||||||||||||||
| uses: ./.github/actions/create-release | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| package-path: packages/types | ||||||||||||||||||||||||||||||||||||||||||||||
| repo-token: ${{ secrets.REPO_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - name: Publish Common Solana | ||||||||||||||||||||||||||||||||||||||||||||||
| if: needs.setup.outputs.changed-common-solana == 'true' | ||||||||||||||||||||||||||||||||||||||||||||||
| uses: ./.github/actions/create-release | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| package-path: packages/common-solana | ||||||||||||||||||||||||||||||||||||||||||||||
| repo-token: ${{ secrets.REPO_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - name: Publish Node | ||||||||||||||||||||||||||||||||||||||||||||||
| if: needs.setup.outputs.changed-node == 'true' | ||||||||||||||||||||||||||||||||||||||||||||||
| uses: ./.github/actions/create-release | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| package-path: packages/node | ||||||||||||||||||||||||||||||||||||||||||||||
| repo-token: ${{ secrets.REPO_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| prerelease: | ||||||||||||||||||||||||||||||||||||||||||||||
| name: Prerelease Publish | ||||||||||||||||||||||||||||||||||||||||||||||
| needs: [pre-ci, setup] | ||||||||||||||||||||||||||||||||||||||||||||||
| if: > | ||||||||||||||||||||||||||||||||||||||||||||||
| !startsWith(needs.pre-ci.outputs.commit-message, '[SKIP CI]') | ||||||||||||||||||||||||||||||||||||||||||||||
| && !startsWith(needs.pre-ci.outputs.commit-message, '[release]') | ||||||||||||||||||||||||||||||||||||||||||||||
| && github.repository == 'subquery/subql-solana' | ||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v5 | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||||||||||||||||||
| token: ${{ secrets.REPO_TOKEN }} # Needed to push changes back to repo | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - name: Setup Node.js environment | ||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/setup-node@v5 | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| node-version: lts/* | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - name: Update npm | ||||||||||||||||||||||||||||||||||||||||||||||
| run: npm install -g npm@latest | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - run: yarn | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - name: build | ||||||||||||||||||||||||||||||||||||||||||||||
| run: yarn build | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| # Prerelease publish steps | ||||||||||||||||||||||||||||||||||||||||||||||
| - name: Bump types & deploy | ||||||||||||||||||||||||||||||||||||||||||||||
| if: needs.setup.outputs.changed-types == 'true' | ||||||||||||||||||||||||||||||||||||||||||||||
| uses: ./.github/actions/create-prerelease | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| package-path: packages/types | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - name: Bump common Solana & deploy | ||||||||||||||||||||||||||||||||||||||||||||||
| if: needs.setup.outputs.changed-common-solana == 'true' | ||||||||||||||||||||||||||||||||||||||||||||||
| uses: ./.github/actions/create-prerelease | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| package-path: packages/common-solana | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - name: Bump node & deploy | ||||||||||||||||||||||||||||||||||||||||||||||
| if: needs.setup.outputs.changed-node == 'true' | ||||||||||||||||||||||||||||||||||||||||||||||
| uses: ./.github/actions/create-prerelease | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| package-path: packages/node | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| - name: Commit changes | ||||||||||||||||||||||||||||||||||||||||||||||
| uses: EndBug/add-and-commit@v9 | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| message: "[SKIP CI] Prerelease" | ||||||||||||||||||||||||||||||||||||||||||||||
| default_author: github_actions | ||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Script executed:
Repository: subquery/subql-solana
<shell_result>
Repository: subquery/subql-solana
Exit code: 0
stdout:
</shell_result>
Script executed:
Repository: subquery/subql-solana
<shell_result>
Repository: subquery/subql-solana
Exit code: 1
stdout:
</shell_result>
Script executed:
Repository: subquery/subql-solana
<shell_result>
Repository: subquery/subql-solana
Exit code: 0
stdout:
</shell_result>
Script executed:
Repository: subquery/subql-solana
<shell_result>
Repository: subquery/subql-solana
Exit code: 1
stdout:
</shell_result>
Perfect. Now I have all the information needed. The verification reveals a critical issue: The
.yarnrc.ymlfile expectsNPM_TOKENenvironment variable (line 18), but the workflow never sets it despite having theid-tokenpermission.Here's the final rewritten review comment:
Verify OIDC token is exported to NPM_TOKEN environment variable before calling create-prerelease.
The
npm-tokeninput has been removed, aligning with the PR objective to migrate to NPM OIDC. However, the migration is incomplete:.yarnrc.yml(line 18) requiresnpmAuthToken: "${NPM_TOKEN:-}"to be set, but thepublish.ymlworkflow never exports the OIDC token.Current state:
publish.ymlhaspermissions: id-token: write(line 10) ✓core.getIDToken()to retrieve and export the OIDC token asNPM_TOKENcreate-prereleaseaction receives no authentication mechanismyarn npm publishwill fail with 401 Unauthorized whenNPM_TOKENevaluates to emptyRequired fix: Add a step in the
prereleasejob to export the OIDC token:Or use an action like
actions/create-github-app-tokenthat exportsNPM_TOKENbefore callingcreate-prerelease.Also applies to: 19-19
🤖 Prompt for AI Agents