Skip to content

Commit 495b801

Browse files
committed
chore: migrate to pub workspaces and Melos 8
1 parent e595e02 commit 495b801

22 files changed

Lines changed: 1132 additions & 239 deletions

File tree

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
if [ -z "$BASE" ]; then
4141
FORCE_ALL=true
4242
elif git diff --name-only "$BASE...HEAD" \
43-
| grep -qE '^(\.github/workflows/build\.yml|melos\.yaml|pubspec\.lock|supabase/)'; then
43+
| grep -qE '^(\.github/workflows/build\.yml|pubspec\.yaml|pubspec\.lock|supabase/)'; then
4444
FORCE_ALL=true
4545
fi
4646

.github/workflows/test.yml

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
runs-on: ubuntu-latest
2020
outputs:
2121
dart-matrix: ${{ steps.detect.outputs.dart-matrix }}
22-
sdk-matrix: ${{ steps.detect.outputs.sdk-matrix }}
22+
channel-matrix: ${{ steps.detect.outputs.channel-matrix }}
2323
flutter: ${{ steps.detect.outputs.flutter }}
2424
steps:
2525
- name: Checkout repository
@@ -49,7 +49,7 @@ jobs:
4949
if [ -z "$BASE" ] || [ "$BASE" = "0000000000000000000000000000000000000000" ]; then
5050
FORCE_ALL=true
5151
elif git diff --name-only "$BASE...HEAD" \
52-
| grep -qE '^(\.github/workflows/test\.yml|melos\.yaml|pubspec\.lock|supabase/)'; then
52+
| grep -qE '^(\.github/workflows/test\.yml|pubspec\.yaml|pubspec\.lock|supabase/)'; then
5353
FORCE_ALL=true
5454
fi
5555
@@ -88,13 +88,10 @@ jobs:
8888
fi
8989
echo "dart-matrix=$DART_MATRIX" >> "$GITHUB_OUTPUT"
9090
91-
# Only exercise beta/dev SDKs on pushes to main. On pull requests we
92-
# test stable only to keep the matrix small; upcoming-SDK breakage is
93-
# caught on merge.
9491
if [ "${{ github.event_name }}" = "push" ]; then
95-
echo 'sdk-matrix=["stable","beta","dev"]' >> "$GITHUB_OUTPUT"
92+
echo 'channel-matrix=["stable","beta","master"]' >> "$GITHUB_OUTPUT"
9693
else
97-
echo 'sdk-matrix=["stable"]' >> "$GITHUB_OUTPUT"
94+
echo 'channel-matrix=["stable"]' >> "$GITHUB_OUTPUT"
9895
fi
9996
10097
if echo "$CHANGED" | grep -qx "supabase_flutter"; then
@@ -104,7 +101,7 @@ jobs:
104101
fi
105102
106103
test-dart:
107-
name: Dart ${{ matrix.package.name }} (${{ matrix.sdk }})
104+
name: Dart ${{ matrix.package.name }} (${{ matrix.channel }})
108105
needs: changes
109106
if: ${{ needs.changes.outputs.dart-matrix != '[]' }}
110107
timeout-minutes: 20
@@ -113,40 +110,33 @@ jobs:
113110
fail-fast: false
114111
matrix:
115112
package: ${{ fromJSON(needs.changes.outputs.dart-matrix) }}
116-
sdk: ${{ fromJSON(needs.changes.outputs.sdk-matrix) }}
113+
channel: ${{ fromJSON(needs.changes.outputs.channel-matrix) }}
117114

118115
steps:
119116
- name: Checkout repository
120117
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
121118

122-
- name: Setup Dart
123-
uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c # v1.7.1
119+
- name: Setup Flutter
120+
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0
124121
with:
125-
sdk: ${{ matrix.sdk }}
122+
channel: ${{ matrix.channel }}
123+
cache: false
126124

127-
- name: Cache pub dependencies
128-
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
129-
with:
130-
path: |
131-
${{ env.PUB_CACHE }}
132-
~/.pub-cache
133-
key: ${{ runner.os }}-pub-${{ matrix.sdk }}-${{ hashFiles('**/pubspec.lock') }}
134-
restore-keys: |
135-
${{ runner.os }}-pub-${{ matrix.sdk }}-
136-
${{ runner.os }}-pub-
125+
- name: Show Flutter version
126+
run: flutter --version
137127

138128
- name: Bootstrap workspace
139129
run: |
140130
dart pub global activate melos
141-
melos bootstrap --no-flutter
131+
melos bootstrap
142132
143133
- name: Format
144-
if: ${{ matrix.sdk == 'stable' }}
134+
if: ${{ matrix.channel == 'stable' }}
145135
working-directory: packages/${{ matrix.package.name }}
146136
run: dart format lib test -l 80 --set-exit-if-changed
147137

148138
- name: Analyze
149-
if: ${{ matrix.sdk == 'stable' }}
139+
if: ${{ matrix.channel == 'stable' }}
150140
working-directory: packages/${{ matrix.package.name }}
151141
run: dart analyze --fatal-infos .
152142

@@ -201,18 +191,18 @@ jobs:
201191
if [ "${{ matrix.package.concurrency }}" = "1" ]; then
202192
CONCURRENCY="--concurrency=1"
203193
fi
204-
if [ "${{ matrix.sdk }}" = "stable" ]; then
194+
if [ "${{ matrix.channel }}" = "stable" ]; then
205195
dart pub global activate coverage
206196
dart test $CONCURRENCY --coverage=coverage
207197
dart pub global run coverage:format_coverage \
208-
--packages=.dart_tool/package_config.json \
198+
--packages=../../.dart_tool/package_config.json \
209199
--report-on=lib --lcov -o coverage/lcov.info -i coverage
210200
else
211201
dart test $CONCURRENCY
212202
fi
213203
214204
- name: Upload coverage to Coveralls
215-
if: ${{ matrix.sdk == 'stable' }}
205+
if: ${{ matrix.channel == 'stable' }}
216206
uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2.3.7
217207
with:
218208
github-token: ${{ secrets.GITHUB_TOKEN }}

AGENTS.md

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,11 @@ melos bs
4343
### Linting and Formatting
4444

4545
```bash
46-
# Run all static analysis checks (analyze + format)
47-
melos run lint:all
46+
# Run the analyzer across the whole workspace
47+
melos analyze
4848

49-
# Run analyzer on all packages
50-
melos run analyze
51-
52-
# Format code (80 char line length)
53-
melos run format
49+
# Format code (80 char line length, configured in the root pubspec.yaml)
50+
melos format
5451
```
5552

5653
### Testing
@@ -83,11 +80,19 @@ cd packages/<package>
8380
dart test
8481
```
8582

86-
**Run tests with coverage:**
83+
**Run every package's tests at once:**
84+
85+
```bash
86+
# Runs `dart test`/`flutter test` in each package that has a test/ directory.
87+
# Start the local Supabase stack first (see above) so the backend packages pass.
88+
melos test
89+
```
90+
91+
**Run tests with coverage (from a package directory):**
8792

8893
```bash
89-
# From root or package directory
90-
melos run test:coverage
94+
cd packages/<package>
95+
dart test --coverage=coverage
9196
```
9297

9398
### Running a Single Test File
@@ -103,11 +108,11 @@ dart test test/specific_test.dart -n "test name pattern"
103108
### Package Management
104109

105110
```bash
106-
# Upgrade dependencies across all packages
107-
melos run upgrade
111+
# Upgrade dependencies across the whole workspace (run at the repository root)
112+
dart pub upgrade
108113

109114
# Check for outdated dependencies
110-
melos run outdated
115+
dart pub outdated
111116
```
112117

113118
### Version Management
@@ -203,7 +208,7 @@ await Supabase.initialize(
203208
## Contributing Guidelines
204209

205210
- Fork the repo and create feature branches
206-
- Run `melos run lint:all` before committing
211+
- Run `melos analyze` and `melos format` before committing
207212
- Ensure tests pass for modified packages
208213
- Update package changelogs if making notable changes
209214
- Line length limit is 80 characters

examples/launcher/lib/launcher.dart

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,9 @@ Future<int> run(List<String> args) async {
120120

121121
// Forward Ctrl-C to flutter so it shuts down and control returns here,
122122
// letting the cleanup below stop Supabase, rather than killing the launcher.
123-
final sigint = ProcessSignal.sigint
124-
.watch()
125-
.listen((_) => process.kill(ProcessSignal.sigint));
123+
final sigint = ProcessSignal.sigint.watch().listen(
124+
(_) => process.kill(ProcessSignal.sigint),
125+
);
126126
final code = await process.exitCode;
127127
await sigint.cancel();
128128
return code;
@@ -157,10 +157,9 @@ Directory? _findExamplesRoot() {
157157

158158
Future<bool> _hasCommand(String command) async {
159159
try {
160-
final result = await Process.run(
161-
Platform.isWindows ? 'where' : 'which',
162-
[command],
163-
);
160+
final result = await Process.run(Platform.isWindows ? 'where' : 'which', [
161+
command,
162+
]);
164163
return result.exitCode == 0;
165164
} on ProcessException {
166165
return false;
@@ -169,10 +168,11 @@ Future<bool> _hasCommand(String command) async {
169168

170169
Future<bool> _startSupabase(Directory root) async {
171170
final progress = _logger.progress('Starting the local Supabase stack');
172-
final result = await Process.run(
173-
'supabase',
174-
['start', '--workdir', root.path],
175-
);
171+
final result = await Process.run('supabase', [
172+
'start',
173+
'--workdir',
174+
root.path,
175+
]);
176176
if (result.exitCode == _ok) {
177177
progress.complete('Local Supabase is running');
178178
return true;
@@ -191,10 +191,11 @@ Future<bool> _startSupabase(Directory root) async {
191191

192192
Future<void> _stopSupabase(Directory root) async {
193193
final progress = _logger.progress('Stopping the local Supabase stack');
194-
final result = await Process.run(
195-
'supabase',
196-
['stop', '--workdir', root.path],
197-
);
194+
final result = await Process.run('supabase', [
195+
'stop',
196+
'--workdir',
197+
root.path,
198+
]);
198199
if (result.exitCode == _ok) {
199200
progress.complete('Stopped the local Supabase stack');
200201
} else {
@@ -204,10 +205,13 @@ Future<void> _stopSupabase(Directory root) async {
204205
}
205206

206207
Future<Map<String, String>> _supabaseStatus(Directory root) async {
207-
final result = await Process.run(
208-
'supabase',
209-
['status', '-o', 'env', '--workdir', root.path],
210-
);
208+
final result = await Process.run('supabase', [
209+
'status',
210+
'-o',
211+
'env',
212+
'--workdir',
213+
root.path,
214+
]);
211215
if (result.exitCode != _ok) return {};
212216
return _parseEnv('${result.stdout}');
213217
}

examples/launcher/pubspec.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ publish_to: 'none'
66
version: 1.0.0+1
77

88
environment:
9-
sdk: '>=3.5.0 <4.0.0'
9+
sdk: '>=3.9.0 <4.0.0'
10+
11+
resolution: workspace
1012

1113
dependencies:
1214
mason_logger: ^0.3.0

examples/passkeys/lib/main.dart

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import 'package:flutter/material.dart';
2+
import 'package:passkeys/authenticator.dart';
23
import 'package:supabase_flutter/supabase_flutter.dart';
34

45
const supabaseUrl = String.fromEnvironment('SUPABASE_URL');
5-
const supabasePublishableKey =
6-
String.fromEnvironment('SUPABASE_PUBLISHABLE_KEY');
6+
const supabasePublishableKey = String.fromEnvironment(
7+
'SUPABASE_PUBLISHABLE_KEY',
8+
);
79

810
final messengerKey = GlobalKey<ScaffoldMessengerState>();
911

12+
final _passkeyAuthenticator = PasskeyAuthenticator();
13+
1014
Future<void> main() async {
1115
await Supabase.initialize(
1216
url: supabaseUrl,
@@ -109,7 +113,7 @@ class _SignInViewState extends State<SignInView> {
109113
Future<void> _signInWithPasskey() async {
110114
setState(() => _busy = true);
111115
try {
112-
await supabase.auth.signInWithPasskey();
116+
await supabase.auth.signInWithPasskey(_passkeyAuthenticator);
113117
} catch (error) {
114118
_showError(error);
115119
} finally {
@@ -187,7 +191,7 @@ class _SignedInViewState extends State<SignedInView> {
187191
/// whole ceremony, including the platform prompt.
188192
Future<void> _registerPasskey() async {
189193
try {
190-
await supabase.auth.registerPasskey();
194+
await supabase.auth.registerPasskey(_passkeyAuthenticator);
191195
await _refresh();
192196
} catch (error) {
193197
_showError(error);
@@ -268,36 +272,36 @@ class _SignedInViewState extends State<SignedInView> {
268272
child: _loading
269273
? const Center(child: CircularProgressIndicator())
270274
: _passkeys.isEmpty
271-
? const Center(child: Text('No passkeys yet.'))
272-
: RefreshIndicator(
273-
onRefresh: _refresh,
274-
child: ListView.builder(
275-
itemCount: _passkeys.length,
276-
itemBuilder: (context, index) {
277-
final passkey = _passkeys[index];
278-
return ListTile(
279-
leading: const Icon(Icons.vpn_key),
280-
title: Text(passkey.friendlyName ?? passkey.id),
281-
subtitle: Text(
282-
'Created ${passkey.createdAt.toLocal()}',
275+
? const Center(child: Text('No passkeys yet.'))
276+
: RefreshIndicator(
277+
onRefresh: _refresh,
278+
child: ListView.builder(
279+
itemCount: _passkeys.length,
280+
itemBuilder: (context, index) {
281+
final passkey = _passkeys[index];
282+
return ListTile(
283+
leading: const Icon(Icons.vpn_key),
284+
title: Text(passkey.friendlyName ?? passkey.id),
285+
subtitle: Text(
286+
'Created ${passkey.createdAt.toLocal()}',
287+
),
288+
trailing: Row(
289+
mainAxisSize: MainAxisSize.min,
290+
children: [
291+
IconButton(
292+
icon: const Icon(Icons.edit),
293+
onPressed: () => _rename(passkey),
283294
),
284-
trailing: Row(
285-
mainAxisSize: MainAxisSize.min,
286-
children: [
287-
IconButton(
288-
icon: const Icon(Icons.edit),
289-
onPressed: () => _rename(passkey),
290-
),
291-
IconButton(
292-
icon: const Icon(Icons.delete),
293-
onPressed: () => _delete(passkey),
294-
),
295-
],
295+
IconButton(
296+
icon: const Icon(Icons.delete),
297+
onPressed: () => _delete(passkey),
296298
),
297-
);
298-
},
299-
),
300-
),
299+
],
300+
),
301+
);
302+
},
303+
),
304+
),
301305
),
302306
],
303307
);

examples/passkeys/pubspec.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ environment:
99
sdk: '>=3.9.0 <4.0.0'
1010
flutter: '>=3.35.0'
1111

12+
resolution: workspace
13+
1214
dependencies:
1315
flutter:
1416
sdk: flutter
15-
supabase_flutter:
16-
path: ../../packages/supabase_flutter
17+
passkeys: ^2.21.1
18+
supabase_flutter: ^2.15.4
1719

1820
dev_dependencies:
1921
flutter_lints: ^4.0.0

0 commit comments

Comments
 (0)