Skip to content

Commit 699741f

Browse files
committed
Initial main branch
0 parents  commit 699741f

File tree

263 files changed

+25693
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

263 files changed

+25693
-0
lines changed

.github/workflows/ci.yml

Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
jobs:
15+
# Verify the library compiles and analyzes on the minimum supported Flutter.
16+
# Dev dependencies (lints, test helpers) may require a newer SDK, so this
17+
# job resolves only production dependencies and runs analysis without tests.
18+
compat-check:
19+
name: Compatibility Check (Flutter 3.22.0)
20+
runs-on: macos-latest
21+
timeout-minutes: 15
22+
23+
steps:
24+
- uses: actions/checkout@v4
25+
26+
# Pinned to commit SHA for supply chain security — update hash when upgrading.
27+
- uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0
28+
with:
29+
channel: stable
30+
flutter-version: '3.22.0'
31+
cache: true
32+
33+
- name: Remove incompatible dev dependencies and resolve
34+
run: |
35+
sed -i '' '/flutter_lints/d' pubspec.yaml example/pubspec.yaml
36+
sed -i '' 's/include: package:flutter_lints\/flutter.yaml/# lint package removed for compat check/' analysis_options.yaml example/analysis_options.yaml
37+
flutter pub get
38+
39+
- name: Analyze library code
40+
run: dart analyze --fatal-infos lib
41+
42+
- name: Run unit tests (excluding golden tests)
43+
run: flutter test --exclude-tags=golden
44+
45+
build:
46+
name: Build & Unit Tests
47+
runs-on: macos-latest
48+
timeout-minutes: 30
49+
50+
steps:
51+
- uses: actions/checkout@v4
52+
53+
# Pinned to commit SHA for supply chain security — update hash when upgrading.
54+
- uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0
55+
with:
56+
channel: stable
57+
flutter-version: '3.41.2'
58+
cache: true
59+
60+
- name: Install dependencies
61+
run: flutter pub get
62+
63+
- name: Check formatting
64+
run: |
65+
dart format --language-version=latest .
66+
if [ -n "$(git diff --name-only)" ]; then
67+
echo "::error::The following files need formatting:"
68+
git diff --name-only
69+
echo ""
70+
git diff
71+
exit 1
72+
fi
73+
74+
- name: Analyze
75+
run: dart analyze --fatal-infos
76+
77+
- name: Run unit tests with coverage
78+
run: flutter test --coverage
79+
80+
- name: Upload coverage
81+
uses: actions/upload-artifact@v4
82+
with:
83+
name: coverage
84+
path: coverage/lcov.info
85+
86+
test-ios:
87+
name: Integration Tests (iOS Simulator)
88+
needs: [compat-check, build]
89+
runs-on: macos-latest
90+
timeout-minutes: 30
91+
92+
steps:
93+
- uses: actions/checkout@v4
94+
95+
# Pinned to commit SHA for supply chain security — update hash when upgrading.
96+
- uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0
97+
with:
98+
channel: stable
99+
flutter-version: '3.41.2'
100+
cache: true
101+
102+
- name: Install dependencies
103+
run: flutter pub get
104+
working-directory: example
105+
106+
- name: Boot iOS simulator
107+
run: |
108+
DEVICE_ID=$(xcrun simctl list devices available -j | \
109+
python3 -c "
110+
import json, sys
111+
data = json.load(sys.stdin)
112+
for runtime, devices in data['devices'].items():
113+
if 'iOS' in runtime:
114+
for d in devices:
115+
if 'iPhone' in d['name'] and d['isAvailable']:
116+
print(d['udid'])
117+
sys.exit(0)
118+
sys.exit(1)
119+
")
120+
echo "DEVICE_ID=$DEVICE_ID" >> $GITHUB_ENV
121+
xcrun simctl boot "$DEVICE_ID" 2>/dev/null || true
122+
# Wait for simulator to be fully ready
123+
xcrun simctl bootstatus "$DEVICE_ID" -b
124+
125+
# Verify the simulator is visible to Flutter
126+
flutter devices
127+
128+
- name: Pre-build for iOS simulator
129+
run: flutter build ios --simulator --target=integration_test/run_all_test.dart
130+
working-directory: example
131+
132+
- name: Run integration tests on iOS
133+
run: |
134+
flutter test integration_test/run_all_test.dart \
135+
--timeout 20m \
136+
--ignore-timeouts \
137+
--dart-define=MIXPANEL_TOKEN="${{ secrets.MIXPANEL_TOKEN }}" \
138+
-d "$DEVICE_ID"
139+
working-directory: example
140+
141+
test-android:
142+
name: Integration Tests (Android API ${{ matrix.api-level }})
143+
needs: [compat-check, build]
144+
runs-on: ubuntu-latest
145+
timeout-minutes: 45
146+
strategy:
147+
fail-fast: false
148+
matrix:
149+
include:
150+
- api-level: 24
151+
target: default
152+
arch: x86_64
153+
profile: Nexus 6
154+
name: "Android 7.0 (Nougat)"
155+
- api-level: 34
156+
target: google_apis
157+
arch: x86_64
158+
profile: pixel_6
159+
name: "Android 14 (Latest)"
160+
161+
steps:
162+
- name: Free up disk space
163+
run: |
164+
sudo rm -rf /usr/share/dotnet
165+
sudo rm -rf /usr/local/lib/android/sdk/ndk
166+
sudo rm -rf /opt/ghc
167+
sudo rm -rf /usr/local/share/boost
168+
sudo rm -rf /usr/share/swift
169+
sudo rm -rf /opt/hostedtoolcache/CodeQL
170+
sudo apt-get clean
171+
172+
- name: Enable KVM
173+
run: |
174+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
175+
sudo udevadm control --reload-rules
176+
sudo udevadm trigger --name-match=kvm
177+
178+
- uses: actions/checkout@v4
179+
180+
- name: Set up JDK
181+
uses: actions/setup-java@v4
182+
with:
183+
distribution: 'zulu'
184+
java-version: 17
185+
186+
# Pinned to commit SHA for supply chain security — update hash when upgrading.
187+
- uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0
188+
with:
189+
channel: stable
190+
flutter-version: '3.41.2'
191+
cache: true
192+
193+
- name: Setup Gradle
194+
uses: gradle/gradle-build-action@v2
195+
196+
- name: Install dependencies
197+
run: flutter pub get
198+
working-directory: example
199+
200+
- name: AVD cache
201+
uses: actions/cache@v4
202+
id: avd-cache
203+
with:
204+
path: |
205+
~/.android/avd/*
206+
~/.android/adb*
207+
key: avd-${{ matrix.api-level }}-${{ matrix.target }}-${{ matrix.arch }}-${{ matrix.profile }}
208+
209+
- name: Create AVD and generate snapshot for caching
210+
if: steps.avd-cache.outputs.cache-hit != 'true'
211+
uses: reactivecircus/android-emulator-runner@5d6e86df22ab11632167a1a6b0c9ab0dc3469586 # v2
212+
with:
213+
api-level: ${{ matrix.api-level }}
214+
target: ${{ matrix.target }}
215+
arch: ${{ matrix.arch }}
216+
profile: ${{ matrix.profile }}
217+
force-avd-creation: false
218+
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -accel on
219+
disable-animations: false
220+
script: echo "Generated AVD snapshot for caching."
221+
222+
- name: Run integration tests on Android
223+
uses: reactivecircus/android-emulator-runner@5d6e86df22ab11632167a1a6b0c9ab0dc3469586 # v2
224+
with:
225+
api-level: ${{ matrix.api-level }}
226+
target: ${{ matrix.target }}
227+
arch: ${{ matrix.arch }}
228+
profile: ${{ matrix.profile }}
229+
force-avd-creation: false
230+
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -accel on
231+
disable-animations: true
232+
working-directory: example
233+
script: |
234+
flutter devices
235+
flutter build apk --target=integration_test/run_all_test.dart
236+
flutter test integration_test/run_all_test.dart --timeout 20m --ignore-timeouts --dart-define=MIXPANEL_TOKEN="${{ secrets.MIXPANEL_TOKEN }}"
237+
238+
test-macos:
239+
name: Integration Tests (macOS Desktop)
240+
needs: [compat-check, build]
241+
runs-on: macos-latest
242+
timeout-minutes: 30
243+
244+
steps:
245+
- uses: actions/checkout@v4
246+
247+
# Pinned to commit SHA for supply chain security — update hash when upgrading.
248+
- uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # v2.21.0
249+
with:
250+
channel: stable
251+
flutter-version: '3.41.2'
252+
cache: true
253+
254+
- name: Install dependencies
255+
run: flutter pub get
256+
working-directory: example
257+
258+
- name: Pre-build for macOS
259+
run: flutter build macos --target=integration_test/run_all_test.dart
260+
working-directory: example
261+
262+
- name: Run integration tests on macOS
263+
run: |
264+
flutter test integration_test/run_all_test.dart \
265+
--timeout 20m \
266+
--ignore-timeouts \
267+
--dart-define=MIXPANEL_TOKEN="${{ secrets.MIXPANEL_TOKEN }}" \
268+
-d macos
269+
working-directory: example
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Prepare Release
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Release version (e.g. 1.0.0)'
8+
required: true
9+
type: string
10+
11+
permissions:
12+
contents: write
13+
pull-requests: write
14+
15+
jobs:
16+
prepare-release:
17+
name: Prepare Release
18+
runs-on: macos-26
19+
20+
steps:
21+
- uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0
24+
25+
- name: Validate version format
26+
env:
27+
VERSION: ${{ inputs.version }}
28+
run: |
29+
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$'; then
30+
echo "::error::Invalid version format '$VERSION'. Expected semver (e.g. 1.0.0 or 1.0.0-beta.1)"
31+
exit 1
32+
fi
33+
34+
- name: Bump version and generate changelog
35+
env:
36+
GH_TOKEN: ${{ github.token }}
37+
VERSION: ${{ inputs.version }}
38+
run: ./tool/bump_version.sh "$VERSION"
39+
40+
- name: Clean up existing release branch and PR
41+
env:
42+
GH_TOKEN: ${{ github.token }}
43+
VERSION: ${{ inputs.version }}
44+
run: |
45+
BRANCH="release/$VERSION"
46+
EXISTING_PR=$(gh pr list --head "$BRANCH" --json number --jq '.[0].number' 2>/dev/null || true)
47+
if [[ -n "$EXISTING_PR" ]]; then
48+
echo "Closing existing PR #$EXISTING_PR and deleting branch"
49+
gh pr close "$EXISTING_PR" --delete-branch
50+
elif git ls-remote --exit-code origin "refs/heads/$BRANCH" &>/dev/null; then
51+
echo "Deleting existing remote branch $BRANCH"
52+
git push origin --delete "$BRANCH"
53+
fi
54+
55+
- name: Create pull request
56+
env:
57+
GH_TOKEN: ${{ github.token }}
58+
VERSION: ${{ inputs.version }}
59+
run: |
60+
git config user.name "github-actions[bot]"
61+
git config user.email "github-actions[bot]@users.noreply.github.com"
62+
git checkout -b "release/$VERSION"
63+
git add pubspec.yaml README.md lib/src/version.dart CHANGELOG.md
64+
git commit -m "chore: prepare release $VERSION"
65+
git push -u origin "release/$VERSION"
66+
gh pr create \
67+
--title "chore: release $VERSION" \
68+
--body "$(cat <<EOF
69+
Automated release preparation for v${VERSION}.
70+
71+
**Changes:**
72+
- Bumped version in \`pubspec.yaml\`, \`README.md\`, \`lib/src/version.dart\`
73+
- Generated \`CHANGELOG.md\` from merged PRs since last tag
74+
75+
**Before merging**, review the changelog and edit if needed.
76+
77+
**After merging**, run the **Publish to pub.dev** workflow:
78+
1. Go to Actions > Publish to pub.dev
79+
2. Enter \`main\` as the git ref
80+
3. Enter \`${VERSION}\` as the version confirmation
81+
EOF
82+
)"

0 commit comments

Comments
 (0)