From 11da1069ae5cde93150d817cd94c47506b28bafc Mon Sep 17 00:00:00 2001 From: Justin Scroggins Date: Wed, 11 Nov 2026 13:26:05 -0500 Subject: [PATCH 1/2] Release the Mac app from CI's build, and keep pull requests off the scarce macOS runners The release rebuilt the macOS app from scratch every time: reuse-binaries.sh looked for a tinyclient.app folder, but upload-artifact keeps only what is inside the folder it is given, so the download is Contents/ alone. v0.2.66's macOS job spent 13 of its 14 minutes compiling what CI had already built. It now looks for Contents/MacOS, as Windows and Linux already reuse. The org gets two macOS runners at a time, shared by CI's tests and package, the iOS build and the release; v0.2.66's iOS build waited 24 minutes for one. A pull request now tests on Linux and Windows only, and main adds macOS. The window's tests, which build only with the gui feature, run on Linux for a pull request so they are not lost with the Mac. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 20 ++++++++++++-------- packaging/ci/reuse-binaries.sh | 8 +++++--- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fa368c52..ae09dc49 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,13 +34,17 @@ jobs: name: test (${{ matrix.os }}) strategy: fail-fast: false + # macOS runners are the scarce ones: two at a time, shared with the phone builds and the + # release. A pull request tests on Linux and Windows and main adds macOS, so a break only a + # Mac shows is found on main, before the release it would ship in. matrix: - os: [ubuntu-22.04, macos-latest, windows-latest] - include: - - os: macos-latest - features: --features tinyclient/gui + os: ${{ fromJSON(github.event_name == 'push' && '["ubuntu-22.04","macos-latest","windows-latest"]' || '["ubuntu-22.04","windows-latest"]') }} runs-on: ${{ matrix.os }} timeout-minutes: 60 + # The window's own tests build only with the gui feature. macOS runs them on main; with no + # Mac on a pull request, Linux does. + env: + FEATURES: ${{ (matrix.os == 'macos-latest' || (matrix.os == 'ubuntu-22.04' && github.event_name == 'pull_request')) && '--features tinyclient/gui' || '' }} steps: - uses: actions/checkout@v5 - uses: ./.github/actions/setup-rust @@ -49,20 +53,20 @@ jobs: - uses: taiki-e/install-action@nextest # nextest runs the test binaries side by side, where `cargo test` ran them one at a time. # The window's own tests (prefs, search, shortcuts against the menus, the controls) build - # only with the gui feature, so macOS turns it on for the one pass over the workspace. + # only with the gui feature, which FEATURES turns on for the one pass over the workspace. # Tests use the real media engine. Building it inside each nextest process repeats # Cargo resolution and serializes tests on its build lock (five minutes on a cold Mac). # Use the whole workspace graph so tests and the engine share dependency features. - name: Build test programs shell: bash run: | - cargo build --workspace --all-targets ${{ matrix.features }} --timings + cargo build --workspace --all-targets ${{ env.FEATURES }} --timings echo "TINYCLIENT_TEST_MEDIAD=$GITHUB_WORKSPACE/target/debug/mediad${{ runner.os == 'Windows' && '.exe' || '' }}" >> "$GITHUB_ENV" - name: Test - run: cargo nextest run --workspace ${{ matrix.features }} + run: cargo nextest run --workspace ${{ env.FEATURES }} # nextest does not run doc tests. - name: Doc tests - run: cargo test --workspace --doc ${{ matrix.features }} + run: cargo test --workspace --doc ${{ env.FEATURES }} # The cfg(target_os = "ios"|"android") arms are not type-checked on this host; this proves # the mobile feature does not disturb the desktop arms. It shares this job's cache. - name: Window with the mobile feature enabled diff --git a/packaging/ci/reuse-binaries.sh b/packaging/ci/reuse-binaries.sh index b034e5d9..79d3459a 100755 --- a/packaging/ci/reuse-binaries.sh +++ b/packaging/ci/reuse-binaries.sh @@ -27,10 +27,12 @@ take() { mkdir -p target/release case "$kind" in macos) - app=$(find "$stage" -type d -name 'tinyclient.app' | head -1) - [ -n "$app" ] || return 1 + # CI uploads target/release/tinyclient.app as a directory, and upload-artifact keeps + # what is inside it: the download is Contents/ with no tinyclient.app around it. + macos=$(find "$stage" -type d -path '*/Contents/MacOS' | head -1) + [ -n "$macos" ] || return 1 for program in $programs; do - cp "$app/Contents/MacOS/$program" "target/release/$program" + cp "$macos/$program" "target/release/$program" chmod +x "target/release/$program" done ;; From 0bab18e5cc475b8da6d50953d4121dd25ec0d098 Mon Sep 17 00:00:00 2001 From: Justin Scroggins Date: Wed, 11 Nov 2026 13:51:40 -0500 Subject: [PATCH 2/2] Build Linux tests with the gui feature on main too, so pull requests restore a warm cache Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae09dc49..72e546e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,10 +41,12 @@ jobs: os: ${{ fromJSON(github.event_name == 'push' && '["ubuntu-22.04","macos-latest","windows-latest"]' || '["ubuntu-22.04","windows-latest"]') }} runs-on: ${{ matrix.os }} timeout-minutes: 60 - # The window's own tests build only with the gui feature. macOS runs them on main; with no - # Mac on a pull request, Linux does. + # The window's own tests build only with the gui feature. Linux runs them everywhere, since a + # pull request has no Mac, and on main too: main writes the cache a pull request restores, + # and a Linux build without the feature left every pull request compiling it cold (17 + # minutes, not 1.5). env: - FEATURES: ${{ (matrix.os == 'macos-latest' || (matrix.os == 'ubuntu-22.04' && github.event_name == 'pull_request')) && '--features tinyclient/gui' || '' }} + FEATURES: ${{ matrix.os != 'windows-latest' && '--features tinyclient/gui' || '' }} steps: - uses: actions/checkout@v5 - uses: ./.github/actions/setup-rust