project-auto-wizard 0.13.3 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/project-auto-wizard.js +18 -4
- package/package.json +2 -2
- package/payload/config/breaking-changes.json +28 -14
- package/payload/config/wizard-prompts.yml +102 -46
- package/payload/flutter-app/android/fastlane/Fastfile.playstore +44 -32
- package/payload/flutter-app/ios/ExportOptions.plist +8 -8
- package/payload/flutter-app/ios/fastlane/Fastfile +57 -43
- package/payload/scripts/changelog_manager.py +296 -257
- package/payload/scripts/issue_helper.py +54 -50
- package/payload/scripts/messages.py +2279 -0
- package/payload/scripts/truncate_release_notes.py +7 -6
- package/payload/scripts/version_manager.py +64 -61
- package/payload/version.yml.template +2 -1
- package/payload/workflows/common/PROJECT-COMMON-AI-PR-SUMMARY.yaml +17 -12
- package/payload/workflows/common/PROJECT-COMMON-AUTO-CHANGELOG-CONTROL.yaml +59 -34
- package/payload/workflows/common/PROJECT-COMMON-ISSUE-HELPER.yaml +17 -15
- package/payload/workflows/common/PROJECT-COMMON-README-VERSION-UPDATE.yaml +17 -10
- package/payload/workflows/common/PROJECT-COMMON-RELEASE-PUBLISH.yaml +54 -44
- package/payload/workflows/common/PROJECT-COMMON-VERSION-CONTROL.yaml +24 -17
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-FIREBASE-CICD.yaml +194 -184
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-PLAYSTORE-CICD.yaml +226 -213
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-SELFHOSTED-CICD.yaml +46 -42
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-TEST-APK.yaml +334 -241
- package/payload/workflows/flutter/PROJECT-FLUTTER-APP-BUILD-TRIGGER.yaml +152 -128
- package/payload/workflows/flutter/PROJECT-FLUTTER-CI.yaml +246 -188
- package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT.yaml +353 -238
- package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TESTFLIGHT.yaml +96 -85
- package/payload/workflows/go/PROJECT-GO-CI.yaml +47 -36
- package/payload/workflows/go/PROJECT-GO-PR-PREVIEW.yaml +945 -508
- package/payload/workflows/go/PROJECT-GO-SIMPLE-CICD.yaml +155 -133
- package/payload/workflows/next/PROJECT-NEXT-CI.yaml +76 -60
- package/payload/workflows/next/PROJECT-NEXT-CICD.yaml +97 -77
- package/payload/workflows/python/PROJECT-PYTHON-CI.yaml +62 -47
- package/payload/workflows/python/PROJECT-PYTHON-PR-PREVIEW.yaml +942 -505
- package/payload/workflows/python/PROJECT-PYTHON-SIMPLE-CICD.yaml +148 -126
- package/payload/workflows/react/PROJECT-REACT-CI.yaml +86 -70
- package/payload/workflows/react/PROJECT-REACT-CICD.yaml +112 -92
- package/payload/workflows/spring/PROJECT-SPRING-CI.yml +112 -82
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-NGINX-CICD.yaml +180 -150
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-TRAEFIK-CICD.yaml +161 -131
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-PR-PREVIEW.yaml +970 -549
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-SIMPLE-CICD.yaml +193 -162
- package/src/cli/args.js +98 -52
- package/src/cli/help.js +8 -41
- package/src/commands/doctor.js +85 -89
- package/src/commands/dry-run.js +63 -43
- package/src/commands/full.js +79 -77
- package/src/commands/install-settings.js +16 -15
- package/src/commands/interactive-flutter.js +20 -19
- package/src/commands/interactive.js +135 -132
- package/src/commands/purge.js +47 -42
- package/src/commands/status.js +36 -36
- package/src/commands/uninstall.js +43 -41
- package/src/context.js +12 -11
- package/src/core/assets.js +12 -11
- package/src/core/baseline.js +27 -27
- package/src/core/branches.js +29 -27
- package/src/core/branding.js +7 -6
- package/src/core/breaking-check.js +22 -21
- package/src/core/breaking.js +15 -8
- package/src/core/copy/app-files.js +5 -4
- package/src/core/copy/flutter-app.js +8 -8
- package/src/core/copy/gitignore.js +58 -50
- package/src/core/copy/readme.js +45 -35
- package/src/core/copy/simple.js +16 -15
- package/src/core/copy/workflows.js +131 -124
- package/src/core/deploy-style.js +51 -48
- package/src/core/detect-fs.js +57 -57
- package/src/core/detect.js +67 -65
- package/src/core/errors.js +2 -2
- package/src/core/flutter-doctor.js +17 -16
- package/src/core/flutter-hooks.js +33 -32
- package/src/core/flutter-options.js +34 -33
- package/src/core/fsutil.js +12 -12
- package/src/core/installed-stores.js +4 -4
- package/src/core/logger.js +42 -40
- package/src/core/paths-resolve.js +88 -86
- package/src/core/paths.js +10 -10
- package/src/core/release-options.js +8 -8
- package/src/core/removal-exec.js +14 -13
- package/src/core/removal-plan.js +37 -37
- package/src/core/types.js +47 -47
- package/src/core/verify.js +44 -38
- package/src/core/version-yml.js +76 -68
- package/src/core/wizard-env.js +46 -46
- package/src/core/wizard-labels.js +63 -41
- package/src/i18n/catalog/en/cli.js +50 -0
- package/src/i18n/catalog/en/commands.js +187 -0
- package/src/i18n/catalog/en/copy.js +19 -0
- package/src/i18n/catalog/en/core.js +74 -0
- package/src/i18n/catalog/en/core2.js +15 -0
- package/src/i18n/catalog/en/ui.js +221 -0
- package/src/i18n/catalog/en.js +12 -0
- package/src/i18n/catalog/index.js +5 -0
- package/src/i18n/catalog/ko/cli.js +50 -0
- package/src/i18n/catalog/ko/commands.js +187 -0
- package/src/i18n/catalog/ko/copy.js +19 -0
- package/src/i18n/catalog/ko/core.js +74 -0
- package/src/i18n/catalog/ko/core2.js +15 -0
- package/src/i18n/catalog/ko/ui.js +221 -0
- package/src/i18n/catalog/ko.js +10 -0
- package/src/i18n/index.js +44 -0
- package/src/i18n/languages.js +9 -0
- package/src/index.js +128 -94
- package/src/ui/ansi.js +7 -7
- package/src/ui/banner.js +7 -6
- package/src/ui/env-plan.js +82 -81
- package/src/ui/prompts.js +97 -122
- package/src/ui/readline-engine.js +59 -58
- package/src/ui/status-cards.js +37 -31
- package/src/ui/summary.js +89 -88
|
@@ -1,77 +1,77 @@
|
|
|
1
1
|
# project-auto-wizard:managed-workflow
|
|
2
|
-
# Flutter Android Firebase App Distribution
|
|
2
|
+
# Flutter Android Firebase App Distribution deploy
|
|
3
3
|
#
|
|
4
|
-
# {{MAIN_BRANCH}}
|
|
5
|
-
# Firebase App Distribution
|
|
4
|
+
# On a push to the {{MAIN_BRANCH}} branch, builds the Android AAB and
|
|
5
|
+
# deploys it to Firebase App Distribution.
|
|
6
6
|
#
|
|
7
|
-
# PlayStore CICD
|
|
8
|
-
#
|
|
7
|
+
# After the same build process as the PlayStore CICD (AAB + version check),
|
|
8
|
+
# it uploads to Firebase App Distribution instead of the Play Store.
|
|
9
9
|
#
|
|
10
|
-
#
|
|
10
|
+
# Required GitHub Secrets
|
|
11
11
|
#
|
|
12
12
|
# Release Keystore:
|
|
13
|
-
# RELEASE_KEYSTORE_BASE64:
|
|
14
|
-
# RELEASE_KEYSTORE_PASSWORD: keystore
|
|
13
|
+
# RELEASE_KEYSTORE_BASE64: signing keystore (base64)
|
|
14
|
+
# RELEASE_KEYSTORE_PASSWORD: keystore password
|
|
15
15
|
# RELEASE_KEY_ALIAS: key alias
|
|
16
|
-
# RELEASE_KEY_PASSWORD: key
|
|
16
|
+
# RELEASE_KEY_PASSWORD: key password
|
|
17
17
|
#
|
|
18
18
|
# Firebase:
|
|
19
|
-
# FIREBASE_SERVICE_ACCOUNT_JSON_BASE64: Firebase
|
|
19
|
+
# FIREBASE_SERVICE_ACCOUNT_JSON_BASE64: Firebase service account JSON (base64)
|
|
20
20
|
#
|
|
21
|
-
#
|
|
22
|
-
# ENV_FILE
|
|
23
|
-
# GOOGLE_SERVICES_JSON (
|
|
21
|
+
# Environment settings (optional):
|
|
22
|
+
# ENV_FILE or ENV: contents of the .env file (either one; ENV_FILE takes precedence)
|
|
23
|
+
# GOOGLE_SERVICES_JSON (optional): Firebase google-services.json
|
|
24
24
|
#
|
|
25
|
-
#
|
|
26
|
-
# FIREBASE_APP_ID
|
|
25
|
+
# Note: register the Secrets above under the repository Settings → Secrets and variables → Actions.
|
|
26
|
+
# Edit FIREBASE_APP_ID and FIREBASE_TESTER_GROUP directly in the env section below.
|
|
27
27
|
#
|
|
28
|
-
#
|
|
29
|
-
# APP_ARTIFACT_NAME :
|
|
30
|
-
# FLUTTER_VERSION : Flutter SDK
|
|
31
|
-
# JAVA_VERSION : Java
|
|
32
|
-
# FIREBASE_APP_ID : Firebase
|
|
33
|
-
# FIREBASE_TESTER_GROUP : Firebase
|
|
28
|
+
# Project settings (edit in the env section)
|
|
29
|
+
# APP_ARTIFACT_NAME : project name
|
|
30
|
+
# FLUTTER_VERSION : Flutter SDK version (empty = latest stable)
|
|
31
|
+
# JAVA_VERSION : Java version
|
|
32
|
+
# FIREBASE_APP_ID : Firebase app ID (see the Firebase Console)
|
|
33
|
+
# FIREBASE_TESTER_GROUP : Firebase tester group name
|
|
34
34
|
#
|
|
35
|
-
#
|
|
36
|
-
# 1. Firebase Console → App Distribution →
|
|
37
|
-
# 2. Firebase
|
|
38
|
-
# 3. GitHub Secrets
|
|
39
|
-
# 4.
|
|
35
|
+
# Setup:
|
|
36
|
+
# 1. Firebase Console → App Distribution → create a tester group
|
|
37
|
+
# 2. Create the Firebase service account JSON (base64 encoded)
|
|
38
|
+
# 3. Register FIREBASE_SERVICE_ACCOUNT_JSON_BASE64 in GitHub Secrets
|
|
39
|
+
# 4. Edit FIREBASE_APP_ID and FIREBASE_TESTER_GROUP in the env section
|
|
40
40
|
|
|
41
41
|
name: PROJECT-FLUTTER-ANDROID-FIREBASE-APPDIST-CICD
|
|
42
42
|
|
|
43
43
|
on:
|
|
44
44
|
push:
|
|
45
45
|
branches: ["{{MAIN_BRANCH}}"]
|
|
46
|
-
# @wizard paths-anchor (
|
|
46
|
+
# @wizard paths-anchor (in a monorepo the installer injects a paths filter here)
|
|
47
47
|
workflow_dispatch:
|
|
48
48
|
|
|
49
49
|
env:
|
|
50
|
-
#
|
|
51
|
-
#
|
|
50
|
+
# Project settings (edit the values below)
|
|
51
|
+
# Project name
|
|
52
52
|
APP_ARTIFACT_NAME: "__APP_ARTIFACT_NAME__" # @wizard ask:@repo
|
|
53
|
-
# Flutter/Java
|
|
54
|
-
# Flutter SDK
|
|
55
|
-
#
|
|
53
|
+
# Flutter/Java versions
|
|
54
|
+
# Flutter SDK version - leave empty to use the latest stable channel (matches the SDK constraint of a fresh flutter create project).
|
|
55
|
+
# To pin a version, write it like "3.38.9". It must satisfy the environment.sdk range in pubspec.yaml.
|
|
56
56
|
FLUTTER_VERSION: ""
|
|
57
57
|
JAVA_VERSION: "__JAVA_VERSION__" # @wizard ask:17
|
|
58
58
|
PROJECT_TYPE: "flutter"
|
|
59
|
-
# Flutter
|
|
59
|
+
# Flutter root path (relative to the repo root): "." for a single repo, "app" etc. for a monorepo - set automatically at install
|
|
60
60
|
FLUTTER_PROJECT_DIR: "." # @wizard auto:flutter-root
|
|
61
|
-
#
|
|
61
|
+
# How env vars are passed (dart-define | dotenv) - set automatically from the install-time choice
|
|
62
62
|
ENV_MODE: "dart-define" # @wizard auto:flutter-env-mode
|
|
63
|
-
# Firebase App Distribution
|
|
63
|
+
# Firebase App Distribution settings
|
|
64
64
|
FIREBASE_APP_ID: "your-firebase-app-id"
|
|
65
65
|
FIREBASE_TESTER_GROUP: "testers"
|
|
66
66
|
|
|
67
67
|
jobs:
|
|
68
68
|
prepare-build:
|
|
69
|
-
name:
|
|
69
|
+
name: Environment setup and preparation
|
|
70
70
|
runs-on: ubuntu-latest
|
|
71
71
|
defaults:
|
|
72
72
|
run:
|
|
73
73
|
working-directory: ${{ env.FLUTTER_PROJECT_DIR }}
|
|
74
|
-
#
|
|
74
|
+
# Run only when the CHANGELOG workflow succeeded
|
|
75
75
|
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' }}
|
|
76
76
|
|
|
77
77
|
outputs:
|
|
@@ -86,9 +86,9 @@ jobs:
|
|
|
86
86
|
ref: "{{MAIN_BRANCH}}"
|
|
87
87
|
fetch-depth: 0
|
|
88
88
|
|
|
89
|
-
#
|
|
90
|
-
# ENV_FILE
|
|
91
|
-
- name:
|
|
89
|
+
# Without the signing/upload Secrets the run would only fail well into the build, so report all missing names first and stop
|
|
90
|
+
# ENV_FILE and GOOGLE_SERVICES_JSON are optional, so they are not checked
|
|
91
|
+
- name: Pre-deploy check (Secrets)
|
|
92
92
|
env:
|
|
93
93
|
RELEASE_KEYSTORE_BASE64: ${{ secrets.RELEASE_KEYSTORE_BASE64 }}
|
|
94
94
|
RELEASE_KEYSTORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }}
|
|
@@ -96,24 +96,25 @@ jobs:
|
|
|
96
96
|
RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
|
|
97
97
|
FIREBASE_SERVICE_ACCOUNT_JSON_BASE64: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON_BASE64 }}
|
|
98
98
|
run: |
|
|
99
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
99
100
|
MISSING=""
|
|
100
101
|
for NAME in RELEASE_KEYSTORE_BASE64 RELEASE_KEYSTORE_PASSWORD RELEASE_KEY_ALIAS RELEASE_KEY_PASSWORD FIREBASE_SERVICE_ACCOUNT_JSON_BASE64; do
|
|
101
102
|
[ -n "${!NAME}" ] || MISSING="$MISSING $NAME"
|
|
102
103
|
done
|
|
103
104
|
FAILED=false
|
|
104
105
|
if [ -n "$MISSING" ]; then
|
|
105
|
-
echo "::error title
|
|
106
|
+
echo "::error title=$(m flutter_a.precheck_missing_title)::$(m flutter_a.precheck_missing_body missing="$MISSING")"
|
|
106
107
|
FAILED=true
|
|
107
108
|
fi
|
|
108
|
-
#
|
|
109
|
+
# The target app ID is not a Secret; it is the value in this file's env section
|
|
109
110
|
if [ -z "$FIREBASE_APP_ID" ] || [ "$FIREBASE_APP_ID" = "your-firebase-app-id" ]; then
|
|
110
|
-
echo "::error title
|
|
111
|
+
echo "::error title=$(m flutter_a.precheck_firebase_app_id_title)::$(m flutter_a.precheck_firebase_app_id_body)"
|
|
111
112
|
FAILED=true
|
|
112
113
|
fi
|
|
113
114
|
if [ "$FAILED" = "true" ]; then
|
|
114
115
|
exit 1
|
|
115
116
|
fi
|
|
116
|
-
|
|
117
|
+
m flutter_a.precheck_passed_firebase
|
|
117
118
|
|
|
118
119
|
- name: Pull latest changes
|
|
119
120
|
run: git pull origin {{MAIN_BRANCH}}
|
|
@@ -153,63 +154,65 @@ jobs:
|
|
|
153
154
|
dart run build_runner build --delete-conflicting-outputs
|
|
154
155
|
fi
|
|
155
156
|
|
|
156
|
-
- name:
|
|
157
|
+
- name: Get current version
|
|
157
158
|
id: current_version
|
|
158
|
-
working-directory: ${{ github.workspace }} # version_manager.py
|
|
159
|
+
working-directory: ${{ github.workspace }} # version_manager.py must read the repo-root version.yml
|
|
159
160
|
run: |
|
|
160
|
-
|
|
161
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
162
|
+
# Get VERSION (x.y.z format)
|
|
161
163
|
VERSION=$(python3 .github/scripts/version_manager.py get | tail -n 1)
|
|
162
164
|
|
|
163
|
-
# VERSION_CODE
|
|
165
|
+
# Get VERSION_CODE (a simple incrementing number managed in version.yml)
|
|
164
166
|
VERSION_CODE=$(python3 .github/scripts/version_manager.py get-code | tail -n 1)
|
|
165
167
|
|
|
166
|
-
#
|
|
168
|
+
# Print the result
|
|
167
169
|
echo "✅ VERSION: $VERSION"
|
|
168
170
|
echo "✅ VERSION_CODE: $VERSION_CODE"
|
|
169
|
-
|
|
171
|
+
m flutter_a.project_type project_type="${{ env.PROJECT_TYPE }}"
|
|
170
172
|
|
|
171
|
-
# GitHub outputs
|
|
173
|
+
# Set GitHub outputs
|
|
172
174
|
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
173
175
|
echo "version_code=$VERSION_CODE" >> $GITHUB_OUTPUT
|
|
174
176
|
echo "project_type=${{ env.PROJECT_TYPE }}" >> $GITHUB_OUTPUT
|
|
175
177
|
|
|
176
|
-
#
|
|
178
|
+
# Also set as environment variables (used by scripts)
|
|
177
179
|
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
|
178
180
|
echo "VERSION_CODE=$VERSION_CODE" >> $GITHUB_ENV
|
|
179
181
|
echo "TODAY=$(date '+%Y-%m-%d')" >> $GITHUB_ENV
|
|
180
182
|
echo "TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')" >> $GITHUB_ENV
|
|
181
183
|
echo "PROJECT_TYPE=${{ env.PROJECT_TYPE }}" >> $GITHUB_ENV
|
|
182
184
|
|
|
183
|
-
- name:
|
|
185
|
+
- name: Generate release notes
|
|
184
186
|
id: release_notes
|
|
185
|
-
working-directory: ${{ github.workspace }} # CHANGELOG.json
|
|
187
|
+
working-directory: ${{ github.workspace }} # CHANGELOG.json, changelog_manager.py and final_release_notes.txt (paired with the upload) are relative to the repo root
|
|
186
188
|
run: |
|
|
189
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
187
190
|
VERSION="${{ steps.current_version.outputs.version }}"
|
|
188
191
|
|
|
189
192
|
if [ -f "CHANGELOG.json" ]; then
|
|
190
|
-
|
|
191
|
-
# CHANGELOG.md
|
|
193
|
+
m flutter_a.extracting_v_release_notes_changelog version="$VERSION"
|
|
194
|
+
# Generate CHANGELOG.md
|
|
192
195
|
python3 ./.github/scripts/changelog_manager.py generate-md
|
|
193
196
|
|
|
194
|
-
# changelog_manager.py export
|
|
197
|
+
# Extract the release notes with changelog_manager.py export
|
|
195
198
|
python3 ./.github/scripts/changelog_manager.py export --version $VERSION --output final_release_notes.txt
|
|
196
199
|
|
|
197
200
|
if [ -s final_release_notes.txt ]; then
|
|
198
|
-
|
|
199
|
-
|
|
201
|
+
m flutter_a.release_notes_extracted
|
|
202
|
+
m flutter_a.extracted_release_notes
|
|
200
203
|
echo "----------------------------------------"
|
|
201
204
|
cat final_release_notes.txt
|
|
202
205
|
echo "----------------------------------------"
|
|
203
206
|
echo "RELEASE_NOTES_FOUND=true" >> $GITHUB_ENV
|
|
204
207
|
else
|
|
205
|
-
|
|
208
|
+
m flutter_a.failed_extract_release_notes
|
|
206
209
|
echo "RELEASE_NOTES_FOUND=false" >> $GITHUB_ENV
|
|
207
|
-
|
|
210
|
+
m flutter_a.default_release_note version="$VERSION" > final_release_notes.txt
|
|
208
211
|
fi
|
|
209
212
|
else
|
|
210
|
-
|
|
213
|
+
m flutter_a.changelog_json_not_found_using
|
|
211
214
|
echo "RELEASE_NOTES_FOUND=false" >> $GITHUB_ENV
|
|
212
|
-
|
|
215
|
+
m flutter_a.default_release_note version="$VERSION" > final_release_notes.txt
|
|
213
216
|
fi
|
|
214
217
|
|
|
215
218
|
- name: Upload release notes
|
|
@@ -219,8 +222,8 @@ jobs:
|
|
|
219
222
|
path: final_release_notes.txt
|
|
220
223
|
retention-days: 1
|
|
221
224
|
|
|
222
|
-
#
|
|
223
|
-
# .env
|
|
225
|
+
# Upload the project files as an artifact
|
|
226
|
+
# .env is not included in the artifact for security; each job recreates it from secrets
|
|
224
227
|
- name: Upload project files
|
|
225
228
|
uses: actions/upload-artifact@v7
|
|
226
229
|
with:
|
|
@@ -232,7 +235,7 @@ jobs:
|
|
|
232
235
|
retention-days: 1
|
|
233
236
|
|
|
234
237
|
build-android:
|
|
235
|
-
name: Android AAB
|
|
238
|
+
name: Build Android AAB
|
|
236
239
|
runs-on: ubuntu-latest
|
|
237
240
|
needs: prepare-build
|
|
238
241
|
defaults:
|
|
@@ -255,7 +258,7 @@ jobs:
|
|
|
255
258
|
name: project-files
|
|
256
259
|
path: ${{ env.FLUTTER_PROJECT_DIR }}
|
|
257
260
|
|
|
258
|
-
#
|
|
261
|
+
# Prepare env vars (created from secrets rather than the artifact, for security) - a .env file when ENV_MODE=dotenv, a temp file for dart-define
|
|
259
262
|
- name: Prepare env file
|
|
260
263
|
env:
|
|
261
264
|
ENV_CONTENT: ${{ secrets.ENV_FILE || secrets.ENV }}
|
|
@@ -277,35 +280,37 @@ jobs:
|
|
|
277
280
|
RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }}
|
|
278
281
|
RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
|
|
279
282
|
run: |
|
|
280
|
-
|
|
283
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
284
|
+
# An empty keystore built from an empty Secret leaves it unclear which key signed the build, or ends in a misleading error in a later step
|
|
281
285
|
MISSING=""
|
|
282
286
|
for name in RELEASE_KEYSTORE_BASE64 RELEASE_KEYSTORE_PASSWORD RELEASE_KEY_ALIAS RELEASE_KEY_PASSWORD; do
|
|
283
287
|
[ -n "${!name}" ] || MISSING="$MISSING $name"
|
|
284
288
|
done
|
|
285
289
|
if [ -n "$MISSING" ]; then
|
|
286
|
-
echo "::error
|
|
290
|
+
echo "::error::$(m flutter_a.signing_secrets_empty missing="$MISSING")"
|
|
287
291
|
exit 1
|
|
288
292
|
fi
|
|
289
293
|
mkdir -p android/app/keystore
|
|
290
294
|
printf '%s' "$RELEASE_KEYSTORE_BASE64" | base64 -d > android/app/keystore/key.jks
|
|
291
295
|
if [ ! -s android/app/keystore/key.jks ]; then
|
|
292
|
-
echo "::error
|
|
296
|
+
echo "::error::$(m flutter_a.keystore_decoded_empty)"
|
|
293
297
|
exit 1
|
|
294
298
|
fi
|
|
295
|
-
|
|
299
|
+
m flutter_a.release_keystore_created
|
|
296
300
|
ls -la android/app/keystore/
|
|
297
301
|
|
|
298
302
|
- name: Create key.properties
|
|
299
303
|
run: |
|
|
304
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
300
305
|
cat > android/key.properties << EOF
|
|
301
306
|
storeFile=app/keystore/key.jks
|
|
302
307
|
storePassword=${{ secrets.RELEASE_KEYSTORE_PASSWORD }}
|
|
303
308
|
keyAlias=${{ secrets.RELEASE_KEY_ALIAS }}
|
|
304
309
|
keyPassword=${{ secrets.RELEASE_KEY_PASSWORD }}
|
|
305
310
|
EOF
|
|
306
|
-
|
|
311
|
+
m flutter_a.key_properties_created
|
|
307
312
|
|
|
308
|
-
# google-services.json
|
|
313
|
+
# Create google-services.json (optional) - no empty file is written when the Secret is empty
|
|
309
314
|
- name: Create google-services.json
|
|
310
315
|
env:
|
|
311
316
|
GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
|
|
@@ -357,55 +362,57 @@ jobs:
|
|
|
357
362
|
|
|
358
363
|
- name: Configure Android build for release
|
|
359
364
|
run: |
|
|
360
|
-
|
|
365
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
366
|
+
# Add the release signing config to build.gradle.kts if it is missing
|
|
361
367
|
if ! grep -q "signingConfigs" android/app/build.gradle.kts; then
|
|
362
|
-
|
|
363
|
-
#
|
|
368
|
+
m flutter_a.signing_config_must_added_build
|
|
369
|
+
# Assume signing is already configured (it must be set up manually beforehand)
|
|
364
370
|
fi
|
|
365
|
-
|
|
371
|
+
m flutter_a.android_build_config_check_complete
|
|
366
372
|
|
|
367
|
-
# pubspec.yaml
|
|
368
|
-
#
|
|
373
|
+
# Keep pubspec.yaml in the x.y.z format as is
|
|
374
|
+
# The --build-name and --build-number flags of flutter build override pubspec.yaml
|
|
369
375
|
|
|
370
376
|
- name: Build Android App Bundle (AAB)
|
|
371
377
|
run: |
|
|
378
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
372
379
|
VERSION_NAME="${{ needs.prepare-build.outputs.version }}"
|
|
373
380
|
VERSION_CODE="${{ needs.prepare-build.outputs.version_code }}"
|
|
374
381
|
|
|
375
382
|
echo "=========================================="
|
|
376
|
-
|
|
383
|
+
m flutter_a.starting_aab_build
|
|
377
384
|
echo "=========================================="
|
|
378
|
-
|
|
379
|
-
|
|
385
|
+
m flutter_a.build_version version_name="$VERSION_NAME"
|
|
386
|
+
m flutter_a.build_code version_code="$VERSION_CODE"
|
|
380
387
|
|
|
381
|
-
#
|
|
388
|
+
# Validate inputs
|
|
382
389
|
if [ -z "$VERSION_NAME" ] || [ -z "$VERSION_CODE" ]; then
|
|
383
|
-
|
|
390
|
+
m flutter_a.version_name_or_version_code
|
|
384
391
|
exit 1
|
|
385
392
|
fi
|
|
386
393
|
|
|
387
|
-
# Flutter
|
|
388
|
-
|
|
394
|
+
# Print Flutter environment info
|
|
395
|
+
m flutter_a.flutter_environment_info
|
|
389
396
|
flutter --version
|
|
390
397
|
flutter doctor -v | head -20
|
|
391
398
|
|
|
392
|
-
#
|
|
393
|
-
|
|
399
|
+
# Clean the build directory
|
|
400
|
+
m flutter_a.cleaning_previous_build_output
|
|
394
401
|
rm -rf build/app/outputs/bundle/release/
|
|
395
402
|
mkdir -p build/app/outputs/bundle/release/
|
|
396
403
|
|
|
397
|
-
# Flutter clean
|
|
398
|
-
|
|
404
|
+
# Flutter clean and pub get
|
|
405
|
+
m flutter_a.running_flutter_clean_reinstalling_dependencies
|
|
399
406
|
flutter clean
|
|
400
407
|
flutter pub get
|
|
401
408
|
if grep -q "build_runner" pubspec.yaml; then
|
|
402
409
|
dart run build_runner build --delete-conflicting-outputs
|
|
403
410
|
fi
|
|
404
411
|
|
|
405
|
-
# local.properties
|
|
406
|
-
|
|
412
|
+
# Add version info to local.properties (works around the Flutter flags being ignored)
|
|
413
|
+
m flutter_a.setting_version_info_local_properties
|
|
407
414
|
|
|
408
|
-
#
|
|
415
|
+
# Remove existing version info if local.properties exists
|
|
409
416
|
if [ -f "android/local.properties" ]; then
|
|
410
417
|
grep -v "flutter.versionName\|flutter.versionCode" android/local.properties > android/local.properties.tmp || true
|
|
411
418
|
mv android/local.properties.tmp android/local.properties
|
|
@@ -413,24 +420,24 @@ jobs:
|
|
|
413
420
|
touch android/local.properties
|
|
414
421
|
fi
|
|
415
422
|
|
|
416
|
-
#
|
|
423
|
+
# Add version info
|
|
417
424
|
echo "flutter.versionName=$VERSION_NAME" >> android/local.properties
|
|
418
425
|
echo "flutter.versionCode=$VERSION_CODE" >> android/local.properties
|
|
419
426
|
|
|
420
|
-
|
|
421
|
-
|
|
427
|
+
m flutter_a.local_properties_updated
|
|
428
|
+
m flutter_a.version_info_version_name_version version_name="$VERSION_NAME" version_code="$VERSION_CODE"
|
|
422
429
|
|
|
423
|
-
# Gradle
|
|
430
|
+
# Gradle performance tuning
|
|
424
431
|
export GRADLE_OPTS="-Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.workers.max=4"
|
|
425
432
|
export JAVA_OPTS="-Xmx4g"
|
|
426
|
-
|
|
433
|
+
m flutter_a.gradle_tuning_applied
|
|
427
434
|
|
|
428
|
-
#
|
|
429
|
-
# --build-name
|
|
430
|
-
# pubspec.yaml
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
435
|
+
# Pass the version info to the flutter build command
|
|
436
|
+
# The --build-name and --build-number flags override the version in pubspec.yaml
|
|
437
|
+
# pubspec.yaml stays in x.y.z format; VERSION_CODE is managed automatically in version.yml
|
|
438
|
+
m flutter_a.running_flutter_build
|
|
439
|
+
m flutter_a.command_flutter_build_appbundle_release version_name="$VERSION_NAME" version_code="$VERSION_CODE"
|
|
440
|
+
m flutter_a.build_start_time cmd1="$(date '+%Y-%m-%d %H:%M:%S')"
|
|
434
441
|
|
|
435
442
|
flutter build appbundle \
|
|
436
443
|
--release \
|
|
@@ -442,144 +449,144 @@ jobs:
|
|
|
442
449
|
BUILD_EXIT_CODE=$?
|
|
443
450
|
|
|
444
451
|
if [ $BUILD_EXIT_CODE -ne 0 ]; then
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
find build/ -name "*.aab" -o -name "*.apk" 2>/dev/null ||
|
|
452
|
+
m flutter_a.flutter_build_failed_exit_code build_exit_code="$BUILD_EXIT_CODE"
|
|
453
|
+
m flutter_a.build_directory_state
|
|
454
|
+
find build/ -name "*.aab" -o -name "*.apk" 2>/dev/null || m flutter_a.aab_apk_not_found
|
|
448
455
|
exit 1
|
|
449
456
|
fi
|
|
450
457
|
|
|
451
|
-
|
|
458
|
+
m flutter_a.flutter_build_succeeded
|
|
452
459
|
|
|
453
|
-
#
|
|
454
|
-
|
|
460
|
+
# Check the build result
|
|
461
|
+
m flutter_a.checking_build_result
|
|
455
462
|
ls -lah build/app/outputs/bundle/release/
|
|
456
463
|
|
|
457
|
-
# AAB
|
|
464
|
+
# Check that the AAB file exists
|
|
458
465
|
AAB_FILE="build/app/outputs/bundle/release/app-release.aab"
|
|
459
466
|
if [ ! -f "$AAB_FILE" ]; then
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
find build/ -type f -name "*.aab" -o -name "*.apk" 2>/dev/null ||
|
|
463
|
-
|
|
464
|
-
find build/app/outputs/ -type f 2>/dev/null ||
|
|
467
|
+
m flutter_a.aab_file_not_created
|
|
468
|
+
m flutter_a.full_build_directory_contents
|
|
469
|
+
find build/ -type f -name "*.aab" -o -name "*.apk" 2>/dev/null || m flutter_a.aab_apk_not_found
|
|
470
|
+
m flutter_a.outputs_directory_structure
|
|
471
|
+
find build/app/outputs/ -type f 2>/dev/null || m flutter_a.outputs_directory_does_not_exist
|
|
465
472
|
exit 1
|
|
466
473
|
fi
|
|
467
474
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
475
|
+
m flutter_a.aab_file_creation_confirmed
|
|
476
|
+
m flutter_a.aab_file_size cmd1="$(du -h "$AAB_FILE" | cut -f1)"
|
|
477
|
+
m flutter_a.aab_file_info cmd1="$(ls -lah "$AAB_FILE")"
|
|
471
478
|
|
|
472
|
-
#
|
|
473
|
-
|
|
479
|
+
# Download and install bundletool
|
|
480
|
+
m flutter_a.downloading_bundletool
|
|
474
481
|
BUNDLETOOL_VERSION="1.15.6"
|
|
475
482
|
BUNDLETOOL_URL="https://github.com/google/bundletool/releases/download/${BUNDLETOOL_VERSION}/bundletool-all-${BUNDLETOOL_VERSION}.jar"
|
|
476
483
|
|
|
477
|
-
|
|
484
|
+
m flutter_a.download_url bundletool_url="$BUNDLETOOL_URL"
|
|
478
485
|
wget -q "$BUNDLETOOL_URL" -O bundletool.jar
|
|
479
486
|
|
|
480
487
|
if [ ! -f "bundletool.jar" ]; then
|
|
481
|
-
|
|
482
|
-
|
|
488
|
+
m flutter_a.bundletool_download_failed
|
|
489
|
+
m flutter_a.retrying_fallback_url
|
|
483
490
|
wget -q "https://github.com/google/bundletool/releases/latest/download/bundletool-all-1.15.6.jar" -O bundletool.jar
|
|
484
491
|
|
|
485
492
|
if [ ! -f "bundletool.jar" ]; then
|
|
486
|
-
|
|
493
|
+
m flutter_a.bundletool_download_failed_completely
|
|
487
494
|
exit 1
|
|
488
495
|
fi
|
|
489
496
|
fi
|
|
490
497
|
|
|
491
|
-
|
|
492
|
-
|
|
498
|
+
m flutter_a.bundletool_downloaded
|
|
499
|
+
m flutter_a.bundletool_file_size cmd1="$(du -h bundletool.jar | cut -f1)"
|
|
493
500
|
|
|
494
|
-
# Java
|
|
495
|
-
|
|
501
|
+
# Check the Java environment
|
|
502
|
+
m flutter_a.checking_java_environment
|
|
496
503
|
java -version
|
|
497
504
|
|
|
498
|
-
#
|
|
499
|
-
# Flutter CLI
|
|
505
|
+
# Check the actual version info inside the AAB file
|
|
506
|
+
# Verify that the VERSION_CODE passed via the Flutter CLI flags was applied correctly
|
|
500
507
|
echo "=========================================="
|
|
501
|
-
|
|
508
|
+
m flutter_a.verifying_version_info_inside_aab
|
|
502
509
|
echo "=========================================="
|
|
503
510
|
|
|
504
|
-
# AndroidManifest.xml
|
|
505
|
-
|
|
506
|
-
|
|
511
|
+
# Extract the version info from AndroidManifest.xml
|
|
512
|
+
m flutter_a.extracting_actual_version_info_aab
|
|
513
|
+
m flutter_a.command_run_java_jar_bundletool aab_file="$AAB_FILE"
|
|
507
514
|
|
|
508
515
|
MANIFEST_OUTPUT=$(java -jar bundletool.jar dump manifest --bundle="$AAB_FILE" 2>&1)
|
|
509
516
|
MANIFEST_EXIT_CODE=$?
|
|
510
517
|
|
|
511
|
-
|
|
518
|
+
m flutter_a.bundletool_result_exit_code manifest_exit_code="$MANIFEST_EXIT_CODE"
|
|
512
519
|
echo "$MANIFEST_OUTPUT"
|
|
513
520
|
|
|
514
521
|
if [ $MANIFEST_EXIT_CODE -eq 0 ]; then
|
|
515
|
-
|
|
522
|
+
m flutter_a.manifest_extracted
|
|
516
523
|
|
|
517
|
-
#
|
|
524
|
+
# Extract the actual version code and version name
|
|
518
525
|
ACTUAL_VERSION_CODE=$(echo "$MANIFEST_OUTPUT" | grep -o 'android:versionCode="[0-9]*"' | grep -o '[0-9]*' | head -1)
|
|
519
526
|
ACTUAL_VERSION_NAME=$(echo "$MANIFEST_OUTPUT" | grep -o 'android:versionName="[^"]*"' | sed 's/android:versionName="//;s/"//' | head -1)
|
|
520
527
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
528
|
+
m flutter_a.version_info_comparison
|
|
529
|
+
m flutter_a.expected_version_code version_code="$VERSION_CODE"
|
|
530
|
+
m flutter_a.actual_version_code actual_version_code="$ACTUAL_VERSION_CODE"
|
|
531
|
+
m flutter_a.expected_version_name version_name="$VERSION_NAME"
|
|
532
|
+
m flutter_a.actual_version_name actual_version_name="$ACTUAL_VERSION_NAME"
|
|
526
533
|
|
|
527
|
-
# VERSION_CODE
|
|
534
|
+
# Verify VERSION_CODE - a simple incrementing number managed in version.yml
|
|
528
535
|
if [ -z "$ACTUAL_VERSION_CODE" ]; then
|
|
529
|
-
|
|
530
|
-
|
|
536
|
+
m flutter_a.fatal_error_version_code_could
|
|
537
|
+
m flutter_a.full_manifest_contents
|
|
531
538
|
echo "$MANIFEST_OUTPUT"
|
|
532
539
|
exit 1
|
|
533
540
|
elif [ "$ACTUAL_VERSION_CODE" != "$VERSION_CODE" ]; then
|
|
534
|
-
|
|
535
|
-
|
|
541
|
+
m flutter_a.fatal_error_version_code_aab
|
|
542
|
+
m flutter_a.google_play_would_reject_version
|
|
536
543
|
echo ""
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
544
|
+
m flutter_a.debugging_info
|
|
545
|
+
m flutter_a.version_code_version_yml version_code="$VERSION_CODE"
|
|
546
|
+
m flutter_a.version_code_inside_aab_file actual_version_code="$ACTUAL_VERSION_CODE"
|
|
540
547
|
echo ""
|
|
541
|
-
|
|
548
|
+
m flutter_a.flags_passed_flutter_build_command
|
|
542
549
|
echo " --build-name='$VERSION_NAME'"
|
|
543
550
|
echo " --build-number='$VERSION_CODE'"
|
|
544
551
|
echo ""
|
|
545
|
-
|
|
552
|
+
m flutter_a.full_manifest_contents_2
|
|
546
553
|
echo "$MANIFEST_OUTPUT" | grep -E "versionCode|versionName|package"
|
|
547
554
|
exit 1
|
|
548
555
|
else
|
|
549
|
-
|
|
556
|
+
m flutter_a.version_code_check_passed actual_version_code="$ACTUAL_VERSION_CODE"
|
|
550
557
|
fi
|
|
551
558
|
|
|
552
|
-
#
|
|
559
|
+
# Check the version name too (warning only)
|
|
553
560
|
if [ -z "$ACTUAL_VERSION_NAME" ]; then
|
|
554
|
-
|
|
561
|
+
m flutter_a.warning_version_name_could_not
|
|
555
562
|
elif [ "$ACTUAL_VERSION_NAME" != "$VERSION_NAME" ]; then
|
|
556
|
-
|
|
557
|
-
|
|
563
|
+
m flutter_a.warning_version_name_differs_expected
|
|
564
|
+
m flutter_a.expected_actual version_name="$VERSION_NAME" actual_version_name="$ACTUAL_VERSION_NAME"
|
|
558
565
|
else
|
|
559
|
-
|
|
566
|
+
m flutter_a.version_name_check_passed actual_version_name="$ACTUAL_VERSION_NAME"
|
|
560
567
|
fi
|
|
561
568
|
|
|
562
569
|
else
|
|
563
|
-
|
|
564
|
-
|
|
570
|
+
m flutter_a.failed_extract_manifest_bundletool
|
|
571
|
+
m flutter_a.trying_verify_another_way
|
|
565
572
|
|
|
566
|
-
#
|
|
567
|
-
|
|
573
|
+
# Try checking directly with unzip
|
|
574
|
+
m flutter_a.trying_direct_extraction_unzip
|
|
568
575
|
UNZIP_OUTPUT=$(unzip -p "$AAB_FILE" base/manifest/AndroidManifest.xml 2>/dev/null | strings | grep -E "versionCode|versionName")
|
|
569
576
|
|
|
570
577
|
if [ -n "$UNZIP_OUTPUT" ]; then
|
|
571
|
-
|
|
578
|
+
m flutter_a.version_info_extracted_unzip
|
|
572
579
|
echo "$UNZIP_OUTPUT"
|
|
573
580
|
else
|
|
574
|
-
|
|
575
|
-
|
|
581
|
+
m flutter_a.direct_extraction_unzip_failed_too
|
|
582
|
+
m flutter_a.skipping_aab_verification_continuing
|
|
576
583
|
fi
|
|
577
584
|
fi
|
|
578
585
|
|
|
579
586
|
echo "=========================================="
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
587
|
+
m flutter_a.aab_build_verification_complete
|
|
588
|
+
m flutter_a.final_aab aab_file="$AAB_FILE"
|
|
589
|
+
m flutter_a.file_size cmd1="$(du -h "$AAB_FILE" | cut -f1)"
|
|
583
590
|
echo "=========================================="
|
|
584
591
|
|
|
585
592
|
- name: Upload AAB artifact
|
|
@@ -590,7 +597,7 @@ jobs:
|
|
|
590
597
|
retention-days: 1
|
|
591
598
|
|
|
592
599
|
deploy-firebase:
|
|
593
|
-
name: Firebase App Distribution
|
|
600
|
+
name: Deploy to Firebase App Distribution
|
|
594
601
|
runs-on: ubuntu-latest
|
|
595
602
|
needs: [prepare-build, build-android]
|
|
596
603
|
|
|
@@ -617,18 +624,19 @@ jobs:
|
|
|
617
624
|
env:
|
|
618
625
|
SERVICE_ACCOUNT_BASE64: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON_BASE64 }}
|
|
619
626
|
run: |
|
|
627
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
620
628
|
if [ -z "$SERVICE_ACCOUNT_BASE64" ]; then
|
|
621
|
-
echo "::error
|
|
629
|
+
echo "::error::$(m flutter_a.firebase_service_account_json_base64)"
|
|
622
630
|
exit 1
|
|
623
631
|
fi
|
|
624
632
|
printf '%s' "$SERVICE_ACCOUNT_BASE64" | base64 --decode > firebase-service-account.json
|
|
625
|
-
|
|
633
|
+
m flutter_a.firebase_service_account_json_file
|
|
626
634
|
|
|
627
|
-
# Firebase App Distribution release notes
|
|
635
|
+
# Length limit for Firebase App Distribution release notes (safety net)
|
|
628
636
|
- name: Truncate release notes
|
|
629
637
|
run: |
|
|
630
638
|
if [ -f "final_release_notes.txt" ]; then
|
|
631
|
-
# Firebase App Distribution release notes
|
|
639
|
+
# Safety net for the Firebase App Distribution release notes length limit (4000 characters)
|
|
632
640
|
python3 ./.github/scripts/truncate_release_notes.py final_release_notes.txt 4000 char
|
|
633
641
|
fi
|
|
634
642
|
|
|
@@ -642,7 +650,7 @@ jobs:
|
|
|
642
650
|
file: ${{ env.FLUTTER_PROJECT_DIR }}/build/app/outputs/bundle/release/app-release.aab
|
|
643
651
|
releaseNotesFile: final_release_notes.txt
|
|
644
652
|
|
|
645
|
-
# Firebase
|
|
653
|
+
# Delete the Firebase credentials file (security)
|
|
646
654
|
- name: Cleanup Firebase credentials
|
|
647
655
|
if: always()
|
|
648
656
|
run: rm -f firebase-service-account.json
|
|
@@ -650,17 +658,19 @@ jobs:
|
|
|
650
658
|
- name: Notify Firebase Upload Success
|
|
651
659
|
if: success()
|
|
652
660
|
run: |
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
661
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
662
|
+
m flutter_a.firebase_app_distribution_deployment_succeeded
|
|
663
|
+
m flutter_a.version version="${{ needs.prepare-build.outputs.version }}" version_code="${{ needs.prepare-build.outputs.version_code }}"
|
|
664
|
+
m flutter_a.commit sha="${{ github.sha }}"
|
|
656
665
|
echo ""
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
666
|
+
m flutter_a.how_testers_check_build
|
|
667
|
+
m flutter_a.launch_firebase_app_tester_app
|
|
668
|
+
m flutter_a.select_app
|
|
669
|
+
m flutter_a.download_latest_build
|
|
661
670
|
|
|
662
671
|
- name: Notify on Failure
|
|
663
672
|
if: failure()
|
|
664
673
|
run: |
|
|
665
|
-
|
|
666
|
-
|
|
674
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
675
|
+
m flutter_a.firebase_app_distribution_deployment_failed
|
|
676
|
+
m flutter_a.please_check_logs
|