Build #23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build | |
| on: | |
| push: | |
| tags: | |
| - 'v[0-9]+.[0-9]+.[0-9]+' | |
| branches: | |
| - staging | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'App version string (e.g. 1.2.3)' | |
| required: true | |
| default: '0.0.1' | |
| build_number: | |
| description: 'Build number (integer)' | |
| required: true | |
| default: '1' | |
| jobs: | |
| build-linux: | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| contents: read | |
| packages: read | |
| container: | |
| image: ghcr.io/${{ github.repository_owner }}/stackwallet-ci:latest | |
| credentials: | |
| username: ${{ github.actor }} | |
| password: ${{ github.token }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| submodules: recursive | |
| - name: Set version | |
| id: ver | |
| run: | | |
| if [ "${{ github.ref_type }}" = "tag" ]; then | |
| VERSION="${{ github.ref_name }}" | |
| VERSION="${VERSION#v}" | |
| BUILD_NUMBER="${{ github.run_number }}" | |
| elif [ -n "${{ inputs.version }}" ]; then | |
| VERSION="${{ inputs.version }}" | |
| BUILD_NUMBER="${{ inputs.build_number }}" | |
| else | |
| VERSION="0.0.0-staging.${{ github.run_number }}" | |
| BUILD_NUMBER="${{ github.run_number }}" | |
| fi | |
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
| echo "build_number=${BUILD_NUMBER}" >> $GITHUB_OUTPUT | |
| - name: Configure app | |
| run: | | |
| cd scripts | |
| echo "yes" | ./build_app.sh \ | |
| -v "${{ steps.ver.outputs.version }}" \ | |
| -b "${{ steps.ver.outputs.build_number }}" \ | |
| -p linux -a stack_wallet -d -s | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Create git_versions.dart stubs | |
| run: | | |
| mkdir -p crypto_plugins/flutter_libepiccash/lib | |
| mkdir -p crypto_plugins/flutter_libmwc/lib | |
| EPIC_TAG=$(git -C crypto_plugins/flutter_libepiccash describe --tags --exact-match HEAD 2>/dev/null || echo "dev") | |
| MWC_TAG=$(git -C crypto_plugins/flutter_libmwc describe --tags --exact-match HEAD 2>/dev/null || echo "dev") | |
| printf 'String getPluginVersion() => "%s";\n' "$EPIC_TAG" \ | |
| > crypto_plugins/flutter_libepiccash/lib/git_versions.dart | |
| printf 'String getPluginVersion() => "%s";\n' "$MWC_TAG" \ | |
| > crypto_plugins/flutter_libmwc/lib/git_versions.dart | |
| - name: Decode secrets | |
| env: | |
| CHANGE_NOW: ${{ secrets.CHANGE_NOW }} | |
| run: echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart | |
| - name: Build | |
| env: | |
| USE_SYSTEM_SECURE_STORAGE_DEPS: "1" | |
| run: flutter build linux --release --verbose | |
| - name: Package | |
| run: | | |
| tar -czf "stack_wallet-linux-x86_64-${{ steps.ver.outputs.version }}.tar.gz" \ | |
| -C build/linux/x64/release bundle | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: stack_wallet-linux-x86_64-${{ steps.ver.outputs.version }} | |
| path: stack_wallet-linux-x86_64-${{ steps.ver.outputs.version }}.tar.gz | |
| build-android: | |
| runs-on: ubuntu-24.04 | |
| permissions: | |
| contents: read | |
| packages: read | |
| container: | |
| image: ghcr.io/${{ github.repository_owner }}/stackwallet-ci:latest | |
| credentials: | |
| username: ${{ github.actor }} | |
| password: ${{ github.token }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| submodules: recursive | |
| - name: Set version | |
| id: ver | |
| run: | | |
| if [ "${{ github.ref_type }}" = "tag" ]; then | |
| VERSION="${{ github.ref_name }}" | |
| VERSION="${VERSION#v}" | |
| BUILD_NUMBER="${{ github.run_number }}" | |
| elif [ -n "${{ inputs.version }}" ]; then | |
| VERSION="${{ inputs.version }}" | |
| BUILD_NUMBER="${{ inputs.build_number }}" | |
| else | |
| VERSION="0.0.0-staging.${{ github.run_number }}" | |
| BUILD_NUMBER="${{ github.run_number }}" | |
| fi | |
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
| echo "build_number=${BUILD_NUMBER}" >> $GITHUB_OUTPUT | |
| - name: Configure app | |
| run: | | |
| cd scripts | |
| echo "yes" | ./build_app.sh \ | |
| -v "${{ steps.ver.outputs.version }}" \ | |
| -b "${{ steps.ver.outputs.build_number }}" \ | |
| -p android -a stack_wallet -d -s | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Create git_versions.dart stubs | |
| run: | | |
| mkdir -p crypto_plugins/flutter_libepiccash/lib | |
| mkdir -p crypto_plugins/flutter_libmwc/lib | |
| EPIC_TAG=$(git -C crypto_plugins/flutter_libepiccash describe --tags --exact-match HEAD 2>/dev/null || echo "dev") | |
| MWC_TAG=$(git -C crypto_plugins/flutter_libmwc describe --tags --exact-match HEAD 2>/dev/null || echo "dev") | |
| printf 'String getPluginVersion() => "%s";\n' "$EPIC_TAG" \ | |
| > crypto_plugins/flutter_libepiccash/lib/git_versions.dart | |
| printf 'String getPluginVersion() => "%s";\n' "$MWC_TAG" \ | |
| > crypto_plugins/flutter_libmwc/lib/git_versions.dart | |
| - name: Decode secrets | |
| env: | |
| CHANGE_NOW: ${{ secrets.CHANGE_NOW }} | |
| run: echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart | |
| - name: Set up Android local.properties | |
| run: | | |
| cat > android/local.properties <<EOF | |
| sdk.dir=${ANDROID_SDK_ROOT} | |
| flutter.sdk=${FLUTTER_HOME} | |
| EOF | |
| - name: Set up signing | |
| env: | |
| KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} | |
| run: | | |
| echo "$KEYSTORE_BASE64" | base64 --decode > android/keystore.jks | |
| cat > android/key.properties <<EOF | |
| storeFile=../keystore.jks | |
| storePassword=${{ secrets.ANDROID_STORE_PASSWORD }} | |
| keyPassword=${{ secrets.ANDROID_KEY_PASSWORD }} | |
| keyAlias=${{ secrets.ANDROID_KEY_ALIAS }} | |
| EOF | |
| - name: Build APKs | |
| run: flutter build apk --split-per-abi --release | |
| - name: Build AAB | |
| run: flutter build appbundle --release | |
| - name: Collect artifacts | |
| run: | | |
| VERSION="${{ steps.ver.outputs.version }}" | |
| mkdir -p android-artifacts | |
| cp build/app/outputs/flutter-apk/app-arm64-v8a-release.apk \ | |
| android-artifacts/stack_wallet-android-arm64-v8a-${VERSION}.apk | |
| cp build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk \ | |
| android-artifacts/stack_wallet-android-armeabi-v7a-${VERSION}.apk | |
| cp build/app/outputs/flutter-apk/app-x86_64-release.apk \ | |
| android-artifacts/stack_wallet-android-x86_64-${VERSION}.apk | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: stack_wallet-android-${{ steps.ver.outputs.version }} | |
| path: android-artifacts/ | |
| build-windows: | |
| runs-on: windows-2022 | |
| defaults: | |
| run: | |
| shell: bash | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| submodules: recursive | |
| - name: Set version | |
| id: ver | |
| run: | | |
| if [ "${{ github.ref_type }}" = "tag" ]; then | |
| VERSION="${{ github.ref_name }}" | |
| VERSION="${VERSION#v}" | |
| BUILD_NUMBER="${{ github.run_number }}" | |
| elif [ -n "${{ inputs.version }}" ]; then | |
| VERSION="${{ inputs.version }}" | |
| BUILD_NUMBER="${{ inputs.build_number }}" | |
| else | |
| VERSION="0.0.0-staging.${{ github.run_number }}" | |
| BUILD_NUMBER="${{ github.run_number }}" | |
| fi | |
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
| echo "build_number=${BUILD_NUMBER}" >> $GITHUB_OUTPUT | |
| - uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.38.1' | |
| channel: 'stable' | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.24.13' | |
| - name: Flutter doctor | |
| run: flutter doctor -v | |
| - name: Configure app | |
| run: | | |
| cd scripts | |
| echo "yes" | ./build_app.sh \ | |
| -v "${{ steps.ver.outputs.version }}" \ | |
| -b "${{ steps.ver.outputs.build_number }}" \ | |
| -p windows -a stack_wallet -d -s | |
| # The Actions windows-2022 runner user lacks SeCreateSymbolicLinkPrivilege, | |
| # so link_assets.sh's mklink /D calls either fail or produce broken reparse | |
| # points that Flutter's asset resolver cannot traverse. Replace each of | |
| # the five gitignored asset directories with real copies instead. | |
| - name: Replace asset symlinks with copies (CI workaround) | |
| run: | | |
| set -euo pipefail | |
| for dirname in default_themes icon lottie in_app_logo_icons svg; do | |
| target="assets/${dirname}" | |
| source="asset_sources/${dirname}/stack_wallet" | |
| # Remove whatever link_assets.sh left (reparse point, symlink, or nothing). | |
| # cmd.exe rmdir on a junction/symlink removes the link, not the target. | |
| if [ -e "$target" ] || [ -L "$target" ]; then | |
| cmd.exe /c rmdir "$(cygpath -w "$target")" 2>/dev/null || rm -rf "$target" | |
| fi | |
| mkdir -p "$target" | |
| cp -r "${source}/." "$target/" | |
| done | |
| - name: Get dependencies | |
| run: flutter pub get | |
| # Stack Wallet uses mwebd.exe as a subprocess on Windows, not the FFI | |
| # DLL, so we don't need libmwebd.dll. The upstream plugin's Windows | |
| # build path requires WSL, which the GitHub runner lacks. | |
| - name: Patch flutter_mwebd to skip Windows FFI build (CI workaround) | |
| run: | | |
| set -euo pipefail | |
| cache_root="$(cygpath -u "$LOCALAPPDATA")/Pub/Cache/hosted/pub.dev" | |
| plugin_dir=$(find "$cache_root" -maxdepth 1 -type d -name 'flutter_mwebd-*' -print -quit) | |
| if [ -z "$plugin_dir" ] || [ ! -f "$plugin_dir/pubspec.yaml" ]; then | |
| echo "::error::Could not locate flutter_mwebd in $cache_root" | |
| exit 1 | |
| fi | |
| pubspec="$plugin_dir/pubspec.yaml" | |
| echo "Patching $pubspec" | |
| sed -i '/^ windows:$/,/^ ffiPlugin: true$/d' "$pubspec" | |
| flutter pub get | |
| - name: Create git_versions.dart stubs | |
| run: | | |
| mkdir -p crypto_plugins/flutter_libepiccash/lib | |
| mkdir -p crypto_plugins/flutter_libmwc/lib | |
| EPIC_TAG=$(git -C crypto_plugins/flutter_libepiccash describe --tags --exact-match HEAD 2>/dev/null || echo "dev") | |
| MWC_TAG=$(git -C crypto_plugins/flutter_libmwc describe --tags --exact-match HEAD 2>/dev/null || echo "dev") | |
| printf 'String getPluginVersion() => "%s";\n' "$EPIC_TAG" \ | |
| > crypto_plugins/flutter_libepiccash/lib/git_versions.dart | |
| printf 'String getPluginVersion() => "%s";\n' "$MWC_TAG" \ | |
| > crypto_plugins/flutter_libmwc/lib/git_versions.dart | |
| - name: Decode secrets | |
| env: | |
| CHANGE_NOW: ${{ secrets.CHANGE_NOW }} | |
| run: echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart | |
| - name: Build secp256k1.dll for Windows | |
| run: dart run coinlib:build_windows | |
| - name: Build | |
| run: flutter build windows --release | |
| - name: Package | |
| shell: pwsh | |
| run: | | |
| Compress-Archive -Path build\windows\x64\runner\Release\* ` | |
| -DestinationPath "stack_wallet-windows-x86_64-${{ steps.ver.outputs.version }}.zip" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: stack_wallet-windows-x86_64-${{ steps.ver.outputs.version }} | |
| path: stack_wallet-windows-x86_64-${{ steps.ver.outputs.version }}.zip | |
| build-macos: | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| submodules: recursive | |
| - name: Set version | |
| id: ver | |
| run: | | |
| if [ "${{ github.ref_type }}" = "tag" ]; then | |
| VERSION="${{ github.ref_name }}" | |
| VERSION="${VERSION#v}" | |
| BUILD_NUMBER="${{ github.run_number }}" | |
| elif [ -n "${{ inputs.version }}" ]; then | |
| VERSION="${{ inputs.version }}" | |
| BUILD_NUMBER="${{ inputs.build_number }}" | |
| else | |
| VERSION="0.0.0-staging.${{ github.run_number }}" | |
| BUILD_NUMBER="${{ github.run_number }}" | |
| fi | |
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
| echo "build_number=${BUILD_NUMBER}" >> $GITHUB_OUTPUT | |
| - uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.38.1' | |
| channel: 'stable' | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.24.13' | |
| - name: Configure app | |
| run: | | |
| cd scripts | |
| echo "yes" | ./build_app.sh \ | |
| -v "${{ steps.ver.outputs.version }}" \ | |
| -b "${{ steps.ver.outputs.build_number }}" \ | |
| -p macos -a stack_wallet -d -s | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Create git_versions.dart stubs | |
| run: | | |
| mkdir -p crypto_plugins/flutter_libepiccash/lib | |
| mkdir -p crypto_plugins/flutter_libmwc/lib | |
| EPIC_TAG=$(git -C crypto_plugins/flutter_libepiccash describe --tags --exact-match HEAD 2>/dev/null || echo "dev") | |
| MWC_TAG=$(git -C crypto_plugins/flutter_libmwc describe --tags --exact-match HEAD 2>/dev/null || echo "dev") | |
| printf 'String getPluginVersion() => "%s";\n' "$EPIC_TAG" \ | |
| > crypto_plugins/flutter_libepiccash/lib/git_versions.dart | |
| printf 'String getPluginVersion() => "%s";\n' "$MWC_TAG" \ | |
| > crypto_plugins/flutter_libmwc/lib/git_versions.dart | |
| - name: Decode secrets | |
| env: | |
| CHANGE_NOW: ${{ secrets.CHANGE_NOW }} | |
| run: echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart | |
| - name: Build | |
| run: flutter build macos --release | |
| - name: Package | |
| run: | | |
| cd "build/macos/Build/Products/Release" | |
| zip -r "$GITHUB_WORKSPACE/stack_wallet-macos-aarch64-${{ steps.ver.outputs.version }}.zip" \ | |
| "Stack Wallet.app" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: stack_wallet-macos-aarch64-${{ steps.ver.outputs.version }} | |
| path: stack_wallet-macos-aarch64-${{ steps.ver.outputs.version }}.zip | |
| build-ios: | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| submodules: recursive | |
| - name: Set version | |
| id: ver | |
| run: | | |
| if [ "${{ github.ref_type }}" = "tag" ]; then | |
| VERSION="${{ github.ref_name }}" | |
| VERSION="${VERSION#v}" | |
| BUILD_NUMBER="${{ github.run_number }}" | |
| elif [ -n "${{ inputs.version }}" ]; then | |
| VERSION="${{ inputs.version }}" | |
| BUILD_NUMBER="${{ inputs.build_number }}" | |
| else | |
| VERSION="0.0.0-staging.${{ github.run_number }}" | |
| BUILD_NUMBER="${{ github.run_number }}" | |
| fi | |
| echo "version=${VERSION}" >> $GITHUB_OUTPUT | |
| echo "build_number=${BUILD_NUMBER}" >> $GITHUB_OUTPUT | |
| - uses: dtolnay/rust-toolchain@master | |
| with: | |
| toolchain: stable | |
| targets: aarch64-apple-ios | |
| - uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: '3.38.1' | |
| channel: 'stable' | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.24.13' | |
| - name: Configure app | |
| run: | | |
| cd scripts | |
| echo "yes" | ./build_app.sh \ | |
| -v "${{ steps.ver.outputs.version }}" \ | |
| -b "${{ steps.ver.outputs.build_number }}" \ | |
| -p ios -a stack_wallet -d -s | |
| - name: Get dependencies | |
| run: flutter pub get | |
| - name: Create git_versions.dart stubs | |
| run: | | |
| mkdir -p crypto_plugins/flutter_libepiccash/lib | |
| mkdir -p crypto_plugins/flutter_libmwc/lib | |
| EPIC_TAG=$(git -C crypto_plugins/flutter_libepiccash describe --tags --exact-match HEAD 2>/dev/null || echo "dev") | |
| MWC_TAG=$(git -C crypto_plugins/flutter_libmwc describe --tags --exact-match HEAD 2>/dev/null || echo "dev") | |
| printf 'String getPluginVersion() => "%s";\n' "$EPIC_TAG" \ | |
| > crypto_plugins/flutter_libepiccash/lib/git_versions.dart | |
| printf 'String getPluginVersion() => "%s";\n' "$MWC_TAG" \ | |
| > crypto_plugins/flutter_libmwc/lib/git_versions.dart | |
| - name: Decode secrets | |
| env: | |
| CHANGE_NOW: ${{ secrets.CHANGE_NOW }} | |
| run: echo "$CHANGE_NOW" | base64 --decode > lib/external_api_keys.dart | |
| - name: Build | |
| run: flutter build ios --release --no-codesign | |
| - name: Package IPA | |
| run: | | |
| mkdir Payload | |
| cp -r build/ios/iphoneos/Runner.app Payload/ | |
| zip -r "stack_wallet-ios-aarch64-${{ steps.ver.outputs.version }}.ipa" Payload/ | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: stack_wallet-ios-aarch64-${{ steps.ver.outputs.version }} | |
| path: stack_wallet-ios-aarch64-${{ steps.ver.outputs.version }}.ipa | |
| release: | |
| if: github.ref_type == 'tag' | |
| needs: [build-linux, build-android, build-windows, build-macos, build-ios] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| merge-multiple: true | |
| - uses: softprops/action-gh-release@v2 | |
| with: | |
| generate_release_notes: true | |
| files: artifacts/* |