Files
hash-wallet/.github/workflows/build-ios-sim.yml
T
jwinterm 784a082f15 Legal + release-readiness pass for Hash Bags launch
Legal (aligned with the hosted hash.boats Terms & Privacy):
- Rewrite in-app Terms (assets/text/Terms_of_Use.txt): drop the false 'No Fiat
  Operations'/'No Embedded Applications' clauses; add MoonPay (optional, where
  available), Trocador swaps + ~1% fee disclosure, WalletConnect, sanctions/18+,
  Apple EULA rider, and PA + class/jury-waiver dispute terms.
- Reconcile PRIVACY.md with the canonical hosted policy.
- Add THIRD_PARTY_LICENSES.md; correct the blanket 'MIT' claim in README (app
  code MIT; bundles BSD-3/Apache-2.0/LGPL-3.0); fix README build-doc + LICENSE.md
  links and copyright year.
- Standardize in-app legal naming to 'Terms of Service'; add in-app links to
  hash.boats/terms and /privacy.

Release fixes:
- Align URL scheme hashwallet:// -> hashbags:// (matches registered scheme) so
  WalletConnect/Trezor/quick-action deep links work.
- Store-review gating: hide Buy action until a provider is available; hide the
  empty 'Apps' tab.
- Exclude removed chains (SOL/TRX/ZEC/DCR/ZANO + tokens) from swap pickers.
- Residual Cake branding: macOS CFBundleDisplayName and Windows Runner.rc
  (Hash Wallet -> Hash Bags); remove Android cakewallet://y.at leftover.
- Genericize internal-infra comments in CI workflows.
2026-07-02 14:07:24 -04:00

332 lines
14 KiB
YAML

name: Hash Bags iOS Simulator build
# Phase 1 of iOS CI: validate the Mac runner end-to-end by producing an
# unsigned simulator .app. Drop the resulting Runner.app into the iOS
# Simulator on any Apple Silicon Mac to verify the app actually compiles
# and launches.
#
# Phase 2 (separate workflow): full TestFlight pipeline with signing.
on:
# Manual-only for now. Trigger via Actions → "Hash Bags iOS Simulator
# build" → Run workflow when you want a build.
workflow_dispatch:
# Cancel in-flight runs when a newer commit lands on the same branch — so a
# burst of commits doesn't pile up N copies of the same long build.
concurrency:
group: ios-sim-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash
jobs:
build:
runs-on: macos-latest
env:
APP_IOS_TYPE: cakewallet
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
# CocoaPods refuses to operate when LANG is ASCII-8BIT (default for the
# Gitea runner shell). Force UTF-8 globally so `pod install` succeeds.
LANG: en_US.UTF-8
LC_ALL: en_US.UTF-8
# Belt-and-suspenders fallback for when the self-hosted runner's internal
# git host presents a self-signed cert. Preferred fix is to trust the
# internal CA on the runner, after which this can be removed. (Runner
# host and network specifics live in the internal CI docs, not this repo.)
NODE_TLS_REJECT_UNAUTHORIZED: '0'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
# Self-hosted Mac runner persists Flutter between runs. Only install if
# it's not already on PATH or version doesn't match.
- name: Check Flutter 3.32.0
id: flutter_check
run: |
if command -v flutter >/dev/null && flutter --version 2>/dev/null | grep -q "3\.32\.0"; then
echo "installed=true" >> "$GITHUB_OUTPUT"
flutter --version
else
echo "installed=false" >> "$GITHUB_OUTPUT"
fi
- name: Install Flutter 3.32.0 (if missing)
if: steps.flutter_check.outputs.installed != 'true'
uses: subosito/flutter-action@v2
with:
flutter-version: '3.32.0'
channel: stable
cache: true
- name: Install CocoaPods (if missing)
run: |
if command -v pod >/dev/null; then
pod --version
exit 0
fi
if command -v brew >/dev/null; then
brew install cocoapods
else
export GEM_HOME="$HOME/.gem"
export PATH="$GEM_HOME/bin:$PATH"
echo "GEM_HOME=$HOME/.gem" >> "$GITHUB_ENV"
echo "$HOME/.gem/bin" >> "$GITHUB_PATH"
gem install --user-install cocoapods --no-document
fi
pod --version
- name: Install Rust + iOS targets (if missing)
run: |
if ! command -v rustup >/dev/null; then
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --no-modify-path
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
export PATH="$HOME/.cargo/bin:$PATH"
fi
# Clean any partial downloads from a previously crashed install — those
# are the source of the 'could not rename .partial → final: No such
# file or directory' race that breaks parallel pod builds.
rm -rf "$HOME/.rustup/downloads"/*.partial 2>/dev/null || true
# Pre-install iOS targets serially so the pod build doesn't try to
# do it under concurrency.
rustup target add aarch64-apple-ios
rustup target add aarch64-apple-ios-sim
rustup target add x86_64-apple-ios
rustup show
- name: Install Go + gomobile (if missing)
run: |
if ! command -v go >/dev/null; then
if command -v brew >/dev/null; then
brew install go
else
echo "Go missing and brew not available"; exit 1
fi
fi
go version
# Ensure $(go env GOPATH)/bin is on PATH for subsequent steps.
GOPATH=$(go env GOPATH)
echo "$GOPATH/bin" >> "$GITHUB_PATH"
export PATH="$PATH:$GOPATH/bin"
# gomobile + gobind are needed by scripts/build_bitbox_flutter.sh
if ! command -v gomobile >/dev/null; then
go install golang.org/x/mobile/cmd/gomobile@latest
go install golang.org/x/mobile/cmd/gobind@latest
fi
which gomobile && gomobile version || true
- name: Show toolchain
run: |
set -x
flutter --version
xcodebuild -version
pod --version
uname -m
which curl unzip
# ---- External prebuilt deps (same as android/linux) ------------------
# macOS doesn't ship wget by default; using curl everywhere.
- name: Fetch prebuilt torch_dart
run: |
set -x -e
pushd scripts
rm -rf torch_dart torch_dart.tar.gz
curl -fsSL -o torch_dart.tar.gz https://github.com/MrCyjaneK/torch_dart/releases/download/v1.0.17/torch_dart-v1.0.17.tar.gz
mkdir torch_dart
tar -xzf torch_dart.tar.gz -C torch_dart
rm torch_dart.tar.gz
popd
- name: Fetch prebuilt reown_flutter
run: |
set -x -e
pushd scripts
rm -rf reown_flutter reown_flutter.tar.gz
curl -fsSL -o reown_flutter.tar.gz https://github.com/cake-tech/reown_flutter/releases/download/v0.0.4/reown_flutter-v0.0.4.tar.gz
mkdir reown_flutter
tar -xzf reown_flutter.tar.gz -C reown_flutter
rm reown_flutter.tar.gz
popd
- name: Clone BitBox Flutter (iOS — skip Android bindings)
run: |
# Pubspec has bitbox_flutter as a path: dep at scripts/bitbox_flutter,
# so the directory must exist for pub get. The bundled build_bindings.sh
# runs `gomobile bind -target=android` which needs the Android SDK we
# don't have on the Mac runner — and the resulting .aar is Android-only.
# iOS uses bitbox_flutter's native ios/Classes plugin, no .aar required.
set -x -e
pushd scripts
if [[ ! -d bitbox_flutter ]]; then
git clone https://github.com/konstantinullrich/bitbox_flutter
fi
cd bitbox_flutter
git fetch -a
git reset --hard
git checkout 5a6e6dd388ef64003f86094af80d5453518b601d
git reset --hard
popd
# ---- Native crypto cores (monero_c prebuilt bundle) ------------------
- name: Fetch prebuilt monero_c bundle
run: |
set -x -e
./scripts/prepare_moneroc.sh
MONERO_C_TAG=$(cd scripts/monero_c && git describe --tags)
mkdir -p "scripts/monero_c/release/$MONERO_C_TAG"
pushd "scripts/monero_c/release/$MONERO_C_TAG"
curl -fsSL -O https://github.com/MrCyjaneK/monero_c/releases/download/v0.18.4.6-RC1/release-bundle.zip
unzip -q release-bundle.zip
rm release-bundle.zip
echo "=== bundle contents (one level) ==="
ls
popd
- name: Inspect iOS targets available in monero_c bundle
run: |
set -x
MONERO_C_TAG=$(cd scripts/monero_c && git describe --tags)
BUNDLE_DIR="scripts/monero_c/release/$MONERO_C_TAG"
echo "=== bundle top-level ==="
ls "$BUNDLE_DIR" || true
echo "=== iOS-y subdirs ==="
find "$BUNDLE_DIR" -maxdepth 1 -type d \( -name '*ios*' -o -name '*apple*' \) 2>/dev/null
echo "=== sample contents of one apple-ios target ==="
for d in "$BUNDLE_DIR"/aarch64-apple-ios "$BUNDLE_DIR"/aarch64-apple-ios-simulator; do
[[ -d "$d" ]] && { echo "--- $d ---"; ls "$d"; }
done
- name: Build MoneroWallet + WowneroWallet XCFrameworks
run: |
set -x -e
pushd scripts/ios
bash ./gen_framework.sh
popd
ls -la ios/MoneroWallet.xcframework ios/WowneroWallet.xcframework
# ---- Configure: pubspec.yaml, Info.plist, GeneratedPluginRegistrant ---
- name: Run iOS configure (cakewallet profile)
run: |
set -x -e
pushd scripts/ios
source ./app_env.sh cakewallet
./app_config.sh
popd
# ---- Secrets ---------------------------------------------------------
- name: Generate per-module secrets.g.dart files (all empty defaults)
run: dart run tool/generate_new_secrets.dart
- name: Inject Trocador affiliate secrets
env:
TROCADOR_API_KEY: ${{ secrets.TROCADOR_API_KEY }}
TROCADOR_MONERO_API_KEY: ${{ secrets.TROCADOR_MONERO_API_KEY }}
TROCADOR_EXCHANGE_MARKUP: ${{ secrets.TROCADOR_EXCHANGE_MARKUP }}
run: |
# macOS sed needs '' after -i; Linux sed doesn't accept that. This
# workflow runs on macos only.
sed -i '' \
-e "s|const trocadorApiKey = '';|const trocadorApiKey = '${TROCADOR_API_KEY}';|" \
-e "s|const trocadorMoneroApiKey = '';|const trocadorMoneroApiKey = '${TROCADOR_MONERO_API_KEY}';|" \
-e "s|const trocadorExchangeMarkup = '';|const trocadorExchangeMarkup = '${TROCADOR_EXCHANGE_MARKUP:-1}';|" \
lib/.secrets.g.dart
grep '^const trocador' lib/.secrets.g.dart
# ---- Flutter init + codegen -----------------------------------------
- name: Initialize Flutter SDK (iOS precache)
run: |
flutter --version
flutter precache --ios --no-linux --no-android --no-macos --no-windows --no-fuchsia --no-web || true
- name: Build generated code (mobx + hive adapters)
run: bash model_generator.sh
- name: Generate localization
run: dart run tool/generate_localization.dart
- name: Compile SVG assets (res/pictures/*.svg → assets/new-ui/*.svg.vec)
run: ./compile_graphics.sh
# CocoaPods: the iOS Podfile installs Flutter plugin pods. Required
# before flutter build can link them.
- name: pod install
run: |
cd ios
pod install --repo-update
# ---- Build iOS Simulator app (no codesign) ---------------------------
- name: Build iOS Simulator app
run: |
set -x -e
flutter build ios --simulator --no-codesign \
--dart-define-from-file=env.json
ls -la build/ios/iphonesimulator/
- name: Zip Runner.app
run: |
cd build/ios/iphonesimulator
zip -r hash_wallet_ios_sim_${{ github.sha }}.zip Runner.app
# Confirm git.such.software resolves to a local target (the Mac itself).
# The runner inherits the Mac's /etc/hosts directly (host-mode act_runner),
# so the user should have:
# 127.0.0.1 git.such.software
# already in /etc/hosts. We only assert that here, don't modify (sudo
# without NOPASSWD prompts for a password the runner can't enter).
#
# macOS's `getent` doesn't exist and `nslookup` bypasses /etc/hosts.
# We grep /etc/hosts directly — that's what Node's getaddrinfo will
# actually consult.
- name: Verify Gitea hostname resolves locally
run: |
if grep -qE '^[[:space:]]*(127\.0\.0\.1|host\.docker\.internal|192\.168\.)[[:space:]]+git\.such\.software' /etc/hosts; then
echo "✓ /etc/hosts points git.such.software at a local target:"
grep git.such.software /etc/hosts
else
echo "✗ /etc/hosts is MISSING a local override for git.such.software."
echo " Node will resolve to the public IP and fail on NAT hairpin."
echo " Add (once, on the Mac mini):"
echo " sudo sh -c 'echo \"127.0.0.1 git.such.software\" >> /etc/hosts'"
exit 1
fi
# Diagnostic: print exactly where upload-artifact will try to send data.
# act_runner injects these env vars; their values tell us whether the
# upload targets git.such.software (uses our /etc/hosts override) or
# a LAN IP directly (override irrelevant). Also probe the URL with
# curl -k so we see the cert + reachability before the real upload.
- name: Diagnose Actions API endpoint
run: |
set +e
echo "=== Actions runtime env ==="
echo "ACTIONS_RUNTIME_URL=${ACTIONS_RUNTIME_URL:-<unset>}"
echo "ACTIONS_RESULTS_URL=${ACTIONS_RESULTS_URL:-<unset>}"
echo "ACTIONS_CACHE_URL=${ACTIONS_CACHE_URL:-<unset>}"
echo "GITHUB_SERVER_URL=${GITHUB_SERVER_URL:-<unset>}"
echo "GITHUB_API_URL=${GITHUB_API_URL:-<unset>}"
echo "NODE_TLS_REJECT_UNAUTHORIZED=${NODE_TLS_REJECT_UNAUTHORIZED:-<unset>}"
echo
# Probe each non-empty URL to see what Node will actually hit.
for var in ACTIONS_RUNTIME_URL ACTIONS_RESULTS_URL GITHUB_SERVER_URL; do
url="${!var}"
[ -z "$url" ] && continue
host=$(echo "$url" | sed -E 's|^https?://([^/:]+).*|\1|')
echo "--- $var → $url ---"
echo "DNS for $host:"
dscacheutil -q host -a name "$host" 2>/dev/null || nslookup "$host" 2>/dev/null || true
echo "HEAD probe (curl -kIv, 10s timeout):"
curl -kIv --max-time 10 "$url" 2>&1 | head -40 || true
echo
done
- name: Upload .app artifact
uses: actions/upload-artifact@v3
with:
name: hash-wallet-ios-sim-${{ github.sha }}
path: build/ios/iphonesimulator/hash_wallet_ios_sim_*.zip
retention-days: 14