-
Notifications
You must be signed in to change notification settings - Fork 0
194 lines (174 loc) · 7.44 KB
/
android.yml
File metadata and controls
194 lines (174 loc) · 7.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
name: android
on:
push:
branches: [main]
tags: ["v*"]
pull_request:
workflow_dispatch:
inputs:
build_type:
description: "Build type (debug or release)"
required: false
default: debug
type: choice
options: [debug, release]
permissions:
contents: write
env:
BUILD_TYPE: ${{ github.event.inputs.build_type || 'debug' }}
jobs:
apk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 10.18.1
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
- uses: android-actions/setup-android@v3
with:
# `packages` is a single space-separated string, not a list. The
# heredoc form is silently treated as one package id.
packages: "platform-tools platforms;android-34 build-tools;34.0.0"
- name: Install JS deps
run: pnpm install --frozen-lockfile
- name: Resolve URLs
# The bundled web build needs the API + gateway URLs at compile time
# (Vite inlines them). The Capacitor shell additionally needs
# TEMPEST_WEB_URL set so the native app loads the live web origin -
# WebAuthn / passkeys refuse to run from https://localhost. All
# three values fall back to apps/mobile/.env.production if the
# repo vars are not configured.
run: |
: "${VITE_API_BASE:=${{ vars.VITE_API_BASE }}}"
: "${VITE_GATEWAY_URL:=${{ vars.VITE_GATEWAY_URL }}}"
: "${TEMPEST_WEB_URL:=${{ vars.TEMPEST_WEB_URL }}}"
if [ -f apps/mobile/.env.production ]; then
set -a; . apps/mobile/.env.production; set +a
fi
if [ -z "$VITE_API_BASE" ]; then
echo "::error::VITE_API_BASE is unset. Set it as a repo variable in" \
"Settings -> Secrets and variables -> Actions -> Variables, or" \
"edit apps/mobile/.env.production. Without it the APK has no" \
"API URL and login will fail with a 404 on /auth/start_login."
exit 1
fi
echo "VITE_API_BASE=$VITE_API_BASE" >> "$GITHUB_ENV"
echo "VITE_GATEWAY_URL=$VITE_GATEWAY_URL" >> "$GITHUB_ENV"
echo "TEMPEST_WEB_URL=$TEMPEST_WEB_URL" >> "$GITHUB_ENV"
if [ -z "$TEMPEST_WEB_URL" ]; then
echo "::warning::TEMPEST_WEB_URL is unset. The APK will fall back to" \
"the bundled web/dist; passkey login will be unavailable until" \
"you point it at your live tempest-web origin."
fi
echo "Building APK with API=$VITE_API_BASE GW=$VITE_GATEWAY_URL WEB=$TEMPEST_WEB_URL"
- name: Build web bundle
env:
VITE_API_BASE: ${{ env.VITE_API_BASE }}
VITE_GATEWAY_URL: ${{ env.VITE_GATEWAY_URL }}
run: pnpm --filter tempest-web build
- name: Add Android platform
# `cap add android` scaffolds apps/mobile/android with the gradle
# project. We don't commit it; CI re-creates it every run so the
# build is always reproducible from the current Capacitor config.
working-directory: apps/mobile
env:
TEMPEST_WEB_URL: ${{ env.TEMPEST_WEB_URL }}
run: |
pnpm exec cap add android
pnpm exec cap sync android
- name: Generate launcher icons + splash
working-directory: apps/mobile
run: pnpm exec capacitor-assets generate --android || true
- name: Decode signing keystore
if: env.BUILD_TYPE == 'release' && env.ANDROID_KEYSTORE_BASE64 != ''
env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
run: |
mkdir -p apps/mobile/android/app
echo "$ANDROID_KEYSTORE_BASE64" | base64 -d > apps/mobile/android/app/release.keystore
- name: Restore debug keystore
# Without this, gradle generates a fresh ~/.android/debug.keystore on
# every CI run, so the APK signing cert (and its SHA-256) changes
# every build. Storing a stable keystore as a secret keeps the
# SHA-256 stable so ANDROID_ASSETLINKS_SHA256 on tempest-web does
# not need updating every build. Generate the secret value with
# scripts/gen-debug-keystore.sh.
env:
ANDROID_DEBUG_KEYSTORE_BASE64: ${{ secrets.ANDROID_DEBUG_KEYSTORE_BASE64 }}
run: |
if [ "$BUILD_TYPE" != "debug" ]; then
exit 0
fi
if [ -z "$ANDROID_DEBUG_KEYSTORE_BASE64" ]; then
echo "::warning::ANDROID_DEBUG_KEYSTORE_BASE64 secret is unset;" \
"this debug APK will be signed by a fresh per-runner" \
"keystore, so the SHA-256 changes every run. Run" \
"scripts/gen-debug-keystore.sh, base64 the output, and add" \
"it as the ANDROID_DEBUG_KEYSTORE_BASE64 repo secret to" \
"stabilize it."
exit 0
fi
mkdir -p "$HOME/.android"
echo "$ANDROID_DEBUG_KEYSTORE_BASE64" | base64 -d > "$HOME/.android/debug.keystore"
chmod 600 "$HOME/.android/debug.keystore"
echo "Restored stable debug keystore from secret."
- name: Assemble APK
working-directory: apps/mobile/android
env:
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }}
run: |
chmod +x ./gradlew
if [ "$BUILD_TYPE" = "release" ]; then
./gradlew assembleRelease --no-daemon
else
./gradlew assembleDebug --no-daemon
fi
- name: Collect APK
run: |
mkdir -p out
find apps/mobile/android/app/build/outputs/apk -name "*.apk" -exec cp -v {} out/ \;
ls -la out
- name: Print signing cert SHA-256 for asset links
# The Android Credential Manager only allows passkeys when the web
# origin publishes /.well-known/assetlinks.json with a fingerprint
# that matches the signing cert of the APK. Print the SHA-256 here
# so it can be pasted into the ANDROID_ASSETLINKS_SHA256 env var on
# the tempest-web service. Debug builds use a per-runner keystore,
# so this changes every run for build_type=debug.
run: |
APK=$(ls out/*.apk | head -n1)
if [ -z "$APK" ]; then
echo "::warning::no APK to inspect"
exit 0
fi
SHA=$(keytool -printcert -jarfile "$APK" 2>/dev/null \
| awk -F': ' '/SHA256:/{print $2; exit}')
if [ -z "$SHA" ]; then
echo "::warning::could not extract SHA-256 from $APK"
exit 0
fi
echo "::notice::Android signing SHA-256 ($BUILD_TYPE): $SHA"
echo "Set ANDROID_ASSETLINKS_SHA256 on tempest-web to this value"
echo "(comma-separated if you need both debug and release):"
echo " $SHA"
- uses: actions/upload-artifact@v4
with:
name: tempest-android-${{ env.BUILD_TYPE }}
path: out/*.apk
if-no-files-found: error
retention-days: 14
- name: Attach to release
if: startsWith(github.ref, 'refs/tags/v')
uses: softprops/action-gh-release@v2
with:
files: out/*.apk