Skip to content

Commit 2da68f9

Browse files
committed
feat: add semantic-release automation for monorepo
- Add semantic-release configuration for all packages - Support both stable (main) and RC (rc) release channels - Automatic package detection and dependency resolution - GitHub Actions workflow for automated releases - pub.dev publishing with proper version management - Comprehensive documentation in RELEASE.md - Integration with existing melos workspace BREAKING CHANGE: Introduces automated release process
1 parent d729fa4 commit 2da68f9

File tree

9 files changed

+1219
-1
lines changed

9 files changed

+1219
-1
lines changed

.github/workflows/release.yml

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
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

.gitignore

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,13 @@ packages/**/pubspec.lock
7979
!**/ios/**/default.pbxuser
8080
!**/ios/**/default.perspectivev3
8181

82-
/packages/*/coverage
82+
/packages/*/coverage
83+
84+
# Node.js
85+
node_modules/
86+
npm-debug.log*
87+
yarn-debug.log*
88+
yarn-error.log*
89+
90+
# Semantic Release
91+
.semanticdb/

0 commit comments

Comments
 (0)