Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 209 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
name: Build

on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
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
container:
image: stackwallet/stackwallet-ci:latest
credentials:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_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 }}"
else
VERSION="${{ inputs.version }}"
BUILD_NUMBER="${{ inputs.build_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: Generate app config
run: dart run build_runner build --delete-conflicting-outputs

- name: Build
run: flutter build linux --release

- 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
container:
image: stackwallet/stackwallet-ci:latest
credentials:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_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 }}"
else
VERSION="${{ inputs.version }}"
BUILD_NUMBER="${{ inputs.build_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: Generate app config
run: dart run build_runner build --delete-conflicting-outputs

- 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
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/

release:
if: github.ref_type == 'tag'
needs: [build-linux, build-android]
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/*
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Configure app
run: |
cd scripts
echo "yes" | ./build_app.sh -v "0.0.1" -b "1" -p "linux" -a "stack_wallet" -s
echo "yes" | ./build_app.sh -v "0.0.1" -b "1" -p "linux" -a "stack_wallet" -d -s

- name: Get dependencies
run: flutter pub get
Expand Down
34 changes: 25 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ ENV DEBIAN_FRONTEND=noninteractive \
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 \
Expand All @@ -18,6 +19,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
ocl-icd-opencl-dev opencl-headers valac zlib1g-dev \
g++-aarch64-linux-gnu gcc-aarch64-linux-gnu \
g++-mingw-w64-x86-64 gcc-mingw-w64-x86-64 \
openjdk-17-jdk-headless \
&& rm -rf /var/lib/apt/lists/*

RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \
Expand All @@ -30,27 +32,41 @@ ENV RUSTUP_HOME=/usr/local/rustup \

RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --default-toolchain 1.89.0 --profile minimal --no-modify-path \
&& rustup install 1.85.1 --profile minimal \
&& rustup install 1.85.1 1.71.0 --profile minimal \
&& rustup target add x86_64-unknown-linux-gnu --toolchain 1.89.0 \
&& cargo install cargo-ndk \
&& chmod -R a+rwX "$CARGO_HOME" "$RUSTUP_HOME"

ENV ANDROID_NDK_ROOT=/opt/android-ndk-r28 \
ANDROID_NDK_HOME=/opt/android-ndk-r28
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64

ENV ANDROID_SDK_ROOT=/opt/android-sdk \
ANDROID_HOME=/opt/android-sdk \
ANDROID_NDK_ROOT=/opt/android-sdk/ndk/28.2.13676358 \
ANDROID_NDK_HOME=/opt/android-sdk/ndk/28.2.13676358 \
PATH=/opt/android-sdk/cmdline-tools/latest/bin:/opt/android-sdk/platform-tools:$PATH

RUN curl -fsSL https://dl.google.com/android/repository/android-ndk-r28-linux.zip \
-o /tmp/android-ndk.zip \
&& echo "a186b67e8810cb949514925e4f7a2255548fb55f5e9b0824a6430d012c1b695b /tmp/android-ndk.zip" | sha256sum -c \
&& unzip -q /tmp/android-ndk.zip -d /opt \
&& rm /tmp/android-ndk.zip
RUN mkdir -p "$ANDROID_SDK_ROOT/cmdline-tools" \
&& curl -fsSL https://dl.google.com/android/repository/commandlinetools-linux-14742923_latest.zip \
-o /tmp/cmdline-tools.zip \
&& echo "48833c34b761c10cb20bcd16582129395d121b27 /tmp/cmdline-tools.zip" | sha1sum -c \
&& unzip -q /tmp/cmdline-tools.zip -d "$ANDROID_SDK_ROOT/cmdline-tools" \
&& mv "$ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools" "$ANDROID_SDK_ROOT/cmdline-tools/latest" \
&& rm /tmp/cmdline-tools.zip \
&& yes | sdkmanager --licenses \
&& sdkmanager \
"platform-tools" \
"build-tools;35.0.0" \
"platforms;android-35" \
"ndk;28.2.13676358" \
&& chmod -R a+rwX "$ANDROID_SDK_ROOT"

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 \
&& flutter precache --linux --android \
&& chmod -R a+rwX "$FLUTTER_HOME"

RUN git config --system --add safe.directory '*'
Expand Down
17 changes: 17 additions & 0 deletions scripts/android/download_all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

set -x -e

mkdir -p build
. ./config.sh

PLUGINS_DIR=../../crypto_plugins

(cd "${PLUGINS_DIR}"/flutter_libepiccash/scripts/android && ./download.sh)

(cd "${PLUGINS_DIR}"/flutter_libmwc/scripts/android && ./download.sh)

(cd "${PLUGINS_DIR}"/frostdart/scripts/android && ./download.sh)

wait
echo "Done"
35 changes: 25 additions & 10 deletions scripts/build_app.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ APP_NAMED_IDS=("stack_wallet" "stack_duo" "campfire")

# Function to display usage.
usage() {
echo "Usage: $0 -v <version> -b <build_number> -p <platform> -a <app> [-i] [-f] [-s]"
echo "Usage: $0 -v <version> -b <build_number> -p <platform> -a <app> [-d] [-i] [-f] [-s]"
exit 1
}

Expand All @@ -33,17 +33,19 @@ unset -v APP_NAMED_ID

# optional args (with defaults)
BUILD_CRYPTO_PLUGINS=0
DOWNLOAD_CRYPTO_PLUGINS=0
BUILD_ISAR_FROM_SOURCE=0
USE_SYSTEM_SECURE_STORAGE_DEPS=0

# Parse command-line arguments.
while getopts "v:b:p:a:i:fs" opt; do
while getopts "v:b:p:a:idfs" opt; do
case "${opt}" in
v) APP_VERSION_STRING="$OPTARG" ;;
b) APP_BUILD_NUMBER="$OPTARG" ;;
p) APP_BUILD_PLATFORM="$OPTARG" ;;
a) APP_NAMED_ID="$OPTARG" ;;
i) BUILD_CRYPTO_PLUGINS=1 ;;
d) DOWNLOAD_CRYPTO_PLUGINS=1 ;;
f) BUILD_ISAR_FROM_SOURCE=1 ;;
s) USE_SYSTEM_SECURE_STORAGE_DEPS=1 ;;
*) usage ;;
Expand Down Expand Up @@ -114,15 +116,28 @@ else
fi

if [ "$BUILD_CRYPTO_PLUGINS" -eq 0 ]; then
if [[ "$APP_NAMED_ID" = "stack_wallet" ]]; then
./build_all.sh
elif [[ "$APP_NAMED_ID" = "stack_duo" ]]; then
./build_all_duo.sh
elif [[ "$APP_NAMED_ID" = "campfire" ]]; then
./build_all_campfire.sh
if [ "$DOWNLOAD_CRYPTO_PLUGINS" -eq 1 ]; then
if [[ "$APP_NAMED_ID" = "stack_wallet" ]]; then
./download_all.sh
elif [[ "$APP_NAMED_ID" = "stack_duo" ]]; then
./build_all_duo.sh
elif [[ "$APP_NAMED_ID" = "campfire" ]]; then
./build_all_campfire.sh
else
echo "Invalid app id: ${APP_NAMED_ID}"
exit 1
fi
else
echo "Invalid app id: ${APP_NAMED_ID}"
exit 1
if [[ "$APP_NAMED_ID" = "stack_wallet" ]]; then
./build_all.sh
elif [[ "$APP_NAMED_ID" = "stack_duo" ]]; then
./build_all_duo.sh
elif [[ "$APP_NAMED_ID" = "campfire" ]]; then
./build_all_campfire.sh
else
echo "Invalid app id: ${APP_NAMED_ID}"
exit 1
fi
fi
fi

Expand Down
17 changes: 17 additions & 0 deletions scripts/linux/download_all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

set -x -e

mkdir -p build
./build_secure_storage_deps.sh

(cd ../../crypto_plugins/flutter_libepiccash/scripts/linux && ./download.sh)

(cd ../../crypto_plugins/flutter_libmwc/scripts/linux && ./download.sh)

(cd ../../crypto_plugins/frostdart/scripts/linux && ./download.sh)

./build_secp256k1.sh

wait
echo "Done"
Loading