1- name : Minimal App Token Release & PR Test
1+ name : Publish releases
2+ # Consolidates canary and stable releases into single workflow
3+ # Trusted workflow for publishing to npm
24
35on :
6+ push :
7+ branches : [master]
48 workflow_dispatch :
9+ inputs :
10+ version_specifier :
11+ description : ' Semver bump (patch|minor|major|pre*) or exact version (v1.2.3)'
12+ required : true
13+ type : string
14+
15+ env :
16+ NODE_VERSION : ' 20'
517
618jobs :
7- release-stable-pr :
19+ release-stable :
20+ if : ${{ github.event_name == 'workflow_dispatch' }}
821 runs-on : ubuntu-latest
22+ permissions :
23+ contents : read
24+ id-token : write
25+
926 steps :
10- - name : Generate App token
27+ - name : Check if actor is member of admin or client-libs team
28+ id : team-check
29+ uses : actions/github-script@v7
30+ with :
31+ github-token : ${{ secrets.GITHUB_TOKEN }}
32+ script : |
33+ const org = 'supabase'
34+ const { actor } = context
35+
36+ async function isTeamMember(team_slug) {
37+ try {
38+ const res = await github.rest.teams.getMembershipForUserInOrg({
39+ org,
40+ team_slug,
41+ username: actor,
42+ })
43+ return res && res.status === 200
44+ } catch (_) {
45+ return false
46+ }
47+ }
48+
49+ const isAdmin = await isTeamMember('admin')
50+ const isClientLibs = await isTeamMember('client-libs')
51+ const isMember = isAdmin || isClientLibs
52+ core.setOutput('is_team_member', isMember ? 'true' : 'false')
53+
54+ - name : Fail if not authorized
55+ if : ${{ steps.team-check.outputs.is_team_member != 'true' }}
56+ run : |
57+ echo "You must be a member of @supabase/admin or @supabase/client-libs."
58+ exit 1
59+
60+ - name : Generate token
1161 id : app-token
1262 uses : actions/create-github-app-token@v2
1363 with :
@@ -20,19 +70,210 @@ jobs:
2070
2171 - uses : actions/setup-node@v4
2272 with :
23- node-version : 20
73+ node-version : ${{ env.NODE_VERSION }}
2474 cache : ' npm'
75+ registry-url : ' https://registry.npmjs.org'
76+
77+ - name : Update npm
78+ run : npm install -g npm@latest
2579
2680 - name : Install dependencies
2781 run : npm ci --legacy-peer-deps
2882
29- - name : Configure git user
83+ - name : Configure git
3084 run : |
3185 git config --global user.name "supabase-releaser[bot]"
3286 git config --global user.email "supabase-releaser[bot]@users.noreply.github.com"
3387
34- - name : Run release-stable script
88+ - name : Validate input
89+ run : |
90+ VS="${{ github.event.inputs.version_specifier }}"
91+ echo "Validating: $VS"
92+
93+ if [[ "$VS" =~ ^(patch|minor|major|prepatch|preminor|premajor|prerelease)$ ]]; then
94+ echo "✔ bump keyword"
95+ elif [[ "$VS" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$ ]]; then
96+ echo "✔ explicit version"
97+ else
98+ echo "❌ Invalid version_specifier: '$VS'"
99+ echo " Use: patch|minor|major|pre*, or v1.2.3"
100+ exit 1
101+ fi
102+
103+ - name : Release & create PR
35104 env :
105+ NPM_CONFIG_PROVENANCE : true
106+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
36107 RELEASE_GITHUB_TOKEN : ${{ steps.app-token.outputs.token }}
37108 GH_TOKEN : ${{ steps.app-token.outputs.token }}
38- run : npm run release-stable
109+ run : |
110+ npm run release-stable -- --versionSpecifier "${{ github.event.inputs.version_specifier }}"
111+
112+ - name : Summary
113+ if : ${{ success() }}
114+ run : |
115+ echo "## ✅ Stable Release" >> $GITHUB_STEP_SUMMARY
116+ echo "- **Version specifier:** \`${{ github.event.inputs.version_specifier }}\`" >> $GITHUB_STEP_SUMMARY
117+ echo "- **Source commit:** HEAD of the checked-out branch" >> $GITHUB_STEP_SUMMARY
118+ echo "- **Dist-tag:** \`latest\`" >> $GITHUB_STEP_SUMMARY
119+
120+ docs-after-stable-release :
121+ name : Generate Documentation
122+ needs : release-stable
123+ if : ${{ github.event_name == 'workflow_dispatch' && needs.release-stable.result == 'success' }}
124+ uses : ./.github/workflows/docs.yml
125+ permissions :
126+ actions : read
127+ contents : write
128+
129+ trigger-update-js-libs :
130+ name : Trigger Update JS Libs
131+ runs-on : ubuntu-latest
132+ needs : release-stable
133+ if : ${{ github.event_name == 'workflow_dispatch' && needs.release-stable.result == 'success' }}
134+ steps :
135+ - name : Generate token
136+ id : app-token
137+ uses : actions/create-github-app-token@v2
138+ with :
139+ app-id : ${{ secrets.APP_ID }}
140+ private-key : ${{ secrets.PRIVATE_KEY }}
141+ - name : Trigger supabase/supabase update-js-libs workflow
142+ uses : actions/github-script@v7
143+ with :
144+ github-token : ${{ steps.app-token.outputs.token }}
145+ script : |
146+ await github.rest.actions.createWorkflowDispatch({
147+ owner: 'supabase',
148+ repo: 'supabase',
149+ workflow_id: 'update-js-libs.yml',
150+ ref: 'master',
151+ inputs: {
152+ version: '${{ github.event.inputs.version_specifier }}',
153+ source: 'supabase-js-stable-release'
154+ }
155+ });
156+
157+ trigger-supabase-docs-update :
158+ name : Trigger Supabase Docs Update
159+ runs-on : ubuntu-latest
160+ needs : [release-stable, docs-after-stable-release]
161+ if : ${{ github.event_name == 'workflow_dispatch' && needs.release-stable.result == 'success' && needs.docs-after-stable-release.result == 'success' }}
162+ steps :
163+ - name : Generate token
164+ id : app-token
165+ uses : actions/create-github-app-token@v2
166+ with :
167+ app-id : ${{ secrets.APP_ID }}
168+ private-key : ${{ secrets.PRIVATE_KEY }}
169+
170+ - name : Trigger supabase/supabase docs workflow
171+ uses : actions/github-script@v7
172+ with :
173+ github-token : ${{ steps.app-token.outputs.token }}
174+ script : |
175+ await github.rest.actions.createWorkflowDispatch({
176+ owner: 'supabase',
177+ repo: 'supabase',
178+ workflow_id: 'docs-js-libs-update.yml',
179+ ref: 'master',
180+ inputs: {
181+ version: '${{ github.event.inputs.version_specifier }}',
182+ source: 'supabase-js-stable-release'
183+ }
184+ });
185+
186+ # preview jobs
187+ ci-core :
188+ if : ${{ github.event_name == 'push' }}
189+ name : Core Packages CI
190+ uses : ./.github/workflows/ci-core.yml
191+ permissions :
192+ actions : read
193+ contents : read
194+
195+ ci-supabase-js :
196+ if : ${{ github.event_name == 'push' }}
197+ name : Supabase-JS Integration CI
198+ uses : ./.github/workflows/ci-supabase-js.yml
199+ permissions :
200+ actions : read
201+ contents : read
202+
203+ ci-auth-js-node18 :
204+ if : ${{ github.event_name == 'push' }}
205+ name : Auth-JS Node.js 18 Compatibility
206+ uses : ./.github/workflows/ci-auth-js-node18.yml
207+ permissions :
208+ actions : read
209+ contents : read
210+
211+ release-canary :
212+ name : Release Canary
213+ runs-on : ubuntu-latest
214+ needs : [ci-core, ci-supabase-js, ci-auth-js-node18]
215+ permissions :
216+ contents : read
217+ id-token : write
218+ if : |
219+ github.ref == 'refs/heads/master' &&
220+ github.event_name == 'push' &&
221+ needs.ci-core.result == 'success' &&
222+ needs.ci-supabase-js.result == 'success' &&
223+ needs.ci-auth-js-node18.result == 'success'
224+ steps :
225+ - name : Generate token
226+ id : app-token
227+ uses : actions/create-github-app-token@v2
228+ with :
229+ app-id : ${{ secrets.APP_ID }}
230+ private-key : ${{ secrets.PRIVATE_KEY }}
231+
232+ - name : Checkout code
233+ uses : actions/checkout@v5
234+ with :
235+ fetch-depth : 0
236+
237+ - name : Setup Node.js
238+ uses : actions/setup-node@v4
239+ with :
240+ node-version : ${{ env.NODE_VERSION }}
241+ cache : ' npm'
242+ registry-url : ' https://registry.npmjs.org'
243+
244+ - name : Update npm
245+ run : npm install -g npm@latest
246+ - name : Install dependencies
247+ run : npm ci --legacy-peer-deps
248+ - name : Configure git
249+ run : |
250+ git config --global user.name "supabase-releaser[bot]"
251+ git config --global user.email "supabase-releaser[bot]@users.noreply.github.com"
252+
253+ - name : Release canary version
254+ id : release
255+ run : |
256+ echo "Running nx release..."
257+ npm run release-canary
258+ env :
259+ NPM_CONFIG_PROVENANCE : true
260+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
261+ RELEASE_GITHUB_TOKEN : ${{ steps.app-token.outputs.token }}
262+
263+ notify-stable-failure :
264+ name : Notify Slack for Stable failure
265+ needs : release-stable
266+ if : ${{ always() && github.event_name == 'workflow_dispatch' && needs.release-stable.result == 'failure' }}
267+ uses : ./.github/workflows/slack-notify.yml
268+ secrets : inherit
269+ with :
270+ subject : ' Stable Release'
271+
272+ notify-canary-failure :
273+ name : Notify Slack for Canary failure
274+ needs : release-canary
275+ if : ${{ always() && github.event_name == 'push' && needs.release-canary.result == 'failure' }}
276+ uses : ./.github/workflows/slack-notify.yml
277+ secrets : inherit
278+ with :
279+ subject : ' Canary Release'
0 commit comments