ci: upload app builds for manual tests (#7880)

This commit is contained in:
Evgeny @ SimpleX Chat authored and GitHub committed 2026-10-26 18:19:24 +00:00
1 parent a0730ae8b8
commit 3de946b7d4
7 files changed
+14 -14

No files matched your search

+2 -2
View File
@@ -250,13 +250,13 @@ jobs:
unzip -l "$RUNNER_TEMP/apk/$APK" | grep -E ' lib/'
- name: Upload app
if: ${{ !cancelled() && steps.build.outcome == 'success' && needs.plan.outputs.run-claude == 'true' }}
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
uses: actions/upload-artifact@v7
with:
name: android-app
path: ${{ runner.temp }}/apk/${{ env.APK }}
compression-level: 0
retention-days: 1
retention-days: 14
if-no-files-found: error
- name: Install emulator and system image
+4 -4
View File
@@ -253,19 +253,19 @@ jobs:
du -sh "$app"
LD_LIBRARY_PATH="$app/lib/app/resources" ldd "$app/lib/app/resources/libapp-lib.so"
# for the Claude job; a tarball keeps the app's file modes, which an artifact drops
# a tarball keeps the app's file modes, which an artifact drops
- name: Pack app
if: ${{ !cancelled() && steps.build.outcome == 'success' && needs.plan.outputs.run-claude == 'true' }}
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
run: tar -czf "$RUNNER_TEMP/desktop-app.tar.gz" -C apps/multiplatform/release/main/app simplex
- name: Upload app
if: ${{ !cancelled() && steps.build.outcome == 'success' && needs.plan.outputs.run-claude == 'true' }}
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
uses: actions/upload-artifact@v7
with:
name: desktop-app
path: ${{ runner.temp }}/desktop-app.tar.gz
compression-level: 0
retention-days: 1
retention-days: 14
if-no-files-found: error
- name: Run desktop tests
+2 -4
View File
@@ -249,19 +249,17 @@ jobs:
DEVELOPMENT_TEAM= \
PROVISIONING_PROFILE_SPECIFIER=
# for the Claude job; a tarball keeps the app's file modes, which an artifact drops
# a tarball keeps the app's file modes, which an artifact drops
- name: Pack app
if: needs.plan.outputs.run-claude == 'true'
run: tar -czf "$RUNNER_TEMP/SimpleX.app.tar.gz" -C "$RUNNER_TEMP/DerivedData/Build/Products/Debug-iphonesimulator" SimpleX.app
- name: Upload app
if: needs.plan.outputs.run-claude == 'true'
uses: actions/upload-artifact@v7
with:
name: ios-sim-app
path: ${{ runner.temp }}/SimpleX.app.tar.gz
compression-level: 0
retention-days: 1
retention-days: 14
if-no-files-found: error
- name: Install AXe
+3 -1
View File
@@ -150,7 +150,7 @@ Pushes start none of the app workflows: a run is started by hand, on any branch,
| Input | iOS | Desktop | Android |
|---|---|---|---|
| no input | scripted test | scripted test | scripted test |
| no input | scripted test, the app uploaded | scripted test, the app uploaded | scripted test, the app uploaded |
| `claude` | scripted test, then Claude | scripted test, then Claude | scripted test, then Claude |
| `backend` | also the test backend | also the test backend | also the test backend |
| `release` | — | also the latest release's onboarding, to tell a branch's failure from the runner's | also the latest release's onboarding, to tell a branch's failure from the runner's |
@@ -166,6 +166,8 @@ gh workflow run android-emu.yml --ref <branch> -f claude=true
A newer run of a workflow on the same branch cancels the older one.
Each run uploads the app it built, for manual tests, as an artifact kept 14 days: `ios-sim-app` (SimpleX.app.tar.gz, for the iOS simulator on an Apple-silicon Mac), `desktop-app` (desktop-app.tar.gz, for Linux x86-64) and `android-app` (the debug APK, arm64-v8a only). The run's page lists it under Artifacts; `gh run download <run id> -n <artifact>` downloads it.
## How long a run takes
| Run | iOS | Desktop | Android |
+1 -1
View File
@@ -19,7 +19,7 @@ Every run builds the core library, and the backend when it's asked for, from the
| `backend` (opt-in) | desktop-linux's `build-backend.sh` | about 30 min, skipped when reused |
| `release` (opt-in) | the latest release's arm64 APK, its signer checked against SimpleX's key, onboarding only | about 4 min |
Results are artifacts: `android-smoke-test` (numbered screenshots, the accessibility tree and the text of each, `steps.log`, `checks.txt`, logcat as `app.log`, `emulator.log`), `android-release-smoke-test`, `android-claude-test`, and the backend's logs; `android-app`, the APK for the Claude job, is kept a day. The job summaries list the checks and the Claude usage.
Results are artifacts: `android-smoke-test` (numbered screenshots, the accessibility tree and the text of each, `steps.log`, `checks.txt`, logcat as `app.log`, `emulator.log`), `android-release-smoke-test`, `android-claude-test`, and the backend's logs; `android-app`, the APK for manual tests and the Claude job, is kept 14 days. The job summaries list the checks and the Claude usage.
## The emulator
+1 -1
View File
@@ -19,7 +19,7 @@ Every run builds the core library, and the backend when it's asked for, from the
| `backend` (opt-in) | `build-backend.sh`: `simplex-chat`, `simplex-directory-service`, and `smp-server` from the simplexmq commit `cabal.project` pins | about 30 min, skipped when reused |
| `release` (opt-in) | the latest release's .deb for this Ubuntu, onboarding only, to tell a branch's failure from the runner's | 1.5 min |
Queueing for a runner adds from under a minute to 20 minutes. Results are artifacts: `desktop-smoke-test` (numbered screenshots, the text OCR read from each, `steps.log`, `checks.txt`, `app.log`), `desktop-test-report`, `desktop-claude-test`, and the backend's logs; `desktop-app`, the distributable for the Claude job, is kept a day. The job summaries list the checks, the desktopTest results and the Claude usage.
Queueing for a runner adds from under a minute to 20 minutes. Results are artifacts: `desktop-smoke-test` (numbered screenshots, the text OCR read from each, `steps.log`, `checks.txt`, `app.log`), `desktop-test-report`, `desktop-claude-test`, and the backend's logs; `desktop-app`, the distributable for manual tests and the Claude job, is kept 14 days. The job summaries list the checks, the desktopTest results and the Claude usage.
## Scripts
+1 -1
View File
@@ -22,7 +22,7 @@ The macOS jobs run on `macos-26`, the image with Xcode 26 and the iPhone 17 simu
## The Claude session
It runs in its own job, `claude`, once the app job has passed: the job installs that job's build (the artifact `ios-sim-app`, kept a day) in a new simulator, runs the smoke test to reach the sessions' starting state, then one session per layout listed in `claude-scope`, with Claude Code installed from npm at the version the desktop workflow pins too. Only this job references the environment `app-sim-claude`, which holds the secret `CLAUDE_CODE_OAUTH_TOKEN` (a Claude subscription token) and admits the branches its rule allows; one runs per branch at a time. Only the Claude step gets the token, and `claude-test.sh` passes it to the `claude` processes alone. The job checks out without persisting its GitHub token and installs a pinned AXe (`install-axe.sh`), since it holds the Claude token. It starts the test backend when `claude-scope` says `backend: yes`; a run that asks for Claude must then ask for the backend too, or the plan job fails. On master it says `no`, since the smoke plan doesn't use the backend.
It runs in its own job, `claude`, once the app job has passed: the job installs that job's build (the artifact `ios-sim-app`, kept 14 days) in a new simulator, runs the smoke test to reach the sessions' starting state, then one session per layout listed in `claude-scope`, with Claude Code installed from npm at the version the desktop workflow pins too. Only this job references the environment `app-sim-claude`, which holds the secret `CLAUDE_CODE_OAUTH_TOKEN` (a Claude subscription token) and admits the branches its rule allows; one runs per branch at a time. Only the Claude step gets the token, and `claude-test.sh` passes it to the `claude` processes alone. The job checks out without persisting its GitHub token and installs a pinned AXe (`install-axe.sh`), since it holds the Claude token. It starts the test backend when `claude-scope` says `backend: yes`; a run that asks for Claude must then ask for the backend too, or the plan job fails. On master it says `no`, since the smoke plan doesn't use the backend.
Each session's final message ends with `CLAUDE-TEST: PASS`, or `CLAUDE-TEST: FAIL` and the failed cases; the step fails unless every session passes.