From 3de946b7d4d323c7ff1a6cca8bf899004a53827f Mon Sep 17 00:00:00 2001 From: "Evgeny @ SimpleX Chat" <259188159+evgeny-simplex@users.noreply.github.com> Date: Mon, 26 Oct 2026 18:19:24 +0000 Subject: [PATCH] ci: upload app builds for manual tests (#7880) --- .github/workflows/android-emu.yml | 4 ++-- .github/workflows/desktop-linux.yml | 8 ++++---- .github/workflows/ios-sim.yml | 6 ++---- scripts/ci/README.md | 4 +++- scripts/ci/android/README.md | 2 +- scripts/ci/desktop-linux/README.md | 2 +- scripts/ci/ios-sim/README.md | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/android-emu.yml b/.github/workflows/android-emu.yml index 3bc26a5a50..f8512aeda9 100644 --- a/.github/workflows/android-emu.yml +++ b/.github/workflows/android-emu.yml @@ -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 diff --git a/.github/workflows/desktop-linux.yml b/.github/workflows/desktop-linux.yml index 82725791f5..ce5a1c7922 100644 --- a/.github/workflows/desktop-linux.yml +++ b/.github/workflows/desktop-linux.yml @@ -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 diff --git a/.github/workflows/ios-sim.yml b/.github/workflows/ios-sim.yml index 08502674d9..b6477018e9 100644 --- a/.github/workflows/ios-sim.yml +++ b/.github/workflows/ios-sim.yml @@ -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 diff --git a/scripts/ci/README.md b/scripts/ci/README.md index 5b5e6d4351..a8cb147b01 100644 --- a/scripts/ci/README.md +++ b/scripts/ci/README.md @@ -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 -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 -n ` downloads it. + ## How long a run takes | Run | iOS | Desktop | Android | diff --git a/scripts/ci/android/README.md b/scripts/ci/android/README.md index 106a147a22..ceac2a1b08 100644 --- a/scripts/ci/android/README.md +++ b/scripts/ci/android/README.md @@ -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 diff --git a/scripts/ci/desktop-linux/README.md b/scripts/ci/desktop-linux/README.md index 918e0d68ce..90143005e8 100644 --- a/scripts/ci/desktop-linux/README.md +++ b/scripts/ci/desktop-linux/README.md @@ -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 diff --git a/scripts/ci/ios-sim/README.md b/scripts/ci/ios-sim/README.md index c79acfaa59..6bc7d673e4 100644 --- a/scripts/ci/ios-sim/README.md +++ b/scripts/ci/ios-sim/README.md @@ -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.