-
Notifications
You must be signed in to change notification settings - Fork 13
352 lines (297 loc) · 15.7 KB
/
flutter-upgrade.yml
File metadata and controls
352 lines (297 loc) · 15.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
name: Flutter Auto Upgrade
on:
schedule:
# Run every Sunday at 2 AM UTC
- cron: '0 2 * * 0'
workflow_dispatch: # Allow manual triggering
jobs:
check-and-upgrade-flutter:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
channel: 'stable'
- name: Get current Flutter version
id: current-version
run: |
# Check if we have a tracked version file
if [ -f ".flutter-version-tracked" ]; then
TRACKED_VERSION=$(cat .flutter-version-tracked)
echo "tracked=$TRACKED_VERSION" >> $GITHUB_OUTPUT
echo "Previously tracked Flutter version: $TRACKED_VERSION"
else
# Get current installed version as fallback
CURRENT_VERSION=$(flutter --version | head -n 1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
echo "tracked=$CURRENT_VERSION" >> $GITHUB_OUTPUT
echo "No tracked version found, using current Flutter version: $CURRENT_VERSION"
fi
# Also get the actual installed version for reference
INSTALLED_VERSION=$(flutter --version | head -n 1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
echo "installed=$INSTALLED_VERSION" >> $GITHUB_OUTPUT
echo "Currently installed Flutter version: $INSTALLED_VERSION"
- name: Check for Flutter upgrades
id: check-upgrade
run: |
# Get the latest stable Flutter version (filter out pre-releases)
LATEST_VERSION=$(curl -s https://api.github.com/repos/flutter/flutter/releases | grep '"tag_name"' | grep -v 'pre' | head -1 | cut -d '"' -f 4)
# Fallback to current installed version if API call fails
if [ -z "$LATEST_VERSION" ]; then
LATEST_VERSION=${{ steps.current-version.outputs.installed }}
echo "Warning: Could not fetch latest version from GitHub, using installed version"
fi
echo "latest=$LATEST_VERSION" >> $GITHUB_OUTPUT
echo "Latest Flutter version: $LATEST_VERSION"
# Compare with tracked version (not current installed version)
TRACKED_VERSION="${{ steps.current-version.outputs.tracked }}"
if [ "$TRACKED_VERSION" != "$LATEST_VERSION" ]; then
echo "upgrade_available=true" >> $GITHUB_OUTPUT
echo "Upgrade available: $TRACKED_VERSION -> $LATEST_VERSION"
else
echo "upgrade_available=false" >> $GITHUB_OUTPUT
echo "Flutter is already up to date (tracked: $TRACKED_VERSION)"
fi
- name: Check for dependency updates
id: check-deps
run: |
echo "Checking for dependency updates..."
# Check dio version
DIO_CURRENT=$(grep "dio:" pubspec.yaml | sed 's/.*: \^//')
echo "Current dio version: $DIO_CURRENT"
DIO_LATEST=$(curl -s https://pub.dev/api/packages/dio | jq -r '.latest.version')
echo "Latest dio version: $DIO_LATEST"
# Check http version
HTTP_CURRENT=$(grep "http:" pubspec.yaml | sed 's/.*: \^//')
echo "Current http version: $HTTP_CURRENT"
HTTP_LATEST=$(curl -s https://pub.dev/api/packages/http | jq -r '.latest.version')
echo "Latest http version: $HTTP_LATEST"
# Set outputs
echo "dio_current=$DIO_CURRENT" >> $GITHUB_OUTPUT
echo "dio_latest=$DIO_LATEST" >> $GITHUB_OUTPUT
echo "http_current=$HTTP_CURRENT" >> $GITHUB_OUTPUT
echo "http_latest=$HTTP_LATEST" >> $GITHUB_OUTPUT
# Check if dependency updates are available
DEPS_AVAILABLE=false
if [ "$DIO_CURRENT" != "$DIO_LATEST" ]; then
echo "Dio update available: $DIO_CURRENT -> $DIO_LATEST"
DEPS_AVAILABLE=true
fi
if [ "$HTTP_CURRENT" != "$HTTP_LATEST" ]; then
echo "HTTP update available: $HTTP_CURRENT -> $HTTP_LATEST"
DEPS_AVAILABLE=true
fi
echo "deps_available=$DEPS_AVAILABLE" >> $GITHUB_OUTPUT
if [ "$DEPS_AVAILABLE" = "true" ]; then
echo "Dependency updates are available"
else
echo "All dependencies are up to date"
fi
- name: Create upgrade branch
if: steps.check-upgrade.outputs.upgrade_available == 'true' || steps.check-deps.outputs.deps_available == 'true'
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
# Create unique branch name with timestamp to avoid conflicts
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
if [ "${{ steps.check-upgrade.outputs.upgrade_available }}" == "true" ]; then
BRANCH_NAME="flutter/auto-upgrade-${{ steps.check-upgrade.outputs.latest }}-$TIMESTAMP"
else
BRANCH_NAME="deps/auto-update-$TIMESTAMP"
fi
# Delete remote branch if it exists (cleanup from previous runs)
git push origin --delete "$BRANCH_NAME" 2>/dev/null || echo "Remote branch doesn't exist, continuing..."
# Create and checkout new branch
git checkout -b "$BRANCH_NAME"
echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV
- name: Upgrade Flutter
if: steps.check-upgrade.outputs.upgrade_available == 'true'
run: |
echo "Upgrading Flutter to ${{ steps.check-upgrade.outputs.latest }}"
# Try normal upgrade first
if ! flutter upgrade; then
echo "Normal upgrade failed, attempting force upgrade..."
flutter upgrade --force
fi
# Update Flutter version in pubspec.yaml if it exists with version constraints
if [ -f "pubspec.yaml" ] && grep -q "flutter:" "pubspec.yaml"; then
echo "Checking pubspec.yaml for Flutter version constraints..."
# Note: This is a basic approach - you might need more sophisticated version handling
fi
- name: Update dependencies
if: steps.check-deps.outputs.deps_available == 'true'
run: |
echo "Updating dependencies..."
# Update dio if newer version available
if [ "${{ steps.check-deps.outputs.dio_current }}" != "${{ steps.check-deps.outputs.dio_latest }}" ]; then
echo "Updating dio from ${{ steps.check-deps.outputs.dio_current }} to ${{ steps.check-deps.outputs.dio_latest }}"
sed -i.bak "s/dio: \^${{ steps.check-deps.outputs.dio_current }}/dio: ^${{ steps.check-deps.outputs.dio_latest }}/" pubspec.yaml
fi
# Update http if newer version available
if [ "${{ steps.check-deps.outputs.http_current }}" != "${{ steps.check-deps.outputs.http_latest }}" ]; then
echo "Updating http from ${{ steps.check-deps.outputs.http_current }} to ${{ steps.check-deps.outputs.http_latest }}"
sed -i.bak "s/http: \^${{ steps.check-deps.outputs.http_current }}/http: ^${{ steps.check-deps.outputs.http_latest }}/" pubspec.yaml
fi
# Clean up backup files
rm -f pubspec.yaml.bak
- name: Apply automatic fixes
if: steps.check-upgrade.outputs.upgrade_available == 'true' || steps.check-deps.outputs.deps_available == 'true'
run: |
echo "Applying automatic Dart fixes for deprecations and lint issues..."
# First check what fixes are available (dry run)
echo "Checking available fixes:"
dart fix --dry-run || echo "No automatic fixes available or dry-run failed"
# Apply the fixes
echo "Applying fixes:"
dart fix --apply || echo "No fixes applied or apply failed"
- name: Update tracked Flutter version
if: steps.check-upgrade.outputs.upgrade_available == 'true'
run: |
echo "Updating tracked Flutter version to ${{ steps.check-upgrade.outputs.latest }}"
echo "${{ steps.check-upgrade.outputs.latest }}" > .flutter-version-tracked
echo "Tracked version file updated"
- name: Install dependencies and test
if: steps.check-upgrade.outputs.upgrade_available == 'true' || steps.check-deps.outputs.deps_available == 'true'
run: |
flutter pub get
# Run basic checks to ensure upgrade didn't break anything
echo "Running Flutter doctor..."
flutter doctor
echo "Analyzing project..."
flutter analyze
echo "Running tests..."
flutter test || echo "Tests failed - upgrade may need manual review"
- name: Check for changes
if: steps.check-upgrade.outputs.upgrade_available == 'true' || steps.check-deps.outputs.deps_available == 'true'
id: check-changes
run: |
git add .
if git diff --staged --quiet; then
echo "has_changes=false" >> $GITHUB_OUTPUT
echo "No changes detected after Flutter upgrade"
else
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "Changes detected after Flutter upgrade"
fi
- name: Commit changes
if: steps.check-changes.outputs.has_changes == 'true'
run: |
# Create appropriate commit message based on what was updated
if [ "${{ steps.check-upgrade.outputs.upgrade_available }}" == "true" ] && [ "${{ steps.check-deps.outputs.deps_available }}" == "true" ]; then
COMMIT_MSG="chore: upgrade Flutter to ${{ steps.check-upgrade.outputs.latest }} and update dependencies
- Automated Flutter upgrade from ${{ steps.current-version.outputs.tracked }} to ${{ steps.check-upgrade.outputs.latest }}
- Updated dependencies (dio, http)
- Applied automatic fixes with dart fix
- Updated tracked Flutter version
- Verified with flutter analyze and flutter test"
elif [ "${{ steps.check-upgrade.outputs.upgrade_available }}" == "true" ]; then
COMMIT_MSG="chore: upgrade Flutter to ${{ steps.check-upgrade.outputs.latest }}
- Automated Flutter upgrade from ${{ steps.current-version.outputs.tracked }} to ${{ steps.check-upgrade.outputs.latest }}
- Applied automatic fixes with dart fix
- Updated tracked Flutter version
- Verified with flutter analyze and flutter test"
else
COMMIT_MSG="chore: update dependencies
- Updated dependencies (dio: ${{ steps.check-deps.outputs.dio_latest }}, http: ${{ steps.check-deps.outputs.http_latest }})
- Applied automatic fixes with dart fix
- Verified with flutter analyze and flutter test"
fi
git commit -m "$COMMIT_MSG"
- name: Push changes
if: steps.check-changes.outputs.has_changes == 'true'
run: |
# Try normal push first, then force push if it fails
if ! git push origin "$BRANCH_NAME"; then
echo "Normal push failed, attempting force push..."
git push --force origin "$BRANCH_NAME"
fi
- name: Create Pull Request
if: steps.check-changes.outputs.has_changes == 'true'
uses: actions/github-script@v7
with:
script: |
const latestVersion = '${{ steps.check-upgrade.outputs.latest }}';
const trackedVersion = '${{ steps.current-version.outputs.tracked }}';
const { data: pullRequest } = await github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `chore: upgrade Flutter to ${latestVersion} and dependencies`,
head: process.env.BRANCH_NAME,
base: 'master', // Change to 'main' if that's your default branch
body: `## Flutter Auto Upgrade
This PR was automatically created to upgrade Flutter from **${trackedVersion}** to **${latestVersion}** and update dependencies.
### Changes Made:
- Upgraded Flutter to the latest stable version
- Updated dependencies with \`flutter pub get\`
- Applied automatic fixes for deprecations with \`dart fix --apply\`
- Used force upgrade fallback if normal upgrade failed
- Verified with \`flutter analyze\`
- Ran \`flutter test\` (check CI results)
### Review Checklist:
- [ ] Verify all tests pass in CI
- [ ] Check for any breaking changes in Flutter release notes
- [ ] Test the app manually if needed
- [ ] Review any dependency conflicts
### Flutter Release Notes:
Check the [Flutter releases page](https://github.com/flutter/flutter/releases/tag/${latestVersion}) for detailed information about this version.
---
*This PR was created automatically by the Flutter Auto Upgrade workflow.*`
});
console.log('Created PR #' + pullRequest.number);
- name: Add labels to PR
if: steps.check-changes.outputs.has_changes == 'true'
continue-on-error: true
uses: actions/github-script@v7
with:
script: |
try {
// Get the PR number from the previous step
const prs = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
head: context.repo.owner + ':' + process.env.BRANCH_NAME,
state: 'open'
});
if (prs.data.length > 0) {
const prNumber = prs.data[0].number;
console.log(`Attempting to add labels to PR #${prNumber}`);
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
labels: ['dependencies', 'flutter', 'automated', 'upgrade']
});
console.log('Successfully added labels to PR');
} else {
console.log('No PR found to add labels to');
}
} catch (error) {
console.log('Failed to add labels to PR (this is non-critical):', error.message);
console.log('The PR was created successfully, labels can be added manually if needed');
}
- name: Summary
run: |
if [ "${{ steps.check-upgrade.outputs.upgrade_available }}" == "true" ]; then
if [ "${{ steps.check-changes.outputs.has_changes }}" == "true" ]; then
echo "Flutter upgrade available, changes detected, and PR created!"
echo "Upgraded from ${{ steps.current-version.outputs.tracked }} to ${{ steps.check-upgrade.outputs.latest }}"
echo "Branch created: $BRANCH_NAME"
else
echo "Flutter upgrade available, but no changes detected"
fi
elif [ "${{ steps.check-deps.outputs.deps_available }}" == "true" ]; then
if [ "${{ steps.check-changes.outputs.has_changes }}" == "true" ]; then
echo "Dependency updates available, changes detected, and PR created!"
echo "Branch created: $BRANCH_NAME"
else
echo "Dependency updates available, but no changes detected"
fi
else
echo "Flutter is already up to date (tracked: ${{ steps.current-version.outputs.tracked }})"
fi