1+ name : Release
2+
3+ on :
4+ push :
5+ branches :
6+ - main
7+ - rc
8+ workflow_dispatch :
9+ inputs :
10+ packages :
11+ description : ' Comma-separated list of packages to release (leave empty for auto-detection)'
12+ required : false
13+ type : string
14+ dry_run :
15+ description : ' Dry run (no actual publishing)'
16+ required : false
17+ type : boolean
18+ default : false
19+ test_mode :
20+ description : ' Test mode (validate configuration only)'
21+ required : false
22+ type : boolean
23+ default : false
24+ release_channel :
25+ description : ' Release channel (stable, rc)'
26+ required : false
27+ type : choice
28+ options :
29+ - stable
30+ - rc
31+ default : stable
32+
33+ permissions :
34+ contents : write
35+ issues : write
36+ pull-requests : write
37+ id-token : write
38+
39+ jobs :
40+ detect-changes :
41+ runs-on : ubuntu-latest
42+ outputs :
43+ packages : ${{ steps.changes.outputs.packages }}
44+ matrix : ${{ steps.changes.outputs.matrix }}
45+ release_channel : ${{ steps.channel.outputs.release_channel }}
46+ steps :
47+ - name : Checkout repository
48+ uses : actions/checkout@v4
49+ with :
50+ fetch-depth : 0
51+ token : ${{ secrets.GITHUB_TOKEN }}
52+
53+ - name : Setup Node.js
54+ uses : actions/setup-node@v4
55+ with :
56+ node-version : ' 20'
57+ cache : ' npm'
58+
59+ - name : Install dependencies
60+ run : npm ci
61+
62+ - name : Determine release channel
63+ id : channel
64+ run : |
65+ if [[ "${{ github.event.inputs.release_channel }}" != "" ]]; then
66+ echo "release_channel=${{ github.event.inputs.release_channel }}" >> $GITHUB_OUTPUT
67+ elif [[ "${{ github.ref }}" == "refs/heads/rc" ]]; then
68+ echo "release_channel=rc" >> $GITHUB_OUTPUT
69+ else
70+ echo "release_channel=stable" >> $GITHUB_OUTPUT
71+ fi
72+
73+ - name : Detect changed packages
74+ id : changes
75+ run : |
76+ if [[ -n "${{ github.event.inputs.packages }}" ]]; then
77+ # Manual trigger with specific packages
78+ IFS=',' read -ra PACKAGES <<< "${{ github.event.inputs.packages }}"
79+ PACKAGES_JSON=$(printf '%s\n' "${PACKAGES[@]}" | jq -R . | jq -s .)
80+ echo "packages=$PACKAGES_JSON" >> $GITHUB_OUTPUT
81+ echo "matrix={\"package\":$(echo $PACKAGES_JSON)}" >> $GITHUB_OUTPUT
82+ else
83+ # Auto-detect changed packages
84+ node scripts/detect-changed-packages.js
85+ PACKAGES=$(cat $GITHUB_OUTPUT | grep 'packages=' | cut -d'=' -f2)
86+ if [[ "$PACKAGES" != "[]" ]]; then
87+ echo "matrix={\"package\":$PACKAGES}" >> $GITHUB_OUTPUT
88+ else
89+ echo "matrix={\"package\":[]}" >> $GITHUB_OUTPUT
90+ fi
91+ fi
92+
93+ test-configuration :
94+ if : github.event.inputs.test_mode == 'true'
95+ runs-on : ubuntu-latest
96+ steps :
97+ - name : Checkout repository
98+ uses : actions/checkout@v4
99+ with :
100+ fetch-depth : 0
101+
102+ - name : Setup Node.js
103+ uses : actions/setup-node@v4
104+ with :
105+ node-version : ' 20'
106+ cache : ' npm'
107+
108+ - name : Install dependencies
109+ run : npm ci
110+
111+ - name : Test semantic-release configuration
112+ run : |
113+ echo "Testing semantic-release configuration..."
114+ npx semantic-release --dry-run --no-ci
115+ echo "✅ Configuration is valid"
116+
117+ - name : Test package detection
118+ run : |
119+ echo "Testing package detection..."
120+ node scripts/detect-changed-packages.js
121+ echo "✅ Package detection works"
122+
123+ release :
124+ needs : detect-changes
125+ if : needs.detect-changes.outputs.packages != '[]' && github.event.inputs.test_mode != 'true'
126+ runs-on : ubuntu-latest
127+ strategy :
128+ matrix : ${{ fromJSON(needs.detect-changes.outputs.matrix) }}
129+ fail-fast : false
130+ max-parallel : 1 # Release packages one at a time to avoid conflicts
131+
132+ steps :
133+ - name : Checkout repository
134+ uses : actions/checkout@v4
135+ with :
136+ fetch-depth : 0
137+ token : ${{ secrets.GITHUB_TOKEN }}
138+
139+ - name : Setup Node.js
140+ uses : actions/setup-node@v4
141+ with :
142+ node-version : ' 20'
143+ cache : ' npm'
144+
145+ - name : Setup Dart SDK
146+ uses : dart-lang/setup-dart@v1
147+ with :
148+ sdk : stable
149+
150+ - name : Setup Flutter SDK
151+ uses : subosito/flutter-action@v2
152+ with :
153+ flutter-version : ' 3.19.x'
154+ channel : ' stable'
155+
156+ - name : Install Node.js dependencies
157+ run : npm ci
158+
159+ - name : Install Dart dependencies
160+ run : |
161+ dart pub global activate melos
162+ melos bootstrap
163+
164+ - name : Configure pub.dev credentials
165+ if : github.event.inputs.dry_run != 'true'
166+ run : |
167+ mkdir -p ~/.pub-cache
168+ echo '${{ secrets.PUB_DEV_CREDENTIALS }}' > ~/.pub-cache/credentials.json
169+
170+ - name : Configure Git
171+ run : |
172+ git config user.name "github-actions[bot]"
173+ git config user.email "github-actions[bot]@users.noreply.github.com"
174+
175+ - name : Run tests for ${{ matrix.package }}
176+ run : |
177+ cd packages/${{ matrix.package }}
178+
179+ # Start required services for packages that need them
180+ case "${{ matrix.package }}" in
181+ "gotrue"|"postgrest"|"storage_client")
182+ cd ../../infra/${{ matrix.package }}
183+ docker compose up -d
184+ cd ../../packages/${{ matrix.package }}
185+ ;;
186+ esac
187+
188+ # Run tests
189+ if [[ "${{ matrix.package }}" == "supabase_flutter" ]]; then
190+ flutter test --concurrency=1
191+ else
192+ dart test -j 1
193+ fi
194+
195+ - name : Run linting for ${{ matrix.package }}
196+ run : |
197+ cd packages/${{ matrix.package }}
198+ dart analyze --fatal-warnings --fatal-infos .
199+ dart format lib test -l 80 --set-exit-if-changed
200+
201+ - name : Release ${{ matrix.package }}
202+ env :
203+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
204+ PACKAGE_NAME : ${{ matrix.package }}
205+ RELEASE_CHANNEL : ${{ needs.detect-changes.outputs.release_channel }}
206+ run : |
207+ export PACKAGE_NAME=${{ matrix.package }}
208+ export RELEASE_CHANNEL=${{ needs.detect-changes.outputs.release_channel }}
209+ if [[ "${{ github.event.inputs.dry_run }}" == "true" ]]; then
210+ echo "Running dry-run for ${{ matrix.package }} on $RELEASE_CHANNEL channel..."
211+ npx semantic-release --dry-run
212+ else
213+ echo "Running release for ${{ matrix.package }} on $RELEASE_CHANNEL channel..."
214+ npx semantic-release
215+ fi
216+
217+ - name : Cleanup Docker services
218+ if : always()
219+ run : |
220+ case "${{ matrix.package }}" in
221+ "gotrue"|"postgrest"|"storage_client")
222+ cd infra/${{ matrix.package }}
223+ docker compose down
224+ ;;
225+ esac
226+
227+ update-changelog :
228+ needs : [detect-changes, release]
229+ if : needs.detect-changes.outputs.packages != '[]' && github.event.inputs.dry_run != 'true' && github.event.inputs.test_mode != 'true'
230+ runs-on : ubuntu-latest
231+ steps :
232+ - name : Checkout repository
233+ uses : actions/checkout@v4
234+ with :
235+ fetch-depth : 0
236+ token : ${{ secrets.GITHUB_TOKEN }}
237+
238+ - name : Setup Node.js
239+ uses : actions/setup-node@v4
240+ with :
241+ node-version : ' 20'
242+ cache : ' npm'
243+
244+ - name : Setup Dart SDK
245+ uses : dart-lang/setup-dart@v1
246+ with :
247+ sdk : stable
248+
249+ - name : Install dependencies
250+ run : |
251+ npm ci
252+ dart pub global activate melos
253+ melos bootstrap
254+
255+ - name : Update workspace changelog
256+ run : |
257+ # Run melos version to update the workspace changelog
258+ melos version --no-release --yes
259+
260+ # Commit the updated changelog if there are changes
261+ if git diff --quiet; then
262+ echo "No changelog changes to commit"
263+ else
264+ git config user.name "github-actions[bot]"
265+ git config user.email "github-actions[bot]@users.noreply.github.com"
266+ git add .
267+ git commit -m "chore: update workspace changelog [skip ci]"
268+ git push
269+ fi
0 commit comments