Repository navigation
209 lines (182 loc) · 8.61 KB
/
Copy pathmobile-build.yml
File metadata and controls
209 lines (182 loc) · 8.61 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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
name: Mobile App CI
permissions:
contents: read
on:
push:
branches: [ master ]
workflow_dispatch:
# Xcode allocates the production build number during export. Keep that export
# and its eventual upload in one lane so another run cannot choose the same
# number while the first IPA is still being verified. Retain pending app builds
# even when a later push only changes backend files.
concurrency:
group: maple-ios-production-testflight
cancel-in-progress: false
queue: max
jobs:
changes:
if: >-
github.repository == 'MaplePrivacyLabs/Maple' &&
github.ref == 'refs/heads/master' &&
(github.event_name == 'push' || github.event_name == 'workflow_dispatch')
uses: ./.github/workflows/app-change-detection.yml
build-ios:
environment: apple-signing
needs: changes
if: >-
always() && !cancelled() &&
github.repository == 'MaplePrivacyLabs/Maple' &&
github.ref == 'refs/heads/master' &&
(github.event_name == 'push' || github.event_name == 'workflow_dispatch') &&
(needs.changes.result != 'success' || needs.changes.outputs.frontend != 'false' || needs.changes.outputs.ios != 'false')
runs-on: blacksmith-6vcpu-macos-26
# The ONNX source build and the app build each allow 90 minutes.
timeout-minutes: 240
permissions:
contents: read
id-token: write
attestations: write
artifact-metadata: write
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # was v4
with:
persist-credentials: false
- name: Select pinned Xcode
id: select_xcode
run: python3 scripts/ci/select-xcode.py
- name: Install Nix
uses: DeterminateSystems/determinate-nix-action@96c5ee93a9dddf2830d31e1da6ec719077336c28 # v3.23.3
with:
source-tag: v3.23.3
github-token: ""
- name: Verify pinned Nix runtime
run: bash scripts/ci/verify-nix-runtime.sh
- name: Cache Xcode DerivedData and SourcePackages
uses: irgaly/xcode-cache@4141f139f00e335c6e1031fb93e667181f86146f # was v1
with:
key: xcode-cache-ios-xcode${{ steps.select_xcode.outputs.version }}-${{ steps.select_xcode.outputs.build }}-${{ github.workflow }}-${{ hashFiles('apps/maple-research/frontend/src-tauri/Cargo.lock') }}
restore-keys: |
xcode-cache-ios-xcode${{ steps.select_xcode.outputs.version }}-${{ steps.select_xcode.outputs.build }}-${{ github.workflow }}-
xcode-cache-ios-xcode${{ steps.select_xcode.outputs.version }}-${{ steps.select_xcode.outputs.build }}-
- name: Cache ONNX Runtime iOS artifact
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # was v4
with:
path: |
apps/maple-research/frontend/src-tauri/onnxruntime-ios
key: release-onnxruntime-ios-artifact-1.23.2-xcode${{ steps.select_xcode.outputs.version }}-${{ steps.select_xcode.outputs.build }}-${{ hashFiles('flake.lock', 'flake.nix', 'scripts/ci/apple-toolchain.json', 'scripts/ci/select-xcode.py', 'scripts/ci/_common.sh', 'scripts/ci/ios-onnxruntime.sh', 'apps/maple-research/frontend/src-tauri/scripts/build-ios-onnxruntime-all.sh', 'apps/maple-research/frontend/src-tauri/scripts/canonicalize-static-archive.py', 'apps/maple-research/frontend/src-tauri/scripts/onnxruntime-pins.sh') }}
restore-keys: |
release-onnxruntime-ios-artifact-1.23.2-xcode${{ steps.select_xcode.outputs.version }}-${{ steps.select_xcode.outputs.build }}-
- name: Prepare ONNX Runtime iOS artifact
run: nix develop --no-update-lock-file .#apple -c ./scripts/ci/ios-onnxruntime.sh
timeout-minutes: 90
- name: Build Tauri iOS App (signed)
run: nix develop --no-update-lock-file .#apple -c ./scripts/ci/ios-release.sh
env:
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
APPLE_API_PRIVATE_KEY: ${{ secrets.APPLE_API_PRIVATE_KEY }}
APPLE_DEVELOPMENT_TEAM: ${{ secrets.APPLE_TEAM_ID }}
MAPLE_ENFORCE_IOS_SIGNED_REPRODUCIBILITY: "1"
timeout-minutes: 90
- name: Collect iOS release checksums
run: |
nix develop --no-update-lock-file .#apple -c ./scripts/ci/attestation-manifest.sh \
ios-release-artifacts.sha256 \
apps/maple-research/frontend/src-tauri/target/reproducibility/ios-release-final.sha256 \
apps/maple-research/frontend/src-tauri/target/reproducibility/ios-release-*.sha256 \
apps/maple-research/frontend/src-tauri/target/reproducibility/ios-release-*.txt \
apps/maple-research/frontend/src-tauri/target/reproducibility/ios-onnxruntime-*.sha256
cat ios-release-artifacts.sha256
- name: Attest iOS release artifacts
# Keep uploads/verifiers running if GitHub token policy rejects artifact attestation.
continue-on-error: true
uses: actions/attest@281a49d4cbb0a72c9575a50d18f6deb515a11deb # was v4
with:
subject-checksums: ios-release-artifacts.sha256
- name: Upload iOS App
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # was v4
with:
name: maple-ios
path: |
apps/maple-research/frontend/src-tauri/gen/apple/build/arm64/*.ipa
apps/maple-research/frontend/src-tauri/target/reproducibility/*.sha256
apps/maple-research/frontend/src-tauri/target/reproducibility/*.txt
retention-days: 5
verify-ios-artifacts:
needs: build-ios
runs-on: macos-26
timeout-minutes: 30
permissions:
contents: read
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # was v4
with:
persist-credentials: false
- name: Install Nix
uses: DeterminateSystems/determinate-nix-action@96c5ee93a9dddf2830d31e1da6ec719077336c28 # v3.23.3
with:
source-tag: v3.23.3
github-token: ""
- name: Verify pinned Nix runtime
run: bash scripts/ci/verify-nix-runtime.sh
- name: Download iOS artifacts
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # was v4
with:
name: maple-ios
path: artifacts
- name: Verify iOS artifact reproducibility proofs
run: nix develop --no-update-lock-file .#ci -c ./scripts/ci/verify-release-artifacts.sh artifacts ios
env:
MAPLE_ENFORCE_IOS_SIGNED_REPRODUCIBILITY: "1"
submit-ios-testflight:
environment: apple-signing
if: >-
github.repository == 'MaplePrivacyLabs/Maple' &&
github.ref == 'refs/heads/master' &&
(github.event_name == 'push' || github.event_name == 'workflow_dispatch')
needs: verify-ios-artifacts
runs-on: macos-26
timeout-minutes: 45
permissions:
contents: read
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # was v4
with:
ref: ${{ github.sha }}
persist-credentials: false
- name: Select pinned Xcode
run: python3 scripts/ci/select-xcode.py
- name: Download verified iOS artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # was v4
with:
name: maple-ios
path: artifacts
- name: Prepare App Store Connect API key
env:
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
APPLE_API_PRIVATE_KEY: ${{ secrets.APPLE_API_PRIVATE_KEY }}
run: |
set -euo pipefail
if [ -z "${APPLE_API_ISSUER}" ] || [ -z "${APPLE_API_KEY}" ] || [ -z "${APPLE_API_PRIVATE_KEY}" ]; then
echo "APPLE_API_ISSUER, APPLE_API_KEY, and APPLE_API_PRIVATE_KEY are required to submit to TestFlight." >&2
exit 1
fi
mkdir -p "${HOME}/.private_keys"
key_path="${HOME}/.private_keys/AuthKey_${APPLE_API_KEY}.p8"
if ! printf '%s' "${APPLE_API_PRIVATE_KEY}" | base64 --decode > "${key_path}" 2>/dev/null; then
printf '%s' "${APPLE_API_PRIVATE_KEY}" | base64 -D > "${key_path}"
fi
chmod 600 "${key_path}"
- name: Submit verified IPA to TestFlight
run: |
set -euo pipefail
IPA_PATH="$(find artifacts -name "*.ipa" | LC_ALL=C sort | head -n 1)"
if [ -z "${IPA_PATH}" ]; then
echo "No IPA found under downloaded artifacts" >&2
exit 1
fi
xcrun altool --upload-app --type ios \
--file "${IPA_PATH}" \
--apiKey "${{ secrets.APPLE_API_KEY }}" \
--apiIssuer "${{ secrets.APPLE_API_ISSUER }}"