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
|
@@ -62,6 +62,7 @@ jobs:
|
|
|
62
62
|
SERVER_USER: ${{ secrets.SERVER_USER }}
|
|
63
63
|
SERVER_PASSWORD: ${{ secrets.SERVER_PASSWORD }}
|
|
64
64
|
run: |
|
|
65
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
65
66
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
66
67
|
MISSING=""
|
|
67
68
|
for NAME in SERVER_HOST SERVER_USER SERVER_PASSWORD; do
|
|
@@ -75,7 +76,9 @@ jobs:
|
|
|
75
76
|
|
|
76
77
|
- name: List repository contents
|
|
77
78
|
run: |
|
|
78
|
-
echo "
|
|
79
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
80
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
81
|
+
m wf_flutter.repo_checked_out
|
|
79
82
|
ls -la
|
|
80
83
|
|
|
81
84
|
# Debug keystore setup - this workflow signs with DEBUG_KEYSTORE (password android, alias androiddebugkey)
|
|
@@ -84,6 +87,7 @@ jobs:
|
|
|
84
87
|
env:
|
|
85
88
|
DEBUG_KEYSTORE: ${{ secrets.DEBUG_KEYSTORE }}
|
|
86
89
|
run: |
|
|
90
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
87
91
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
88
92
|
# This is for internal distribution, so the build proceeds even without the Secret - the runner signs with a freshly created debug key,
|
|
89
93
|
# so the signature differs per build and cannot update an existing install; leave that as a warning.
|
|
@@ -104,29 +108,33 @@ jobs:
|
|
|
104
108
|
env:
|
|
105
109
|
ENV_CONTENT: ${{ secrets.ENV_FILE || secrets.ENV }}
|
|
106
110
|
run: |
|
|
111
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
112
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
107
113
|
if [ "$ENV_MODE" = "dotenv" ]; then
|
|
108
114
|
printf '%s\n' "$ENV_CONTENT" > .env
|
|
109
|
-
|
|
115
|
+
m wf_flutter.dotenv_created
|
|
110
116
|
elif [ -n "$ENV_CONTENT" ]; then
|
|
111
117
|
DART_DEFINE_FILE="$RUNNER_TEMP/dart-define.env"
|
|
112
118
|
printf '%s\n' "$ENV_CONTENT" > "$DART_DEFINE_FILE"
|
|
113
119
|
echo "DART_DEFINE_FILE=$DART_DEFINE_FILE" >> "$GITHUB_ENV"
|
|
114
|
-
|
|
120
|
+
m wf_flutter.dart_define_prepared
|
|
115
121
|
fi
|
|
116
122
|
|
|
117
123
|
- name: Setup Keystore and key.properties
|
|
118
124
|
if: steps.signing.outputs.mode == 'keystore'
|
|
119
125
|
run: |
|
|
126
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
127
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
120
128
|
mkdir -p android/app/keystore
|
|
121
129
|
# Reuse the keystore validated in the previous step
|
|
122
130
|
cp ~/.android/debug.keystore android/app/keystore/key.jks
|
|
123
|
-
|
|
131
|
+
m wf_flutter.keystore_from_debug
|
|
124
132
|
ls -la android/app/keystore
|
|
125
133
|
echo "storeFile=app/keystore/key.jks" > android/key.properties
|
|
126
134
|
echo "storePassword=android" >> android/key.properties
|
|
127
135
|
echo "keyAlias=androiddebugkey" >> android/key.properties
|
|
128
136
|
echo "keyPassword=android" >> android/key.properties
|
|
129
|
-
|
|
137
|
+
m wf_flutter.key_properties_created
|
|
130
138
|
ls -la android/
|
|
131
139
|
|
|
132
140
|
# Create google-services.json (optional) - no empty file is written when the Secret is empty
|
|
@@ -134,12 +142,14 @@ jobs:
|
|
|
134
142
|
env:
|
|
135
143
|
GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
|
|
136
144
|
run: |
|
|
145
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
146
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
137
147
|
if [ -n "$GOOGLE_SERVICES_JSON" ]; then
|
|
138
148
|
mkdir -p android/app
|
|
139
149
|
printf '%s' "$GOOGLE_SERVICES_JSON" > android/app/google-services.json
|
|
140
|
-
|
|
150
|
+
m wf_flutter.google_services_created
|
|
141
151
|
else
|
|
142
|
-
|
|
152
|
+
m wf_flutter.google_services_skipped
|
|
143
153
|
fi
|
|
144
154
|
|
|
145
155
|
- name: Set up Flutter
|
|
@@ -151,7 +161,9 @@ jobs:
|
|
|
151
161
|
|
|
152
162
|
- name: Verify Flutter version
|
|
153
163
|
run: |
|
|
154
|
-
echo "
|
|
164
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
165
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
166
|
+
m wf_flutter.flutter_setup_done
|
|
155
167
|
flutter --version
|
|
156
168
|
|
|
157
169
|
- name: Cache Flutter dependencies
|
|
@@ -173,21 +185,24 @@ jobs:
|
|
|
173
185
|
|
|
174
186
|
- name: Install dependencies
|
|
175
187
|
run: |
|
|
188
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
189
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
176
190
|
flutter pub get
|
|
177
191
|
if grep -q "build_runner" pubspec.yaml; then
|
|
178
192
|
dart run build_runner build --delete-conflicting-outputs
|
|
179
193
|
fi
|
|
180
|
-
|
|
194
|
+
m wf_flutter.deps_installed
|
|
181
195
|
ls -la
|
|
182
196
|
|
|
183
197
|
- name: Setup Gradle
|
|
184
198
|
working-directory: ${{ env.FLUTTER_PROJECT_DIR }}/android
|
|
185
199
|
run: |
|
|
200
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
186
201
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
187
202
|
# The default flutter create .gitignore does not commit gradlew - flutter build creates it when missing
|
|
188
203
|
if [ -f gradlew ]; then
|
|
189
204
|
chmod +x gradlew
|
|
190
|
-
|
|
205
|
+
m wf_flutter.gradle_perm
|
|
191
206
|
else
|
|
192
207
|
m flutter_a.gradlew_missing
|
|
193
208
|
fi
|
|
@@ -200,12 +215,15 @@ jobs:
|
|
|
200
215
|
|
|
201
216
|
- name: Verify Java version
|
|
202
217
|
run: |
|
|
203
|
-
echo "
|
|
218
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
219
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
220
|
+
m wf_flutter.java_setup_done
|
|
204
221
|
java -version
|
|
205
222
|
|
|
206
223
|
- name: Get version info and calculate short commit hash
|
|
207
224
|
id: version_info
|
|
208
225
|
run: |
|
|
226
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
209
227
|
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
210
228
|
CURRENT_VERSION=$(grep 'version:' pubspec.yaml | sed 's/version: //' | tr -d ' ')
|
|
211
229
|
VERSION=$(echo $CURRENT_VERSION | cut -d'+' -f1)
|
|
@@ -223,15 +241,19 @@ jobs:
|
|
|
223
241
|
# APK build (keeps the release build - built directly with flutter)
|
|
224
242
|
- name: Build APK
|
|
225
243
|
run: |
|
|
244
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
245
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
226
246
|
flutter build apk --release ${DART_DEFINE_FILE:+--dart-define-from-file="$DART_DEFINE_FILE"}
|
|
227
247
|
ls -la build/app/outputs/flutter-apk/ || true
|
|
228
|
-
|
|
248
|
+
m wf_flutter.apk_built
|
|
229
249
|
|
|
230
250
|
- name: Rename and Prepare APK
|
|
231
251
|
run: |
|
|
252
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
253
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
232
254
|
mkdir -p ./android/app/build/outputs/apk/release/
|
|
233
255
|
mv ./build/app/outputs/flutter-apk/app-release.apk ./android/app/build/outputs/apk/release/${{ env.APP_ARTIFACT_NAME }}-v${{ env.VERSION }}-${{ env.SHORT_COMMIT_HASH }}.apk
|
|
234
|
-
|
|
256
|
+
m wf_flutter.apk_renamed name="${{ env.APP_ARTIFACT_NAME }}-v${{ env.VERSION }}-${{ env.SHORT_COMMIT_HASH }}.apk"
|
|
235
257
|
ls -la ./android/app/build/outputs/apk/release/
|
|
236
258
|
|
|
237
259
|
- name: Upload APK as Artifact
|
|
@@ -253,14 +275,18 @@ jobs:
|
|
|
253
275
|
|
|
254
276
|
- name: List repository contents for deploy
|
|
255
277
|
run: |
|
|
256
|
-
echo "
|
|
278
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
279
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
280
|
+
m wf_flutter.repo_checked_out_deploy
|
|
257
281
|
ls -la
|
|
258
282
|
|
|
259
283
|
- name: Install dependencies
|
|
260
284
|
run: |
|
|
285
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
286
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
261
287
|
sudo apt-get update
|
|
262
288
|
sudo apt-get install -y smbclient jq
|
|
263
|
-
|
|
289
|
+
m wf_flutter.smb_deps_installed
|
|
264
290
|
|
|
265
291
|
- name: Download build artifacts
|
|
266
292
|
uses: actions/download-artifact@v8
|
|
@@ -270,36 +296,44 @@ jobs:
|
|
|
270
296
|
|
|
271
297
|
- name: List downloaded structure (Debug)
|
|
272
298
|
run: |
|
|
299
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
300
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
273
301
|
ls -alR android/app/build/outputs
|
|
274
|
-
|
|
302
|
+
m wf_flutter.download_listed
|
|
275
303
|
|
|
276
304
|
- name: Find APK file
|
|
277
305
|
run: |
|
|
306
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
307
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
278
308
|
APK_FILE=$(find android/app/build/outputs/ -name "*.apk" | head -n 1)
|
|
279
309
|
echo "APK_FILE=$APK_FILE" >> $GITHUB_ENV
|
|
280
310
|
APK_NAME=$(basename "$APK_FILE")
|
|
281
311
|
echo "APK_NAME=$APK_NAME" >> $GITHUB_ENV
|
|
282
|
-
|
|
312
|
+
m wf_flutter.apk_file_found file="$APK_FILE"
|
|
283
313
|
|
|
284
314
|
- name: Upload files to server via SMB
|
|
285
315
|
env:
|
|
286
316
|
SMB_USERNAME: ${{ secrets.SERVER_USER }}
|
|
287
317
|
SMB_PASSWORD: ${{ secrets.SERVER_PASSWORD }}
|
|
288
318
|
run: |
|
|
319
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
320
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
289
321
|
SMB_SERVER=${{ secrets.SERVER_HOST }}
|
|
290
322
|
SMB_PORT=${{ env.SMB_PORT }}
|
|
291
323
|
SMB_SHARE=${{ env.SMB_SHARE }}
|
|
292
324
|
SMB_PATH="/${{ env.APP_ARTIFACT_NAME }}${{ env.SMB_PATH_ANDROID }}"
|
|
293
|
-
|
|
294
|
-
|
|
325
|
+
m wf_flutter.smb_uploading name="${{ env.APK_NAME }}"
|
|
326
|
+
m wf_flutter.smb_path path="$SMB_PATH"
|
|
295
327
|
smbclient "//$SMB_SERVER/$SMB_SHARE" -p "$SMB_PORT" -U "$SMB_USERNAME%$SMB_PASSWORD" -m SMB3 -d 10 -c "mkdir $SMB_PATH; cd $SMB_PATH; put ${{ env.APK_FILE }} ${{ env.APK_NAME }}"
|
|
296
|
-
|
|
328
|
+
m wf_flutter.smb_uploaded
|
|
297
329
|
|
|
298
330
|
- name: Update CICD history JSON
|
|
299
331
|
env:
|
|
300
332
|
SMB_USERNAME: ${{ secrets.SERVER_USER }}
|
|
301
333
|
SMB_PASSWORD: ${{ secrets.SERVER_PASSWORD }}
|
|
302
334
|
run: |
|
|
335
|
+
[ -f "$GITHUB_WORKSPACE/.github/scripts/messages.py" ] || { echo "::error::messages.py is missing; rerun \`npx project-auto-wizard --mode full --force\`"; exit 1; }
|
|
336
|
+
m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
|
|
303
337
|
export TZ='Asia/Seoul'
|
|
304
338
|
BUILD_DATE=$(date +"%Y-%m-%d %H:%M")
|
|
305
339
|
FILE_SIZE=$(stat -c%s "${{ env.APK_FILE }}")
|
|
@@ -321,12 +355,12 @@ jobs:
|
|
|
321
355
|
SMB_PATH="/${{ env.APP_ARTIFACT_NAME }}${{ env.SMB_PATH_ANDROID }}"
|
|
322
356
|
|
|
323
357
|
smbclient "//$SMB_SERVER/$SMB_SHARE" -p "$SMB_PORT" -U "$SMB_USERNAME%$SMB_PASSWORD" -m SMB3 -d 10 -c "cd $SMB_PATH; get $HISTORY_FILE" || echo '{"files": []}' > $HISTORY_FILE
|
|
324
|
-
|
|
358
|
+
m wf_flutter.history_loaded file="$HISTORY_FILE"
|
|
325
359
|
cat $HISTORY_FILE
|
|
326
360
|
|
|
327
361
|
jq --argjson new_build "$NEW_BUILD_INFO" '.files += [$new_build]' $HISTORY_FILE > updated.json
|
|
328
|
-
|
|
362
|
+
m wf_flutter.history_updated file="$HISTORY_FILE"
|
|
329
363
|
cat updated.json
|
|
330
364
|
|
|
331
365
|
smbclient "//$SMB_SERVER/$SMB_SHARE" -p "$SMB_PORT" -U "$SMB_USERNAME%$SMB_PASSWORD" -m SMB3 -d 10 -c "cd $SMB_PATH; put updated.json $HISTORY_FILE"
|
|
332
|
-
|
|
366
|
+
m wf_flutter.history_uploaded file="$HISTORY_FILE"
|