44 push :
55 tags :
66 - ' v[0-9]+.[0-9]+.[0-9]+'
7+ branches :
8+ - staging
79 workflow_dispatch :
810 inputs :
911 version :
@@ -19,11 +21,14 @@ jobs:
1921
2022 build-linux :
2123 runs-on : ubuntu-24.04
24+ permissions :
25+ contents : read
26+ packages : read
2227 container :
23- image : stackwallet /stackwallet-ci:latest
28+ image : ghcr.io/${{ github.repository_owner }} /stackwallet-ci:latest
2429 credentials :
25- username : ${{ secrets.DOCKERHUB_USERNAME }}
26- password : ${{ secrets.DOCKERHUB_TOKEN }}
30+ username : ${{ github.actor }}
31+ password : ${{ github.token }}
2732 steps :
2833 - uses : actions/checkout@v6
2934 with :
3742 VERSION="${{ github.ref_name }}"
3843 VERSION="${VERSION#v}"
3944 BUILD_NUMBER="${{ github.run_number }}"
40- else
45+ elif [ -n "${{ inputs.version }}" ]; then
4146 VERSION="${{ inputs.version }}"
4247 BUILD_NUMBER="${{ inputs.build_number }}"
48+ else
49+ VERSION="0.0.0-staging.${{ github.run_number }}"
50+ BUILD_NUMBER="${{ github.run_number }}"
4351 fi
4452 echo "version=${VERSION}" >> $GITHUB_OUTPUT
4553 echo "build_number=${BUILD_NUMBER}" >> $GITHUB_OUTPUT
@@ -73,11 +81,10 @@ jobs:
7381 CHANGE_NOW : ${{ secrets.CHANGE_NOW }}
7482 run : echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart
7583
76- - name : Generate app config
77- run : dart run build_runner build --delete-conflicting-outputs
78-
7984 - name : Build
80- run : flutter build linux --release
85+ env :
86+ USE_SYSTEM_SECURE_STORAGE_DEPS : " 1"
87+ run : flutter build linux --release --verbose
8188
8289 - name : Package
8390 run : |
@@ -91,11 +98,14 @@ jobs:
9198
9299 build-android :
93100 runs-on : ubuntu-24.04
101+ permissions :
102+ contents : read
103+ packages : read
94104 container :
95- image : stackwallet /stackwallet-ci:latest
105+ image : ghcr.io/${{ github.repository_owner }} /stackwallet-ci:latest
96106 credentials :
97- username : ${{ secrets.DOCKERHUB_USERNAME }}
98- password : ${{ secrets.DOCKERHUB_TOKEN }}
107+ username : ${{ github.actor }}
108+ password : ${{ github.token }}
99109 steps :
100110 - uses : actions/checkout@v6
101111 with :
@@ -109,9 +119,12 @@ jobs:
109119 VERSION="${{ github.ref_name }}"
110120 VERSION="${VERSION#v}"
111121 BUILD_NUMBER="${{ github.run_number }}"
112- else
122+ elif [ -n "${{ inputs.version }}" ]; then
113123 VERSION="${{ inputs.version }}"
114124 BUILD_NUMBER="${{ inputs.build_number }}"
125+ else
126+ VERSION="0.0.0-staging.${{ github.run_number }}"
127+ BUILD_NUMBER="${{ github.run_number }}"
115128 fi
116129 echo "version=${VERSION}" >> $GITHUB_OUTPUT
117130 echo "build_number=${BUILD_NUMBER}" >> $GITHUB_OUTPUT
@@ -145,9 +158,6 @@ jobs:
145158 CHANGE_NOW : ${{ secrets.CHANGE_NOW }}
146159 run : echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart
147160
148- - name : Generate app config
149- run : dart run build_runner build --delete-conflicting-outputs
150-
151161 - name : Set up Android local.properties
152162 run : |
153163 cat > android/local.properties <<EOF
@@ -159,7 +169,17 @@ jobs:
159169 env :
160170 KEYSTORE_BASE64 : ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
161171 run : |
162- echo "$KEYSTORE_BASE64" | base64 --decode > android/keystore.jks
172+ printf '%s' "$KEYSTORE_BASE64" | base64 --decode > android/keystore-orig.jks
173+ [ -s android/keystore-orig.jks ] || { echo "ERROR: ANDROID_KEYSTORE_BASE64 secret is empty or not set"; exit 1; }
174+ keytool -importkeystore \
175+ -srckeystore android/keystore-orig.jks \
176+ -destkeystore android/keystore.jks \
177+ -deststoretype pkcs12 \
178+ -srcstorepass "${{ secrets.ANDROID_STORE_PASSWORD }}" \
179+ -deststorepass "${{ secrets.ANDROID_STORE_PASSWORD }}" \
180+ -noprompt \
181+ -J-Dkeystore.pkcs12.legacy
182+ rm android/keystore-orig.jks
163183 cat > android/key.properties <<EOF
164184 storeFile=../keystore.jks
165185 storePassword=${{ secrets.ANDROID_STORE_PASSWORD }}
@@ -190,7 +210,7 @@ jobs:
190210 path : android-artifacts/
191211
192212 build-windows :
193- runs-on : windows-latest
213+ runs-on : windows-2022
194214 defaults :
195215 run :
196216 shell : bash
@@ -207,9 +227,12 @@ jobs:
207227 VERSION="${{ github.ref_name }}"
208228 VERSION="${VERSION#v}"
209229 BUILD_NUMBER="${{ github.run_number }}"
210- else
230+ elif [ -n "${{ inputs.version }}" ]; then
211231 VERSION="${{ inputs.version }}"
212232 BUILD_NUMBER="${{ inputs.build_number }}"
233+ else
234+ VERSION="0.0.0-staging.${{ github.run_number }}"
235+ BUILD_NUMBER="${{ github.run_number }}"
213236 fi
214237 echo "version=${VERSION}" >> $GITHUB_OUTPUT
215238 echo "build_number=${BUILD_NUMBER}" >> $GITHUB_OUTPUT
@@ -219,6 +242,13 @@ jobs:
219242 flutter-version : ' 3.38.1'
220243 channel : ' stable'
221244
245+ - uses : actions/setup-go@v5
246+ with :
247+ go-version : ' 1.24.13'
248+
249+ - name : Flutter doctor
250+ run : flutter doctor -v
251+
222252 - name : Configure app
223253 run : |
224254 cd scripts
@@ -227,9 +257,45 @@ jobs:
227257 -b "${{ steps.ver.outputs.build_number }}" \
228258 -p windows -a stack_wallet -d -s
229259
260+ # The Actions windows-2022 runner user lacks SeCreateSymbolicLinkPrivilege,
261+ # so link_assets.sh's mklink /D calls either fail or produce broken reparse
262+ # points that Flutter's asset resolver cannot traverse. Replace each of
263+ # the five gitignored asset directories with real copies instead.
264+ - name : Replace asset symlinks with copies (CI workaround)
265+ run : |
266+ set -euo pipefail
267+ for dirname in default_themes icon lottie in_app_logo_icons svg; do
268+ target="assets/${dirname}"
269+ source="asset_sources/${dirname}/stack_wallet"
270+ # Remove whatever link_assets.sh left (reparse point, symlink, or nothing).
271+ # cmd.exe rmdir on a junction/symlink removes the link, not the target.
272+ if [ -e "$target" ] || [ -L "$target" ]; then
273+ cmd.exe /c rmdir "$(cygpath -w "$target")" 2>/dev/null || rm -rf "$target"
274+ fi
275+ mkdir -p "$target"
276+ cp -r "${source}/." "$target/"
277+ done
278+
230279 - name : Get dependencies
231280 run : flutter pub get
232281
282+ # Stack Wallet uses mwebd.exe as a subprocess on Windows, not the FFI
283+ # DLL, so we don't need libmwebd.dll. The upstream plugin's Windows
284+ # build path requires WSL, which the GitHub runner lacks.
285+ - name : Patch flutter_mwebd to skip Windows FFI build (CI workaround)
286+ run : |
287+ set -euo pipefail
288+ cache_root="$(cygpath -u "$LOCALAPPDATA")/Pub/Cache/hosted/pub.dev"
289+ plugin_dir=$(find "$cache_root" -maxdepth 1 -type d -name 'flutter_mwebd-*' -print -quit)
290+ if [ -z "$plugin_dir" ] || [ ! -f "$plugin_dir/pubspec.yaml" ]; then
291+ echo "::error::Could not locate flutter_mwebd in $cache_root"
292+ exit 1
293+ fi
294+ pubspec="$plugin_dir/pubspec.yaml"
295+ echo "Patching $pubspec"
296+ sed -i '/^ windows:$/,/^ ffiPlugin: true$/d' "$pubspec"
297+ flutter pub get
298+
233299 - name : Create git_versions.dart stubs
234300 run : |
235301 mkdir -p crypto_plugins/flutter_libepiccash/lib
@@ -248,22 +314,16 @@ jobs:
248314 CHANGE_NOW : ${{ secrets.CHANGE_NOW }}
249315 run : echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart
250316
251- - name : Generate app config
252- run : dart run build_runner build --delete-conflicting-outputs
317+ - name : Build secp256k1.dll for Windows
318+ run : dart run coinlib:build_windows
253319
254320 - name : Build
255321 run : flutter build windows --release
256322
257- - name : Package
258- shell : pwsh
259- run : |
260- Compress-Archive -Path build\windows\x64\runner\Release\* `
261- -DestinationPath "stack_wallet-windows-x86_64-${{ steps.ver.outputs.version }}.zip"
262-
263323 - uses : actions/upload-artifact@v4
264324 with :
265325 name : stack_wallet-windows-x86_64-${{ steps.ver.outputs.version }}
266- path : stack_wallet- windows-x86_64-${{ steps.ver.outputs.version }}.zip
326+ path : build/ windows/x64/runner/Release/
267327
268328 build-macos :
269329 runs-on : macos-latest
@@ -280,9 +340,12 @@ jobs:
280340 VERSION="${{ github.ref_name }}"
281341 VERSION="${VERSION#v}"
282342 BUILD_NUMBER="${{ github.run_number }}"
283- else
343+ elif [ -n "${{ inputs.version }}" ]; then
284344 VERSION="${{ inputs.version }}"
285345 BUILD_NUMBER="${{ inputs.build_number }}"
346+ else
347+ VERSION="0.0.0-staging.${{ github.run_number }}"
348+ BUILD_NUMBER="${{ github.run_number }}"
286349 fi
287350 echo "version=${VERSION}" >> $GITHUB_OUTPUT
288351 echo "build_number=${BUILD_NUMBER}" >> $GITHUB_OUTPUT
@@ -292,6 +355,10 @@ jobs:
292355 flutter-version : ' 3.38.1'
293356 channel : ' stable'
294357
358+ - uses : actions/setup-go@v5
359+ with :
360+ go-version : ' 1.24.13'
361+
295362 - name : Configure app
296363 run : |
297364 cd scripts
@@ -321,9 +388,6 @@ jobs:
321388 CHANGE_NOW : ${{ secrets.CHANGE_NOW }}
322389 run : echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart
323390
324- - name : Generate app config
325- run : dart run build_runner build --delete-conflicting-outputs
326-
327391 - name : Build
328392 run : flutter build macos --release
329393
@@ -353,23 +417,30 @@ jobs:
353417 VERSION="${{ github.ref_name }}"
354418 VERSION="${VERSION#v}"
355419 BUILD_NUMBER="${{ github.run_number }}"
356- else
420+ elif [ -n "${{ inputs.version }}" ]; then
357421 VERSION="${{ inputs.version }}"
358422 BUILD_NUMBER="${{ inputs.build_number }}"
423+ else
424+ VERSION="0.0.0-staging.${{ github.run_number }}"
425+ BUILD_NUMBER="${{ github.run_number }}"
359426 fi
360427 echo "version=${VERSION}" >> $GITHUB_OUTPUT
361428 echo "build_number=${BUILD_NUMBER}" >> $GITHUB_OUTPUT
362429
363430 - uses : dtolnay/rust-toolchain@master
364431 with :
365- toolchain : ' 1.71.0 '
432+ toolchain : stable
366433 targets : aarch64-apple-ios
367434
368435 - uses : subosito/flutter-action@v2
369436 with :
370437 flutter-version : ' 3.38.1'
371438 channel : ' stable'
372439
440+ - uses : actions/setup-go@v5
441+ with :
442+ go-version : ' 1.24.13'
443+
373444 - name : Configure app
374445 run : |
375446 cd scripts
@@ -399,9 +470,6 @@ jobs:
399470 CHANGE_NOW : ${{ secrets.CHANGE_NOW }}
400471 run : echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart
401472
402- - name : Generate app config
403- run : dart run build_runner build --delete-conflicting-outputs
404-
405473 - name : Build
406474 run : flutter build ios --release --no-codesign
407475
@@ -426,9 +494,19 @@ jobs:
426494 - uses : actions/download-artifact@v4
427495 with :
428496 path : artifacts
429- merge-multiple : true
497+
498+ - name : Package artifacts
499+ run : |
500+ mkdir -p release-files
501+ for dir in artifacts/stack_wallet-windows-*/; do
502+ [ -d "$dir" ] || continue
503+ name=$(basename "$dir")
504+ (cd "$dir" && zip -r "../../release-files/${name}.zip" .)
505+ done
506+ find artifacts/ \( -name "*.tar.gz" -o -name "*.zip" -o -name "*.ipa" \) -mindepth 2 -exec mv {} release-files/ \;
507+ find artifacts/ -name "*.apk" -mindepth 2 -exec mv {} release-files/ \;
430508
431509 - uses : softprops/action-gh-release@v2
432510 with :
433511 generate_release_notes : true
434- files : artifacts /*
512+ files : release-files /*
0 commit comments