Skip to content

Commit 2d952a1

Browse files
committed
feat: enable trusted publishing
Minor workflow changes to use GitHub OIDC for trusted publishing to npm. Allows using two GITHUB_TOKENS, one needed for OIDC + npm release. And the other that has permission to create tags. If we used just one, the token would either not have OIDC permissions (can't read id_token) or wouldn't have permission to create tags.
1 parent 9792a92 commit 2d952a1

File tree

4 files changed

+125
-98
lines changed

4 files changed

+125
-98
lines changed

.github/workflows/main-ci-release.yml

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

.github/workflows/release-stable.yml renamed to .github/workflows/publish.yml

Lines changed: 101 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1-
name: Release Stable
1+
# Consolidates canary and stable releases into single workflow
2+
# Trusted workflow for publishing to npm
3+
4+
name: Publish releases
25

36
on:
7+
push:
8+
branches: [master]
49
workflow_dispatch:
510
inputs:
611
version_specifier:
@@ -12,10 +17,11 @@ env:
1217
NODE_VERSION: '20'
1318

1419
jobs:
15-
release-stable:
20+
release-stable: # stable releases can only be manually triggered
21+
if: ${{ github.event_name == 'workflow_dispatch' }}
1622
runs-on: ubuntu-latest
1723
permissions:
18-
contents: write
24+
contents: read
1925
id-token: write
2026

2127
steps:
@@ -58,7 +64,7 @@ jobs:
5864
with:
5965
app-id: ${{ secrets.APP_ID }}
6066
private-key: ${{ secrets.PRIVATE_KEY }}
61-
- uses: actions/checkout@v4
67+
- uses: actions/checkout@v5
6268
with:
6369
fetch-depth: 0
6470

@@ -92,10 +98,8 @@ jobs:
9298
9399
- name: Release
94100
env:
95-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
96-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
97101
NPM_CONFIG_PROVENANCE: true
98-
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
102+
RELEASE_GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} # used for tags
99103
run: |
100104
npm run release-stable -- --versionSpecifier "${{ github.event.inputs.version_specifier }}"
101105
@@ -109,7 +113,10 @@ jobs:
109113
docs-after-stable-release:
110114
name: Generate Documentation
111115
needs: release-stable
112-
if: needs.release-stable.result == 'success'
116+
if: ${{
117+
github.event_name == 'workflow_dispatch &&
118+
needs.release-stable.result == 'success'
119+
}}
113120
uses: ./.github/workflows/docs.yml
114121
permissions:
115122
actions: read
@@ -119,7 +126,10 @@ jobs:
119126
name: Trigger Update JS Libs
120127
runs-on: ubuntu-latest
121128
needs: release-stable
122-
if: needs.release-stable.result == 'success'
129+
if: ${{
130+
github.event_name == 'workflow_dispatch' &&
131+
needs.release-stable.result == 'success'
132+
}}
123133
steps:
124134
- name: Generate token
125135
id: app-token
@@ -147,9 +157,11 @@ jobs:
147157
name: Trigger Supabase Docs Update
148158
runs-on: ubuntu-latest
149159
needs: [release-stable, docs-after-stable-release]
150-
if: |
160+
if: ${{
161+
github.event_name == 'workflow_dispatch' &&
151162
needs.release-stable.result == 'success' &&
152163
needs.docs-after-stable-release.result == 'success'
164+
}}
153165
steps:
154166
- name: Generate token
155167
id: app-token
@@ -173,3 +185,82 @@ jobs:
173185
source: 'supabase-js-stable-release'
174186
}
175187
});
188+
189+
# preview jobs
190+
ci-core:
191+
if: ${{ github.event_name == 'push' }}
192+
name: Core Packages CI
193+
uses: ./.github/workflows/ci-core.yml
194+
permissions:
195+
actions: read
196+
contents: read
197+
198+
ci-supabase-js:
199+
if: ${{ github.event_name == 'push' }}
200+
name: Supabase-JS Integration CI
201+
uses: ./.github/workflows/ci-supabase-js.yml
202+
permissions:
203+
actions: read
204+
contents: read
205+
206+
ci-auth-js-node18:
207+
if: ${{ github.event_name == 'push' }}
208+
name: Auth-JS Node.js 18 Compatibility
209+
uses: ./.github/workflows/ci-auth-js-node18.yml
210+
permissions:
211+
actions: read
212+
contents: read
213+
214+
# ==========================================
215+
# CANARY RELEASE (only on master, after all CI passes)
216+
# ==========================================
217+
218+
release-canary:
219+
name: Release Canary
220+
runs-on: ubuntu-latest
221+
needs: [ci-core, ci-supabase-js, ci-auth-js-node18]
222+
permissions:
223+
contents: read
224+
id-token: write
225+
# Only run on master branch pushes, and only if all CI jobs succeeded
226+
if: |
227+
github.ref == 'refs/heads/master' &&
228+
github.event_name == 'push' &&
229+
needs.ci-core.result == 'success' &&
230+
needs.ci-supabase-js.result == 'success' &&
231+
needs.ci-auth-js-node18.result == 'success'
232+
steps:
233+
- name: Generate token
234+
id: app-token
235+
uses: actions/create-github-app-token@v2
236+
with:
237+
app-id: ${{ secrets.APP_ID }}
238+
private-key: ${{ secrets.PRIVATE_KEY }}
239+
240+
- name: Checkout code
241+
uses: actions/checkout@v5
242+
with:
243+
fetch-depth: 0
244+
245+
- name: Setup Node.js
246+
uses: actions/setup-node@v4
247+
with:
248+
node-version: ${{ env.NODE_VERSION }}
249+
cache: 'npm'
250+
registry-url: 'https://registry.npmjs.org'
251+
252+
- name: Install dependencies
253+
run: npm ci --legacy-peer-deps
254+
- name: Configure git
255+
run: |
256+
git config --global user.name "supabase-releaser[bot]"
257+
git config --global user.email "supabase-releaser[bot]@users.noreply.github.com"
258+
259+
- name: Release canary version
260+
id: release
261+
run: |
262+
echo "Running nx release..."
263+
npm run release-canary
264+
env:
265+
NPM_CONFIG_PROVENANCE: true
266+
RELEASE_GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} # used for tags

scripts/release-canary.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ import { execSync } from 'child_process'
1818
execSync('npx nx run-many --target=build --all', { stdio: 'inherit' })
1919
console.log('✅ Build complete\n')
2020

21+
// releaseChangelog should use the GitHub token with permission for tagging
22+
// before switching the token, backup the GITHUB_TOKEN so that it
23+
// can be restored afterwards and used by releasePublish. We can't use the same
24+
// token, because releasePublish wants a token that has the id_token: write permission
25+
// so that we can use OIDC for trusted publishing
26+
27+
const gh_token_bak = process.env.GITHUB_TOKEN
28+
process.env.GITHUB_TOKEN = process.env.RELEASE_GITHUB_TOKEN
29+
2130
await releaseChangelog({
2231
versionData: projectsVersionData,
2332
version: workspaceVersion,
@@ -26,6 +35,8 @@ import { execSync } from 'child_process'
2635
stageChanges: false,
2736
})
2837

38+
// npm publish with OIDC
39+
process.env.GITHUB_TOKEN = gh_token_bak
2940
const publishResult = await releasePublish({
3041
registry: 'https://registry.npmjs.org/',
3142
access: 'public',

scripts/release-stable.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ if (!validSpecifiers.includes(versionSpecifier) && !isValidVersion) {
5656
execSync('npx nx run-many --target=build --all', { stdio: 'inherit' })
5757
console.log('✅ Build complete\n')
5858

59+
// releaseChangelog should use the GitHub token with permission for tagging
60+
// before switching the token, backup the GITHUB_TOKEN so that it
61+
// can be restored afterwards and used by releasePublish. We can't use the same
62+
// token, because releasePublish wants a token that has the id_token: write permission
63+
// so that we can use OIDC for trusted publishing
64+
65+
const gh_token_bak = process.env.GITHUB_TOKEN
66+
process.env.GITHUB_TOKEN = process.env.RELEASE_GITHUB_TOKEN
67+
5968
const result = await releaseChangelog({
6069
versionData: projectsVersionData,
6170
version: workspaceVersion,
@@ -64,6 +73,8 @@ if (!validSpecifiers.includes(versionSpecifier) && !isValidVersion) {
6473
stageChanges: false,
6574
})
6675

76+
// npm publish with OIDC
77+
process.env.GITHUB_TOKEN = gh_token_bak
6778
const publishResult = await releasePublish({
6879
registry: 'https://registry.npmjs.org/',
6980
access: 'public',
@@ -82,6 +93,8 @@ if (!validSpecifiers.includes(versionSpecifier) && !isValidVersion) {
8293
}
8394

8495
// ---- Create release branch + PR ----
96+
// switch back to the releaser GitHub token
97+
process.env.GITHUB_TOKEN = process.env.RELEASE_GITHUB_TOKEN
8598
const version = result.workspaceChangelog?.releaseVersion.rawVersion || workspaceVersion
8699

87100
// Validate version to prevent command injection

0 commit comments

Comments
 (0)