The web app has deployed on push since earlier today, but the phone apps carry their own frozen copy of the UI, so a change to server/public silently left them behind until someone remembered to cut a release. Remembering was the weak part. A second Actions runner now runs on the ingest Mac — in host mode, because an app build needs Xcode, the Android SDK and the signing keys, none of which exist in the NAS runner's Linux container. A push touching server/public, mobile/src or the Capacitor config rebuilds and signs both apps, then emails to say the shipped apps are behind, or that the build broke. It deliberately stops before uploading. An upload needs a build number that has never been used, Play refuses to reuse or lower a versionCode, and bumping it means committing the new number back from the build machine on every run. That needs write access from that machine and permanently changes the numbering scheme — a one-way door, so shipping stays an explicit ./release.sh. release.config.json is excluded from the trigger paths so that bumping a build number by hand cannot set off a rebuild of what was just built. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
128 lines
5.5 KiB
YAML
128 lines
5.5 KiB
YAML
# Push something the apps bundle -> the ingest Mac builds both apps and emails you.
|
|
#
|
|
# WHY THIS STOPS SHORT OF UPLOADING
|
|
# Uploading needs a build number that has never been used before, and Play will never
|
|
# accept a versionCode twice or accept one that goes down. Bumping it means committing
|
|
# the new number back to this repo on every build, which needs write access from the
|
|
# build machine and permanently changes how the apps are numbered. That is a one-way
|
|
# door, so it is left as a deliberate command: ./release.sh --ios --android
|
|
#
|
|
# What this does remove is having to REMEMBER. A change that the apps bundle no longer
|
|
# sits unnoticed: it gets built immediately, you find out straight away if it no longer
|
|
# compiles, and you get an email saying the shipped apps are now behind the website.
|
|
#
|
|
# WHY THE INGEST MAC AND NOT THE NAS
|
|
# An app build needs Xcode, the Android SDK and the signing keys. The NAS runner is
|
|
# Linux in a container and has none of them. This job runs in HOST mode (label
|
|
# "macos:host") directly on the ingest Mac, which has all three.
|
|
|
|
name: Build apps
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
paths:
|
|
# Only what actually ends up inside an app bundle. Deliberately NOT all of mobile/:
|
|
# release.config.json is excluded so that bumping a build number by hand never
|
|
# triggers a rebuild of the thing that was just built.
|
|
- 'server/public/**'
|
|
- 'mobile/src/**'
|
|
- 'mobile/capacitor.config.json'
|
|
- 'mobile/package.json'
|
|
- '.gitea/workflows/build-apps.yml'
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: macos
|
|
steps:
|
|
- name: Build both apps
|
|
run: |
|
|
set -eu
|
|
export PATH="/usr/local/bin:/opt/homebrew/bin:$PATH"
|
|
APP="$HOME/checklist-app"
|
|
cd "$APP"
|
|
|
|
echo "── syncing the checkout ──"
|
|
git pull --ff-only
|
|
|
|
echo "── dependencies ──"
|
|
( cd mobile && npm install --no-audit --no-fund >/dev/null )
|
|
|
|
echo "── rebuilding www/ from server/public ──"
|
|
( cd mobile && node scripts/sync-web.js )
|
|
|
|
# Without this the iOS build fails on a missing ios/App/App/public, because that
|
|
# directory is generated rather than committed. release.sh does the same thing.
|
|
echo "── capacitor sync ──"
|
|
( cd mobile && npx cap sync >/dev/null )
|
|
|
|
echo "── android ──"
|
|
( cd mobile/android && . ../scripts/env.sh && ./gradlew :app:bundleRelease --no-daemon -q )
|
|
AAB="$APP/mobile/android/app/build/outputs/bundle/release/app-release.aab"
|
|
test -f "$AAB"
|
|
echo " $AAB ($(du -h "$AAB" | cut -f1))"
|
|
|
|
echo "── ios ──"
|
|
. mobile/ios-signing.config
|
|
rm -rf mobile/build/App.xcarchive mobile/build/ios
|
|
( cd mobile/ios/App && xcodebuild -project App.xcodeproj -scheme App \
|
|
-configuration Release -destination 'generic/platform=iOS' \
|
|
-archivePath "$APP/mobile/build/App.xcarchive" \
|
|
DEVELOPMENT_TEAM="$DEVELOPMENT_TEAM" CODE_SIGN_STYLE=Automatic \
|
|
-allowProvisioningUpdates archive -quiet )
|
|
|
|
cat > mobile/ExportOptions.plist <<PLIST
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<plist version="1.0"><dict>
|
|
<key>method</key><string>app-store-connect</string>
|
|
<key>teamID</key><string>$DEVELOPMENT_TEAM</string>
|
|
<key>destination</key><string>export</string>
|
|
<key>uploadSymbols</key><true/>
|
|
</dict></plist>
|
|
PLIST
|
|
|
|
( cd mobile/ios/App && xcodebuild -exportArchive \
|
|
-archivePath "$APP/mobile/build/App.xcarchive" \
|
|
-exportOptionsPlist "$APP/mobile/ExportOptions.plist" \
|
|
-exportPath "$APP/mobile/build/ios" \
|
|
-allowProvisioningUpdates -quiet )
|
|
IPA="$(find "$APP/mobile/build/ios" -name '*.ipa' | head -1)"
|
|
test -n "$IPA"
|
|
echo " $IPA ($(du -h "$IPA" | cut -f1))"
|
|
|
|
- name: Tell Christian the apps are behind
|
|
if: success()
|
|
run: |
|
|
export PATH="/usr/local/bin:$PATH"
|
|
APP="$HOME/checklist-app"
|
|
cd "$APP"
|
|
V="$(node -e 'const c=require("./mobile/release.config.json");console.log(`${c.version} (ios build ${c.iosBuild}, android code ${c.androidVersionCode})`)')"
|
|
node scripts/alert.js "Apps rebuilt and waiting — shipped versions are now behind" \
|
|
"A change landed that the iOS and Android apps bundle, so they were rebuilt on the
|
|
ingest Mac. Both built cleanly and are signed and ready.
|
|
|
|
They are NOT on anyone's phone yet, and will not be until you ship them:
|
|
|
|
cd ~/Documents/recurring-checklist-app
|
|
./release.sh --ios --android
|
|
|
|
Current numbering: $V
|
|
|
|
The website already has this change — it deploys on push. Only the apps, which carry
|
|
their own copy of the UI, are waiting." || true
|
|
|
|
- name: Tell Christian the build broke
|
|
if: failure()
|
|
run: |
|
|
export PATH="/usr/local/bin:$PATH"
|
|
cd "$HOME/checklist-app"
|
|
node scripts/alert.js "App build FAILED on the ingest Mac" \
|
|
"A push changed something the apps bundle, and the rebuild did not compile.
|
|
|
|
The website is unaffected — it deploys separately and is already live with this
|
|
change. But the apps cannot be shipped until this builds again.
|
|
|
|
Full log: http://chronicles-ab.waterschurch.org:3000/christian/recurring-checklist/actions" || true
|