Skip to content

Commit e15f898

Browse files
authored
fix: use OIDC trusted publishing instead of npm token for releases (#1031)
Remove registry-url from setup-node so the repo .npmrc is preserved, enabling OIDC authentication for npm publishing. Remove NODE_AUTH_TOKEN and the NPM_TOKEN secret dependency. Also align the release workflow with the Typist reference implementation: use package-published output from semantic-release instead of tag-diff detection, add node_modules caching, explicit build step, and consistent step naming.
1 parent 7aaad9d commit e15f898

File tree

4 files changed

+121
-119
lines changed

4 files changed

+121
-119
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
name: Package Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
env:
9+
GH_PACKAGES_TOKEN: ${{ secrets.GH_PACKAGES_TOKEN }}
10+
11+
permissions:
12+
# Enable the use of OIDC for trusted publishing and npm provenance
13+
id-token: write
14+
# Enable the use of GitHub Packages registry
15+
packages: write
16+
# Enable `semantic-release` to publish a GitHub release and push commits
17+
contents: write
18+
# Enable `semantic-release` to post comments on issues
19+
issues: write
20+
# Enable `semantic-release` to post comments on pull requests
21+
pull-requests: write
22+
23+
# The release workflow involves many crucial steps that once triggered shouldn't be cancelled until
24+
# finished, otherwise we might end up in an inconsistent state (e.g., published to GitHub Packages
25+
# but not npm), so new workflow runs are queued until the previous one has completely finished.
26+
concurrency:
27+
group: ${{ github.workflow }}
28+
cancel-in-progress: false
29+
30+
jobs:
31+
release-and-publish:
32+
name: Release & Publish
33+
runs-on: ubuntu-latest
34+
timeout-minutes: 30
35+
36+
steps:
37+
- name: Generate release bot token
38+
id: release-bot
39+
uses: actions/create-github-app-token@v3
40+
with:
41+
app-id: ${{ secrets.DOIST_RELEASE_BOT_ID }}
42+
private-key: ${{ secrets.DOIST_RELEASE_BOT_PRIVATE_KEY }}
43+
permission-contents: write
44+
permission-issues: write
45+
permission-pull-requests: write
46+
47+
- name: Checkout repository
48+
uses: actions/checkout@v6
49+
with:
50+
token: ${{ steps.release-bot.outputs.token }}
51+
fetch-depth: 0
52+
53+
- name: Prepare Node.js environment
54+
uses: actions/setup-node@v6
55+
with:
56+
cache: npm
57+
node-version-file: .node-version
58+
59+
- name: Cache project 'node_modules' directory
60+
id: node-modules-cache
61+
uses: actions/cache@v5
62+
with:
63+
key: node-modules-cache-${{ hashFiles('**/package-lock.json', '**/.node-version', 'patches/**') }}
64+
path: node_modules/
65+
66+
- name: Install project npm dependencies
67+
if: ${{ steps.node-modules-cache.outputs.cache-hit != 'true' }}
68+
run: |
69+
npm ci
70+
71+
- name: Build package
72+
run: |
73+
npm run build
74+
75+
# The Node.js environment is prepared based on the `.npmrc` file in the repo, which
76+
# configures Doist scoped packages to use the public npm registry with OIDC
77+
# authentication for the initial `semantic-release` publish, after which we remove the
78+
# Doist registry configuration, and prepare the Node.js environment for the GitHub
79+
# Packages registry, providing a predictable release workflow for both registries.
80+
- name: Publish package to public npm registry
81+
id: semantic-release
82+
run: |
83+
npx semantic-release
84+
env:
85+
GITHUB_TOKEN: ${{ steps.release-bot.outputs.token }}
86+
GIT_AUTHOR_EMAIL: doistbot@users.noreply.github.com
87+
GIT_AUTHOR_NAME: Doist Bot
88+
GIT_COMMITTER_EMAIL: doistbot@users.noreply.github.com
89+
GIT_COMMITTER_NAME: Doist Bot
90+
91+
- name: Remove Doist registry configuration from `.npmrc`
92+
if: ${{ steps.semantic-release.outputs.package-published == 'true' }}
93+
run: |
94+
npm config delete @doist:registry --location=project
95+
96+
- name: Prepare Node.js environment for GitHub Packages registry
97+
if: ${{ steps.semantic-release.outputs.package-published == 'true' }}
98+
uses: actions/setup-node@v6
99+
with:
100+
cache: npm
101+
node-version-file: .node-version
102+
registry-url: https://npm.pkg.github.com/
103+
scope: '@doist'
104+
105+
- name: Publish package to private GitHub Packages registry
106+
if: ${{ steps.semantic-release.outputs.package-published == 'true' }}
107+
run: |
108+
npm publish
109+
env:
110+
NODE_AUTH_TOKEN: ${{ secrets.GH_PACKAGES_TOKEN }}

.github/workflows/release.yml

Lines changed: 0 additions & 115 deletions
This file was deleted.

package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@
2222
"**/*.css"
2323
],
2424
"publishConfig": {
25-
"access": "public",
26-
"provenance": true
25+
"access": "public"
2726
},
2827
"files": [
2928
"CHANGELOG.md",
@@ -55,8 +54,7 @@
5554
"lint": "eslint --format codeframe --cache --ext js,jsx,ts,tsx ./",
5655
"storybook": "start-storybook -p 6006",
5756
"prettify": "prettier --write \"./**/*.{js,jsx,ts,tsx,json,css,scss,less,md,mdx}\"",
58-
"plop": "plop",
59-
"prepublishOnly": "npm run build && npm test"
57+
"plop": "plop"
6058
},
6159
"peerDependencies": {
6260
"@ariakit/react": "~0.4.19",

release.config.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,14 @@ export default {
1717
},
1818
],
1919
'@semantic-release/github',
20+
[
21+
'@semantic-release/exec',
22+
{
23+
verifyConditionsCmd:
24+
'if [ -n "$GITHUB_OUTPUT" ]; then echo "package-published=false" >> "$GITHUB_OUTPUT"; fi',
25+
successCmd:
26+
'if [ -n "$GITHUB_OUTPUT" ]; then echo "package-published=true" >> "$GITHUB_OUTPUT"; fi',
27+
},
28+
],
2029
],
2130
}

0 commit comments

Comments
 (0)