project-auto-wizard 0.15.0 โ 0.16.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.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +2 -2
- package/README.zh-CN.md +1 -1
- package/package.json +1 -1
- package/payload/config/breaking-changes.json +31 -5
- package/payload/config/wizard-prompts.yml +0 -4
- package/payload/scripts/messages.py +162 -26
- package/payload/scripts/version_manager.py +69 -40
- package/payload/version.yml.template +6 -2
- package/payload/workflows/common/PROJECT-COMMON-AI-PR-SUMMARY.yaml +3 -0
- package/payload/workflows/common/PROJECT-COMMON-AUTO-CHANGELOG-CONTROL.yaml +64 -1
- package/payload/workflows/common/PROJECT-COMMON-README-VERSION-UPDATE.yaml +61 -12
- package/payload/workflows/common/PROJECT-COMMON-RELEASE-PUBLISH.yaml +46 -10
- package/payload/workflows/common/PROJECT-COMMON-VERSION-CONTROL.yaml +40 -11
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-FIREBASE-CICD.yaml +24 -8
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-PLAYSTORE-CICD.yaml +29 -10
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-SELFHOSTED-CICD.yaml +57 -23
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-TEST-APK.yaml +155 -72
- package/payload/workflows/flutter/PROJECT-FLUTTER-APP-BUILD-TRIGGER.yaml +49 -20
- package/payload/workflows/flutter/PROJECT-FLUTTER-CI.yaml +162 -62
- package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT.yaml +184 -87
- package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TESTFLIGHT.yaml +38 -15
- package/payload/workflows/go/PROJECT-GO-CI.yaml +14 -5
- package/payload/workflows/go/PROJECT-GO-PR-PREVIEW.yaml +375 -120
- package/payload/workflows/go/PROJECT-GO-SIMPLE-CICD.yaml +9 -4
- package/payload/workflows/python/PROJECT-PYTHON-CI.yaml +12 -4
- package/payload/workflows/python/PROJECT-PYTHON-PR-PREVIEW.yaml +375 -120
- package/payload/workflows/python/PROJECT-PYTHON-SIMPLE-CICD.yaml +9 -4
- package/payload/workflows/react/PROJECT-REACT-CI.yaml +38 -9
- package/payload/workflows/react/PROJECT-REACT-CICD.yaml +19 -5
- package/payload/workflows/spring/PROJECT-SPRING-CI.yml +71 -35
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-NGINX-CICD.yaml +9 -6
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-TRAEFIK-CICD.yaml +7 -4
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-PR-PREVIEW.yaml +425 -144
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-SIMPLE-CICD.yaml +7 -4
- package/src/cli/args.js +32 -22
- package/src/commands/doctor.js +20 -0
- package/src/commands/dry-run.js +9 -1
- package/src/commands/full.js +9 -4
- package/src/commands/interactive.js +29 -30
- package/src/commands/status.js +19 -5
- package/src/context.js +4 -2
- package/src/core/copy/simple.js +31 -0
- package/src/core/copy/workflows.js +2 -2
- package/src/core/deploy-style.js +1 -1
- package/src/core/detect.js +3 -2
- package/src/core/options.js +88 -0
- package/src/core/release-options.js +6 -23
- package/src/core/types.js +15 -8
- package/src/core/version-yml.js +68 -26
- package/src/i18n/catalog/en/cli.js +3 -1
- package/src/i18n/catalog/en/commands.js +15 -0
- package/src/i18n/catalog/en/core2.js +3 -0
- package/src/i18n/catalog/en/ui.js +1 -0
- package/src/i18n/catalog/ko/cli.js +3 -1
- package/src/i18n/catalog/ko/commands.js +15 -0
- package/src/i18n/catalog/ko/core2.js +3 -0
- package/src/i18n/catalog/ko/ui.js +1 -0
- package/src/index.js +7 -3
- package/src/ui/env-plan.js +1 -1
- package/src/ui/prompts.js +9 -5
- package/src/ui/status-cards.js +2 -2
- package/payload/workflows/next/PROJECT-NEXT-CI.yaml +0 -241
- package/payload/workflows/next/PROJECT-NEXT-CICD.yaml +0 -330
|
@@ -149,12 +149,15 @@ jobs:
|
|
|
149
149
|
sparse-checkout-cone-mode: false
|
|
150
150
|
|
|
151
151
|
- name: Load messages
|
|
152
|
-
run:
|
|
152
|
+
run: |
|
|
153
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
154
|
+
echo "PAW_MSG=$(cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py dump flutter_a.ci_)" >> "$GITHUB_ENV"
|
|
153
155
|
|
|
154
156
|
# Pass the settings on as outputs
|
|
155
157
|
- name: Pass settings
|
|
156
158
|
id: config
|
|
157
159
|
run: |
|
|
160
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
158
161
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
159
162
|
# Check the workflow_dispatch inputs
|
|
160
163
|
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
|
|
@@ -171,19 +174,25 @@ jobs:
|
|
|
171
174
|
echo "enable_android=$ENABLE_ANDROID" >> $GITHUB_OUTPUT
|
|
172
175
|
echo "enable_ios=$ENABLE_IOS" >> $GITHUB_OUTPUT
|
|
173
176
|
m flutter_a.ci_config_header
|
|
174
|
-
|
|
177
|
+
m wf_flutter.ci_analyze_only value="$ANALYZE_ONLY"
|
|
175
178
|
echo " Android: $ENABLE_ANDROID"
|
|
176
179
|
echo " iOS: $ENABLE_IOS"
|
|
177
180
|
m flutter_a.ci_config_trigger event_name="${{ github.event_name }}"
|
|
178
181
|
|
|
179
182
|
- name: Collect build info
|
|
180
183
|
id: info
|
|
184
|
+
env:
|
|
185
|
+
# Branch names are passed through env so shell metacharacters in them are never parsed as commands
|
|
186
|
+
PAW_EVENT_NAME: ${{ github.event_name }}
|
|
187
|
+
PAW_HEAD_REF: ${{ github.head_ref }}
|
|
188
|
+
PAW_REF_NAME: ${{ github.ref_name }}
|
|
181
189
|
run: |
|
|
190
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
182
191
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
183
|
-
if [ "$
|
|
184
|
-
BRANCH_NAME="$
|
|
192
|
+
if [ "$PAW_EVENT_NAME" == "pull_request" ]; then
|
|
193
|
+
BRANCH_NAME="$PAW_HEAD_REF"
|
|
185
194
|
else
|
|
186
|
-
BRANCH_NAME="$
|
|
195
|
+
BRANCH_NAME="$PAW_REF_NAME"
|
|
187
196
|
fi
|
|
188
197
|
COMMIT_HASH=$(echo "${{ github.sha }}" | cut -c1-7)
|
|
189
198
|
|
|
@@ -198,18 +207,25 @@ jobs:
|
|
|
198
207
|
id: comment
|
|
199
208
|
if: github.event_name == 'pull_request'
|
|
200
209
|
uses: actions/github-script@v9
|
|
210
|
+
env:
|
|
211
|
+
PAW_IN_GITHUB_RUN_ID: ${{ github.run_id }}
|
|
212
|
+
PAW_IN_STEPS_CONFIG_OUTPUTS_ANALYZE_ONLY: ${{ steps.config.outputs.analyze_only }}
|
|
213
|
+
PAW_IN_STEPS_CONFIG_OUTPUTS_ENABLE_ANDROID: ${{ steps.config.outputs.enable_android }}
|
|
214
|
+
PAW_IN_STEPS_CONFIG_OUTPUTS_ENABLE_IOS: ${{ steps.config.outputs.enable_ios }}
|
|
215
|
+
PAW_IN_STEPS_INFO_OUTPUTS_BRANCH_NAME: ${{ steps.info.outputs.branch_name }}
|
|
216
|
+
PAW_IN_STEPS_INFO_OUTPUTS_COMMIT_HASH: ${{ steps.info.outputs.commit_hash }}
|
|
201
217
|
with:
|
|
202
218
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
203
219
|
script: |
|
|
204
220
|
const M = JSON.parse(process.env.PAW_MSG);
|
|
205
221
|
const m = (k, p = {}) => M[k].replace(/\{(\w+)\}/g, (s, n) => (n in p ? p[n] : s));
|
|
206
222
|
const prNumber = context.payload.pull_request.number;
|
|
207
|
-
const branchName =
|
|
208
|
-
const commitHash =
|
|
209
|
-
const analyzeOnly =
|
|
210
|
-
const enableAndroid =
|
|
211
|
-
const enableIos =
|
|
212
|
-
const runId =
|
|
223
|
+
const branchName = process.env.PAW_IN_STEPS_INFO_OUTPUTS_BRANCH_NAME;
|
|
224
|
+
const commitHash = process.env.PAW_IN_STEPS_INFO_OUTPUTS_COMMIT_HASH;
|
|
225
|
+
const analyzeOnly = process.env.PAW_IN_STEPS_CONFIG_OUTPUTS_ANALYZE_ONLY === 'true';
|
|
226
|
+
const enableAndroid = process.env.PAW_IN_STEPS_CONFIG_OUTPUTS_ENABLE_ANDROID === 'true';
|
|
227
|
+
const enableIos = process.env.PAW_IN_STEPS_CONFIG_OUTPUTS_ENABLE_IOS === 'true';
|
|
228
|
+
const runId = process.env.PAW_IN_GITHUB_RUN_ID;
|
|
213
229
|
const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId}`;
|
|
214
230
|
const startTime = Date.now();
|
|
215
231
|
|
|
@@ -281,6 +297,7 @@ jobs:
|
|
|
281
297
|
outputs:
|
|
282
298
|
status: ${{ steps.result.outputs.status }}
|
|
283
299
|
test_status: ${{ steps.result.outputs.test_status }}
|
|
300
|
+
test_duration: ${{ steps.result.outputs.test_duration }}
|
|
284
301
|
duration: ${{ steps.result.outputs.duration }}
|
|
285
302
|
|
|
286
303
|
steps:
|
|
@@ -295,21 +312,26 @@ jobs:
|
|
|
295
312
|
uses: actions/checkout@v7
|
|
296
313
|
|
|
297
314
|
- name: Load messages
|
|
298
|
-
|
|
315
|
+
id: load_messages
|
|
316
|
+
run: |
|
|
317
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
318
|
+
echo "PAW_MSG=$(cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py dump flutter_a.ci_)" >> "$GITHUB_ENV"
|
|
299
319
|
|
|
300
320
|
# Prepare env vars - a .env file when ENV_MODE=dotenv, a temp file outside the project (--dart-define-from-file) for dart-define
|
|
301
321
|
- name: Prepare env file
|
|
302
322
|
env:
|
|
303
323
|
ENV_CONTENT: ${{ secrets.ENV_FILE || secrets.ENV }}
|
|
304
324
|
run: |
|
|
325
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
326
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
305
327
|
if [ "$ENV_MODE" = "dotenv" ]; then
|
|
306
328
|
printf '%s\n' "$ENV_CONTENT" > "$ENV_FILE_PATH"
|
|
307
|
-
|
|
329
|
+
m wf_flutter.env_file_created file="$ENV_FILE_PATH"
|
|
308
330
|
elif [ -n "$ENV_CONTENT" ]; then
|
|
309
331
|
DART_DEFINE_FILE="$RUNNER_TEMP/dart-define.env"
|
|
310
332
|
printf '%s\n' "$ENV_CONTENT" > "$DART_DEFINE_FILE"
|
|
311
333
|
echo "DART_DEFINE_FILE=$DART_DEFINE_FILE" >> "$GITHUB_ENV"
|
|
312
|
-
|
|
334
|
+
m wf_flutter.dart_define_prepared
|
|
313
335
|
fi
|
|
314
336
|
|
|
315
337
|
- name: Set up Flutter
|
|
@@ -321,7 +343,9 @@ jobs:
|
|
|
321
343
|
|
|
322
344
|
- name: Verify Flutter version
|
|
323
345
|
run: |
|
|
324
|
-
echo "
|
|
346
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
347
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
348
|
+
m wf_flutter.flutter_setup_done_ok
|
|
325
349
|
flutter --version
|
|
326
350
|
|
|
327
351
|
- name: Cache Flutter dependencies
|
|
@@ -334,15 +358,18 @@ jobs:
|
|
|
334
358
|
- name: Install dependencies
|
|
335
359
|
id: deps
|
|
336
360
|
run: |
|
|
361
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
362
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
337
363
|
flutter pub get
|
|
338
364
|
if grep -q "build_runner" pubspec.yaml; then
|
|
339
365
|
dart run build_runner build --delete-conflicting-outputs
|
|
340
366
|
fi
|
|
341
|
-
|
|
367
|
+
m wf_flutter.deps_installed_ok
|
|
342
368
|
|
|
343
369
|
- name: Run Flutter Analyze
|
|
344
370
|
id: analyze
|
|
345
371
|
run: |
|
|
372
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
346
373
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
347
374
|
m flutter_a.ci_analyze_start
|
|
348
375
|
flutter analyze --no-fatal-infos
|
|
@@ -353,11 +380,14 @@ jobs:
|
|
|
353
380
|
id: test
|
|
354
381
|
if: ${{ !cancelled() && steps.deps.outcome == 'success' }}
|
|
355
382
|
run: |
|
|
383
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
356
384
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
357
385
|
# flutter test itself fails when test/ has no *_test.dart, so skip it
|
|
358
386
|
if [ -d test ] && [ -n "$(find test -name '*_test.dart' -print -quit)" ]; then
|
|
359
387
|
m flutter_a.ci_test_start
|
|
388
|
+
TEST_STARTED=$(date +%s)
|
|
360
389
|
flutter test ${DART_DEFINE_FILE:+--dart-define-from-file="$DART_DEFINE_FILE"}
|
|
390
|
+
echo "seconds=$(( $(date +%s) - TEST_STARTED ))" >> "$GITHUB_OUTPUT"
|
|
361
391
|
echo "ran=true" >> "$GITHUB_OUTPUT"
|
|
362
392
|
m flutter_a.ci_test_passed
|
|
363
393
|
else
|
|
@@ -367,28 +397,41 @@ jobs:
|
|
|
367
397
|
|
|
368
398
|
- name: Record analysis result
|
|
369
399
|
id: result
|
|
370
|
-
if: always()
|
|
400
|
+
if: always() && steps.load_messages.outcome == 'success'
|
|
371
401
|
uses: actions/github-script@v9
|
|
402
|
+
env:
|
|
403
|
+
PAW_IN_STEPS_ANALYZE_OUTCOME: ${{ steps.analyze.outcome }}
|
|
404
|
+
PAW_IN_STEPS_ANALYZE_START_OUTPUTS_TIME: ${{ steps.analyze_start.outputs.time }}
|
|
405
|
+
PAW_IN_STEPS_TEST_OUTCOME: ${{ steps.test.outcome }}
|
|
406
|
+
PAW_IN_STEPS_TEST_OUTPUTS_RAN: ${{ steps.test.outputs.ran }}
|
|
407
|
+
PAW_IN_STEPS_TEST_OUTPUTS_SECONDS: ${{ steps.test.outputs.seconds }}
|
|
372
408
|
with:
|
|
373
409
|
script: |
|
|
374
410
|
const M = JSON.parse(process.env.PAW_MSG);
|
|
375
411
|
const m = (k, p = {}) => M[k].replace(/\{(\w+)\}/g, (s, n) => (n in p ? p[n] : s));
|
|
376
|
-
const analyzeStart = parseInt(
|
|
412
|
+
const analyzeStart = parseInt(process.env.PAW_IN_STEPS_ANALYZE_START_OUTPUTS_TIME);
|
|
377
413
|
const now = Date.now();
|
|
378
414
|
const elapsed = now - analyzeStart;
|
|
379
415
|
const minutes = Math.floor(elapsed / 60000);
|
|
380
416
|
const seconds = Math.floor((elapsed % 60000) / 1000);
|
|
381
417
|
const duration = minutes > 0 ? m('flutter_a.ci_dur_min_sec', { minutes, seconds }) : m('flutter_a.ci_dur_sec', { seconds });
|
|
382
418
|
|
|
383
|
-
const status =
|
|
419
|
+
const status = process.env.PAW_IN_STEPS_ANALYZE_OUTCOME === 'success' ? 'success' : 'failure';
|
|
384
420
|
// none: no test files, skipped: not run because the dependency install failed
|
|
385
|
-
const testOutcome =
|
|
421
|
+
const testOutcome = process.env.PAW_IN_STEPS_TEST_OUTCOME;
|
|
386
422
|
const testStatus = testOutcome === 'success'
|
|
387
|
-
? (
|
|
423
|
+
? (process.env.PAW_IN_STEPS_TEST_OUTPUTS_RAN === 'true' ? 'success' : 'none')
|
|
388
424
|
: (testOutcome === 'failure' ? 'failure' : 'skipped');
|
|
389
425
|
|
|
390
426
|
core.setOutput('status', status);
|
|
427
|
+
// Only a run that finished has a measured time; otherwise leave it empty (shown as -)
|
|
428
|
+
const testSeconds = parseInt(process.env.PAW_IN_STEPS_TEST_OUTPUTS_SECONDS, 10);
|
|
429
|
+
const testDuration = Number.isNaN(testSeconds) ? '' : (testSeconds >= 60
|
|
430
|
+
? m('flutter_a.ci_dur_min_sec', { minutes: Math.floor(testSeconds / 60), seconds: testSeconds % 60 })
|
|
431
|
+
: m('flutter_a.ci_dur_sec', { seconds: testSeconds }));
|
|
432
|
+
|
|
391
433
|
core.setOutput('test_status', testStatus);
|
|
434
|
+
core.setOutput('test_duration', testDuration);
|
|
392
435
|
core.setOutput('duration', duration);
|
|
393
436
|
console.log(m('flutter_a.ci_log_analyze_result', { status, test: testStatus, duration }));
|
|
394
437
|
|
|
@@ -421,21 +464,26 @@ jobs:
|
|
|
421
464
|
uses: actions/checkout@v7
|
|
422
465
|
|
|
423
466
|
- name: Load messages
|
|
424
|
-
|
|
467
|
+
id: load_messages
|
|
468
|
+
run: |
|
|
469
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
470
|
+
echo "PAW_MSG=$(cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py dump flutter_a.ci_)" >> "$GITHUB_ENV"
|
|
425
471
|
|
|
426
472
|
# Prepare env vars - a .env file when ENV_MODE=dotenv, a temp file outside the project (--dart-define-from-file) for dart-define
|
|
427
473
|
- name: Prepare env file
|
|
428
474
|
env:
|
|
429
475
|
ENV_CONTENT: ${{ secrets.ENV_FILE || secrets.ENV }}
|
|
430
476
|
run: |
|
|
477
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
478
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
431
479
|
if [ "$ENV_MODE" = "dotenv" ]; then
|
|
432
480
|
printf '%s\n' "$ENV_CONTENT" > "$ENV_FILE_PATH"
|
|
433
|
-
|
|
481
|
+
m wf_flutter.env_file_created file="$ENV_FILE_PATH"
|
|
434
482
|
elif [ -n "$ENV_CONTENT" ]; then
|
|
435
483
|
DART_DEFINE_FILE="$RUNNER_TEMP/dart-define.env"
|
|
436
484
|
printf '%s\n' "$ENV_CONTENT" > "$DART_DEFINE_FILE"
|
|
437
485
|
echo "DART_DEFINE_FILE=$DART_DEFINE_FILE" >> "$GITHUB_ENV"
|
|
438
|
-
|
|
486
|
+
m wf_flutter.dart_define_prepared
|
|
439
487
|
fi
|
|
440
488
|
|
|
441
489
|
- name: Set up Flutter
|
|
@@ -447,7 +495,9 @@ jobs:
|
|
|
447
495
|
|
|
448
496
|
- name: Verify Flutter version
|
|
449
497
|
run: |
|
|
450
|
-
echo "
|
|
498
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
499
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
500
|
+
m wf_flutter.flutter_setup_done_ok
|
|
451
501
|
flutter --version
|
|
452
502
|
|
|
453
503
|
- name: Cache Flutter dependencies
|
|
@@ -469,11 +519,13 @@ jobs:
|
|
|
469
519
|
|
|
470
520
|
- name: Install dependencies
|
|
471
521
|
run: |
|
|
522
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
523
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
472
524
|
flutter pub get
|
|
473
525
|
if grep -q "build_runner" pubspec.yaml; then
|
|
474
526
|
dart run build_runner build --delete-conflicting-outputs
|
|
475
527
|
fi
|
|
476
|
-
|
|
528
|
+
m wf_flutter.deps_installed_ok
|
|
477
529
|
|
|
478
530
|
- name: Set up Java
|
|
479
531
|
uses: actions/setup-java@v5
|
|
@@ -483,17 +535,20 @@ jobs:
|
|
|
483
535
|
|
|
484
536
|
- name: Verify Java version
|
|
485
537
|
run: |
|
|
486
|
-
echo "
|
|
538
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
539
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
540
|
+
m wf_flutter.java_setup_done_ok
|
|
487
541
|
java -version
|
|
488
542
|
|
|
489
543
|
- name: Setup Gradle
|
|
490
544
|
working-directory: ${{ env.FLUTTER_PROJECT_DIR }}/android
|
|
491
545
|
run: |
|
|
546
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
492
547
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
493
548
|
# The default flutter create .gitignore does not commit gradlew - flutter build creates it when missing
|
|
494
549
|
if [ -f gradlew ]; then
|
|
495
550
|
chmod +x gradlew
|
|
496
|
-
|
|
551
|
+
m wf_flutter.gradle_perm_ok
|
|
497
552
|
else
|
|
498
553
|
m flutter_a.gradlew_missing
|
|
499
554
|
fi
|
|
@@ -502,6 +557,7 @@ jobs:
|
|
|
502
557
|
- name: Build APK
|
|
503
558
|
id: build
|
|
504
559
|
run: |
|
|
560
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
505
561
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
506
562
|
m flutter_a.ci_apk_start
|
|
507
563
|
flutter build apk --debug ${DART_DEFINE_FILE:+--dart-define-from-file="$DART_DEFINE_FILE"}
|
|
@@ -510,20 +566,23 @@ jobs:
|
|
|
510
566
|
|
|
511
567
|
- name: Record build result
|
|
512
568
|
id: result
|
|
513
|
-
if: always()
|
|
569
|
+
if: always() && steps.load_messages.outcome == 'success'
|
|
514
570
|
uses: actions/github-script@v9
|
|
571
|
+
env:
|
|
572
|
+
PAW_IN_STEPS_BUILD_OUTCOME: ${{ steps.build.outcome }}
|
|
573
|
+
PAW_IN_STEPS_BUILD_START_OUTPUTS_TIME: ${{ steps.build_start.outputs.time }}
|
|
515
574
|
with:
|
|
516
575
|
script: |
|
|
517
576
|
const M = JSON.parse(process.env.PAW_MSG);
|
|
518
577
|
const m = (k, p = {}) => M[k].replace(/\{(\w+)\}/g, (s, n) => (n in p ? p[n] : s));
|
|
519
|
-
const buildStart = parseInt(
|
|
578
|
+
const buildStart = parseInt(process.env.PAW_IN_STEPS_BUILD_START_OUTPUTS_TIME);
|
|
520
579
|
const now = Date.now();
|
|
521
580
|
const elapsed = now - buildStart;
|
|
522
581
|
const minutes = Math.floor(elapsed / 60000);
|
|
523
582
|
const seconds = Math.floor((elapsed % 60000) / 1000);
|
|
524
583
|
const duration = minutes > 0 ? m('flutter_a.ci_dur_min_sec', { minutes, seconds }) : m('flutter_a.ci_dur_sec', { seconds });
|
|
525
584
|
|
|
526
|
-
const status =
|
|
585
|
+
const status = process.env.PAW_IN_STEPS_BUILD_OUTCOME === 'success' ? 'success' : 'failure';
|
|
527
586
|
|
|
528
587
|
core.setOutput('status', status);
|
|
529
588
|
core.setOutput('duration', duration);
|
|
@@ -558,7 +617,10 @@ jobs:
|
|
|
558
617
|
uses: actions/checkout@v7
|
|
559
618
|
|
|
560
619
|
- name: Load messages
|
|
561
|
-
|
|
620
|
+
id: load_messages
|
|
621
|
+
run: |
|
|
622
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
623
|
+
echo "PAW_MSG=$(cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py dump flutter_a.ci_)" >> "$GITHUB_ENV"
|
|
562
624
|
|
|
563
625
|
- name: Select Xcode version
|
|
564
626
|
run: sudo xcode-select -s /Applications/Xcode_${{ env.XCODE_VERSION }}.app/Contents/Developer
|
|
@@ -568,16 +630,22 @@ jobs:
|
|
|
568
630
|
# xcode-select alone does not propagate to subprocesses, so set it explicitly
|
|
569
631
|
DEVELOPER_DIR: /Applications/Xcode_${{ env.XCODE_VERSION }}.app/Contents/Developer
|
|
570
632
|
run: |
|
|
571
|
-
echo "
|
|
572
|
-
|
|
573
|
-
|
|
633
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
634
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
635
|
+
m wf_flutter.xcode_platform_check
|
|
636
|
+
if ls "$DEVELOPER_DIR/Platforms/iPhoneOS.platform/" 2>/dev/null; then
|
|
637
|
+
m wf_flutter.xcode_platform_exists
|
|
638
|
+
else
|
|
639
|
+
m wf_flutter.xcode_platform_missing
|
|
640
|
+
fi
|
|
641
|
+
m wf_flutter.xcode_install_pkgs
|
|
574
642
|
sudo installer -pkg /Applications/Xcode_${{ env.XCODE_VERSION }}.app/Contents/Resources/Packages/MobileDevice.pkg -target /
|
|
575
643
|
sudo installer -pkg /Applications/Xcode_${{ env.XCODE_VERSION }}.app/Contents/Resources/Packages/MobileDeviceDevelopment.pkg -target /
|
|
576
|
-
|
|
644
|
+
m wf_flutter.xcode_license
|
|
577
645
|
sudo xcodebuild -license accept
|
|
578
|
-
|
|
646
|
+
m wf_flutter.xcode_init
|
|
579
647
|
xcrun simctl list >/dev/null 2>&1 || true
|
|
580
|
-
|
|
648
|
+
m wf_flutter.xcode_download
|
|
581
649
|
xcodebuild -downloadPlatform iOS
|
|
582
650
|
|
|
583
651
|
# Prepare env vars - a .env file when ENV_MODE=dotenv, a temp file outside the project (--dart-define-from-file) for dart-define
|
|
@@ -585,14 +653,16 @@ jobs:
|
|
|
585
653
|
env:
|
|
586
654
|
ENV_CONTENT: ${{ secrets.ENV_FILE || secrets.ENV }}
|
|
587
655
|
run: |
|
|
656
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
657
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
588
658
|
if [ "$ENV_MODE" = "dotenv" ]; then
|
|
589
659
|
printf '%s\n' "$ENV_CONTENT" > "$ENV_FILE_PATH"
|
|
590
|
-
|
|
660
|
+
m wf_flutter.env_file_created file="$ENV_FILE_PATH"
|
|
591
661
|
elif [ -n "$ENV_CONTENT" ]; then
|
|
592
662
|
DART_DEFINE_FILE="$RUNNER_TEMP/dart-define.env"
|
|
593
663
|
printf '%s\n' "$ENV_CONTENT" > "$DART_DEFINE_FILE"
|
|
594
664
|
echo "DART_DEFINE_FILE=$DART_DEFINE_FILE" >> "$GITHUB_ENV"
|
|
595
|
-
|
|
665
|
+
m wf_flutter.dart_define_prepared
|
|
596
666
|
fi
|
|
597
667
|
|
|
598
668
|
- name: Set up Flutter
|
|
@@ -604,7 +674,9 @@ jobs:
|
|
|
604
674
|
|
|
605
675
|
- name: Verify Flutter version
|
|
606
676
|
run: |
|
|
607
|
-
echo "
|
|
677
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
678
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
679
|
+
m wf_flutter.flutter_setup_done_ok
|
|
608
680
|
flutter --version
|
|
609
681
|
|
|
610
682
|
- name: Cache Flutter dependencies
|
|
@@ -616,11 +688,13 @@ jobs:
|
|
|
616
688
|
|
|
617
689
|
- name: Install dependencies
|
|
618
690
|
run: |
|
|
691
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
692
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
619
693
|
flutter pub get
|
|
620
694
|
if grep -q "build_runner" pubspec.yaml; then
|
|
621
695
|
dart run build_runner build --delete-conflicting-outputs
|
|
622
696
|
fi
|
|
623
|
-
|
|
697
|
+
m wf_flutter.deps_installed_ok
|
|
624
698
|
|
|
625
699
|
- name: Set up Ruby
|
|
626
700
|
uses: ruby/setup-ruby@v1
|
|
@@ -630,6 +704,7 @@ jobs:
|
|
|
630
704
|
|
|
631
705
|
- name: Install CocoaPods
|
|
632
706
|
run: |
|
|
707
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
633
708
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
634
709
|
# A default project without plugins has no Podfile - once plugins are added, flutter build creates it
|
|
635
710
|
if [ -f ios/Podfile ]; then
|
|
@@ -643,6 +718,7 @@ jobs:
|
|
|
643
718
|
- name: Build iOS
|
|
644
719
|
id: build
|
|
645
720
|
run: |
|
|
721
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
646
722
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
647
723
|
m flutter_a.ci_ios_start
|
|
648
724
|
flutter build ios --release --no-codesign ${DART_DEFINE_FILE:+--dart-define-from-file="$DART_DEFINE_FILE"}
|
|
@@ -650,20 +726,23 @@ jobs:
|
|
|
650
726
|
|
|
651
727
|
- name: Record build result
|
|
652
728
|
id: result
|
|
653
|
-
if: always()
|
|
729
|
+
if: always() && steps.load_messages.outcome == 'success'
|
|
654
730
|
uses: actions/github-script@v9
|
|
731
|
+
env:
|
|
732
|
+
PAW_IN_STEPS_BUILD_OUTCOME: ${{ steps.build.outcome }}
|
|
733
|
+
PAW_IN_STEPS_BUILD_START_OUTPUTS_TIME: ${{ steps.build_start.outputs.time }}
|
|
655
734
|
with:
|
|
656
735
|
script: |
|
|
657
736
|
const M = JSON.parse(process.env.PAW_MSG);
|
|
658
737
|
const m = (k, p = {}) => M[k].replace(/\{(\w+)\}/g, (s, n) => (n in p ? p[n] : s));
|
|
659
|
-
const buildStart = parseInt(
|
|
738
|
+
const buildStart = parseInt(process.env.PAW_IN_STEPS_BUILD_START_OUTPUTS_TIME);
|
|
660
739
|
const now = Date.now();
|
|
661
740
|
const elapsed = now - buildStart;
|
|
662
741
|
const minutes = Math.floor(elapsed / 60000);
|
|
663
742
|
const seconds = Math.floor((elapsed % 60000) / 1000);
|
|
664
743
|
const duration = minutes > 0 ? m('flutter_a.ci_dur_min_sec', { minutes, seconds }) : m('flutter_a.ci_dur_sec', { seconds });
|
|
665
744
|
|
|
666
|
-
const status =
|
|
745
|
+
const status = process.env.PAW_IN_STEPS_BUILD_OUTCOME === 'success' ? 'success' : 'failure';
|
|
667
746
|
|
|
668
747
|
core.setOutput('status', status);
|
|
669
748
|
core.setOutput('duration', duration);
|
|
@@ -686,33 +765,53 @@ jobs:
|
|
|
686
765
|
sparse-checkout-cone-mode: false
|
|
687
766
|
|
|
688
767
|
- name: Load messages
|
|
689
|
-
run:
|
|
768
|
+
run: |
|
|
769
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
770
|
+
echo "PAW_MSG=$(cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py dump flutter_a.ci_)" >> "$GITHUB_ENV"
|
|
690
771
|
|
|
691
772
|
- name: Update final result comment
|
|
692
773
|
uses: actions/github-script@v9
|
|
774
|
+
env:
|
|
775
|
+
PAW_IN_GITHUB_RUN_ID: ${{ github.run_id }}
|
|
776
|
+
PAW_IN_NEEDS_ANALYZE_OUTPUTS_DURATION: ${{ needs.analyze.outputs.duration }}
|
|
777
|
+
PAW_IN_NEEDS_ANALYZE_OUTPUTS_STATUS: ${{ needs.analyze.outputs.status }}
|
|
778
|
+
PAW_IN_NEEDS_ANALYZE_OUTPUTS_TEST_STATUS: ${{ needs.analyze.outputs.test_status }}
|
|
779
|
+
PAW_IN_NEEDS_ANALYZE_OUTPUTS_TEST_DURATION: ${{ needs.analyze.outputs.test_duration }}
|
|
780
|
+
PAW_IN_NEEDS_BUILD_ANDROID_OUTPUTS_DURATION: ${{ needs.build-android.outputs.duration }}
|
|
781
|
+
PAW_IN_NEEDS_BUILD_ANDROID_OUTPUTS_STATUS: ${{ needs.build-android.outputs.status }}
|
|
782
|
+
PAW_IN_NEEDS_BUILD_IOS_OUTPUTS_DURATION: ${{ needs.build-ios.outputs.duration }}
|
|
783
|
+
PAW_IN_NEEDS_BUILD_IOS_OUTPUTS_STATUS: ${{ needs.build-ios.outputs.status }}
|
|
784
|
+
PAW_IN_NEEDS_PREPARE_OUTPUTS_ANALYZE_ONLY: ${{ needs.prepare.outputs.analyze_only }}
|
|
785
|
+
PAW_IN_NEEDS_PREPARE_OUTPUTS_BRANCH_NAME: ${{ needs.prepare.outputs.branch_name }}
|
|
786
|
+
PAW_IN_NEEDS_PREPARE_OUTPUTS_COMMENT_ID: ${{ needs.prepare.outputs.comment_id }}
|
|
787
|
+
PAW_IN_NEEDS_PREPARE_OUTPUTS_COMMIT_HASH: ${{ needs.prepare.outputs.commit_hash }}
|
|
788
|
+
PAW_IN_NEEDS_PREPARE_OUTPUTS_ENABLE_ANDROID: ${{ needs.prepare.outputs.enable_android }}
|
|
789
|
+
PAW_IN_NEEDS_PREPARE_OUTPUTS_ENABLE_IOS: ${{ needs.prepare.outputs.enable_ios }}
|
|
790
|
+
PAW_IN_NEEDS_PREPARE_OUTPUTS_START_TIME: ${{ needs.prepare.outputs.start_time }}
|
|
693
791
|
with:
|
|
694
792
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
695
793
|
script: |
|
|
696
794
|
const M = JSON.parse(process.env.PAW_MSG);
|
|
697
795
|
const m = (k, p = {}) => M[k].replace(/\{(\w+)\}/g, (s, n) => (n in p ? p[n] : s));
|
|
698
|
-
const commentId = parseInt(
|
|
699
|
-
const startTime = parseInt(
|
|
700
|
-
const branchName =
|
|
701
|
-
const commitHash =
|
|
702
|
-
const analyzeOnly =
|
|
703
|
-
const enableAndroid =
|
|
704
|
-
const enableIos =
|
|
705
|
-
const runId =
|
|
796
|
+
const commentId = parseInt(process.env.PAW_IN_NEEDS_PREPARE_OUTPUTS_COMMENT_ID);
|
|
797
|
+
const startTime = parseInt(process.env.PAW_IN_NEEDS_PREPARE_OUTPUTS_START_TIME);
|
|
798
|
+
const branchName = process.env.PAW_IN_NEEDS_PREPARE_OUTPUTS_BRANCH_NAME;
|
|
799
|
+
const commitHash = process.env.PAW_IN_NEEDS_PREPARE_OUTPUTS_COMMIT_HASH;
|
|
800
|
+
const analyzeOnly = process.env.PAW_IN_NEEDS_PREPARE_OUTPUTS_ANALYZE_ONLY === 'true';
|
|
801
|
+
const enableAndroid = process.env.PAW_IN_NEEDS_PREPARE_OUTPUTS_ENABLE_ANDROID === 'true';
|
|
802
|
+
const enableIos = process.env.PAW_IN_NEEDS_PREPARE_OUTPUTS_ENABLE_IOS === 'true';
|
|
803
|
+
const runId = process.env.PAW_IN_GITHUB_RUN_ID;
|
|
706
804
|
const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId}`;
|
|
707
805
|
|
|
708
806
|
// Collect the results
|
|
709
|
-
const analyzeStatus =
|
|
710
|
-
const analyzeDuration =
|
|
711
|
-
const testStatus =
|
|
712
|
-
const
|
|
713
|
-
const
|
|
714
|
-
const
|
|
715
|
-
const
|
|
807
|
+
const analyzeStatus = process.env.PAW_IN_NEEDS_ANALYZE_OUTPUTS_STATUS;
|
|
808
|
+
const analyzeDuration = process.env.PAW_IN_NEEDS_ANALYZE_OUTPUTS_DURATION || '-';
|
|
809
|
+
const testStatus = process.env.PAW_IN_NEEDS_ANALYZE_OUTPUTS_TEST_STATUS;
|
|
810
|
+
const testDuration = process.env.PAW_IN_NEEDS_ANALYZE_OUTPUTS_TEST_DURATION || '-';
|
|
811
|
+
const androidStatus = process.env.PAW_IN_NEEDS_BUILD_ANDROID_OUTPUTS_STATUS;
|
|
812
|
+
const androidDuration = process.env.PAW_IN_NEEDS_BUILD_ANDROID_OUTPUTS_DURATION || '-';
|
|
813
|
+
const iosStatus = process.env.PAW_IN_NEEDS_BUILD_IOS_OUTPUTS_STATUS;
|
|
814
|
+
const iosDuration = process.env.PAW_IN_NEEDS_BUILD_IOS_OUTPUTS_DURATION || '-';
|
|
716
815
|
|
|
717
816
|
// Compute the total duration
|
|
718
817
|
const now = Date.now();
|
|
@@ -787,7 +886,7 @@ jobs:
|
|
|
787
886
|
m('flutter_a.ci_table_head'),
|
|
788
887
|
'|----------|------|----------|',
|
|
789
888
|
`| ๐ Analyze | ${analyzeDisplay} | ${analyzeDuration} |`,
|
|
790
|
-
`| ๐งช Test | ${testDisplay} |
|
|
889
|
+
`| ๐งช Test | ${testDisplay} | ${testDuration} |`,
|
|
791
890
|
m('flutter_a.ci_row_android_result', { status: androidDisplay, duration: analyzeOnly || !enableAndroid ? '-' : androidDuration }),
|
|
792
891
|
m('flutter_a.ci_row_ios_result', { status: iosDisplay, duration: analyzeOnly || !enableIos ? '-' : iosDuration }),
|
|
793
892
|
'',
|
|
@@ -877,6 +976,7 @@ jobs:
|
|
|
877
976
|
env:
|
|
878
977
|
RESULTS: ${{ toJSON(needs.*.result) }}
|
|
879
978
|
run: |
|
|
979
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
880
980
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
881
981
|
m flutter_a.ci_gate_results results="$RESULTS"
|
|
882
982
|
if echo "$RESULTS" | grep -Eq '"(failure|cancelled)"'; then
|