From a3794227f492ab66b1d6e692d7481c95edc79d0f Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Fri, 1 May 2026 21:02:02 -0700 Subject: [PATCH 1/3] Fix Android ABI conflict with --split-per-abi --- .github/workflows/build.yaml | 231 ++++++++++++++++++++++++++++++++++- 1 file changed, 228 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2e2ed58c6..b0dd56f2e 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -183,17 +183,242 @@ jobs: 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 - cp build/app/outputs/bundle/release/app-release.aab \ - android-artifacts/stack_wallet-android-${VERSION}.aab - uses: actions/upload-artifact@v4 with: name: stack_wallet-android-${{ steps.ver.outputs.version }} path: android-artifacts/ + build-windows: + runs-on: windows-latest + 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 }}" + else + VERSION="${{ inputs.version }}" + BUILD_NUMBER="${{ inputs.build_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' + + - 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 + + - 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: Generate app config + run: dart run build_runner build --delete-conflicting-outputs + + - 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 }}" + else + VERSION="${{ inputs.version }}" + BUILD_NUMBER="${{ inputs.build_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' + + - 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: Generate app config + run: dart run build_runner build --delete-conflicting-outputs + + - 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 }}" + else + VERSION="${{ inputs.version }}" + BUILD_NUMBER="${{ inputs.build_number }}" + fi + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "build_number=${BUILD_NUMBER}" >> $GITHUB_OUTPUT + + - uses: dtolnay/rust-toolchain@master + with: + toolchain: '1.71.0' + targets: aarch64-apple-ios + + - uses: subosito/flutter-action@v2 + with: + flutter-version: '3.38.1' + channel: 'stable' + + - 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: Generate app config + run: dart run build_runner build --delete-conflicting-outputs + + - 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] + needs: [build-linux, build-android, build-windows, build-macos, build-ios] runs-on: ubuntu-latest permissions: contents: write From c84020e986c87de1d99c39d285ebab7fc8d50755 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Fri, 1 May 2026 21:39:25 -0700 Subject: [PATCH 2/3] Use GHCR for docker image registry and add binary lib download scripts for ios,mac,windows --- .github/workflows/build-ci-image.yaml | 14 +++++++++----- .github/workflows/test.yaml | 9 ++++++--- scripts/ios/download_all.sh | 16 ++++++++++++++++ scripts/macos/download_all.sh | 16 ++++++++++++++++ scripts/windows/download_all.sh | 16 ++++++++++++++++ 5 files changed, 63 insertions(+), 8 deletions(-) create mode 100755 scripts/ios/download_all.sh create mode 100755 scripts/macos/download_all.sh create mode 100755 scripts/windows/download_all.sh diff --git a/.github/workflows/build-ci-image.yaml b/.github/workflows/build-ci-image.yaml index 4c40a0873..cd3facf4d 100644 --- a/.github/workflows/build-ci-image.yaml +++ b/.github/workflows/build-ci-image.yaml @@ -9,11 +9,14 @@ on: workflow_dispatch: env: - IMAGE: ${{ secrets.DOCKERHUB_USERNAME }}/stackwallet-ci + GHCR_IMAGE: ghcr.io/${{ github.repository_owner }}/stackwallet-ci jobs: build: runs-on: ubuntu-24.04 + permissions: + contents: read + packages: write steps: - uses: actions/checkout@v6 @@ -21,8 +24,9 @@ jobs: - uses: docker/login-action@v4 with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v7 @@ -30,7 +34,7 @@ jobs: context: . push: true tags: | - ${{ env.IMAGE }}:latest - ${{ env.IMAGE }}:${{ github.sha }} + ${{ env.GHCR_IMAGE }}:latest + ${{ env.GHCR_IMAGE }}:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 622387ba1..f908ec88e 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -3,11 +3,14 @@ on: [pull_request] jobs: test: runs-on: ubuntu-24.04 + permissions: + contents: read + packages: read container: - image: stackwallet/stackwallet-ci:latest + image: ghcr.io/${{ github.repository_owner }}/stackwallet-ci:latest credentials: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + username: ${{ github.actor }} + password: ${{ github.token }} steps: - name: Prepare repository uses: actions/checkout@v6 diff --git a/scripts/ios/download_all.sh b/scripts/ios/download_all.sh new file mode 100755 index 000000000..714531e9f --- /dev/null +++ b/scripts/ios/download_all.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -x -e + +mkdir -p build + +PLUGINS_DIR=../../crypto_plugins + +(cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/ios && ./download.sh) + +(cd "${PLUGINS_DIR}"/flutter_libmwc/scripts/ios && ./download.sh) + +# frostdart iOS is built from source by Cargokit at pod install time + +wait +echo "Done" diff --git a/scripts/macos/download_all.sh b/scripts/macos/download_all.sh new file mode 100755 index 000000000..4bbb400bc --- /dev/null +++ b/scripts/macos/download_all.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -x -e + +mkdir -p build + +PLUGINS_DIR=../../crypto_plugins + +(cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/macos && ./download.sh) + +(cd "${PLUGINS_DIR}"/flutter_libmwc/scripts/macos && ./download.sh) + +(cd "${PLUGINS_DIR}"/frostdart/scripts/macos && ./download.sh) + +wait +echo "Done" diff --git a/scripts/windows/download_all.sh b/scripts/windows/download_all.sh new file mode 100755 index 000000000..6bd350408 --- /dev/null +++ b/scripts/windows/download_all.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -x -e + +mkdir -p build + +PLUGINS_DIR=../../crypto_plugins + +(cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/windows && ./download.sh) + +(cd "${PLUGINS_DIR}"/flutter_libmwc/scripts/windows && ./download.sh) + +(cd "${PLUGINS_DIR}"/frostdart/scripts/windows && ./download.sh) + +wait +echo "Done" From 5d6d09e7429234274cb95cc914e6c0c1b7766cd3 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Fri, 1 May 2026 21:59:54 -0700 Subject: [PATCH 3/3] Speed up CI image pull by switching to GHCR and adding a minimal test stage --- .github/workflows/build-ci-image.yaml | 13 +++++++++- .github/workflows/test.yaml | 2 +- Dockerfile | 34 ++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-ci-image.yaml b/.github/workflows/build-ci-image.yaml index cd3facf4d..066290576 100644 --- a/.github/workflows/build-ci-image.yaml +++ b/.github/workflows/build-ci-image.yaml @@ -28,13 +28,24 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push + - name: Build and push full image uses: docker/build-push-action@v7 with: context: . + target: full push: true tags: | ${{ env.GHCR_IMAGE }}:latest ${{ env.GHCR_IMAGE }}:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max + + - name: Build and push test image + uses: docker/build-push-action@v7 + with: + context: . + target: test + push: true + tags: ${{ env.GHCR_IMAGE }}:test + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index f908ec88e..9093439cf 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -7,7 +7,7 @@ jobs: contents: read packages: read container: - image: ghcr.io/${{ github.repository_owner }}/stackwallet-ci:latest + image: ghcr.io/${{ github.repository_owner }}/stackwallet-ci:test credentials: username: ${{ github.actor }} password: ${{ github.token }} diff --git a/Dockerfile b/Dockerfile index 0c1a24042..e1c6a237d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1.7 -FROM ubuntu:24.04 +FROM ubuntu:24.04 AS full ENV DEBIAN_FRONTEND=noninteractive \ TZ=Etc/UTC \ @@ -78,3 +78,35 @@ RUN git clone --depth 1 --branch 3.38.1 https://github.com/flutter/flutter.git " RUN git config --system --add safe.directory '*' RUN flutter --version && rustc --version && cargo --version && node --version + + +# Minimal image for flutter test (no Rust, no Android SDK, no cross-compilers) +FROM ubuntu:24.04 AS test + +ENV DEBIAN_FRONTEND=noninteractive \ + TZ=Etc/UTC \ + LANG=C.UTF-8 \ + LC_ALL=C.UTF-8 + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates curl file git unzip xz-utils \ + build-essential cmake ninja-build pkg-config \ + clang libclang-dev \ + libgirepository1.0-dev libglib2.0-dev libgtk-3-dev \ + libjsoncpp-dev liblzma-dev libsecret-1-dev libssl-dev \ + && rm -rf /var/lib/apt/lists/* + +ENV FLUTTER_HOME=/opt/flutter \ + PATH=/opt/flutter/bin:/opt/flutter/bin/cache/dart-sdk/bin:$PATH + +RUN git clone --depth 1 --branch 3.38.1 https://github.com/flutter/flutter.git "$FLUTTER_HOME" \ + && git config --global --add safe.directory '*' \ + && flutter config --no-analytics \ + && flutter precache --linux \ + && chmod -R a+rwX "$FLUTTER_HOME" + +RUN git config --system --add safe.directory '*' + +RUN flutter --version