fix(s001): assets.deploy did not compile first, so it failed on every… #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # SPDX-FileCopyrightText: Sudo Apt Holdings LLC | |
| # SPDX-License-Identifier: Apache-2.0 | |
| # | |
| # Slice 001 lines 9 and 10. This workflow builds the packaged binary on three operating | |
| # systems and smokes it. What it proves and what it cannot are written out in | |
| # docs/packaging.md and repeated by each job in its own summary, because an artifact from a | |
| # runner is easy to mistake for evidence of something it is not. | |
| # | |
| # A runner has no desktop session. No job here opens a window, and none claims to. | |
| name: package | |
| # Corrected 2026-09-06, before this workflow had ever run. The push trigger was | |
| # `branches: [main]`, so the one branch whose evidence depends on it — the slice branch — was | |
| # the one branch it ignored, and pushing slice 001 produced no package run at all. Slice | |
| # branches are where a packaging change is proven; main is where it has already been proven. | |
| on: | |
| push: | |
| branches: [main, 'slice/**'] | |
| pull_request: | |
| workflow_dispatch: | |
| jobs: | |
| package: | |
| name: ${{ matrix.name }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - name: linux x86_64 | |
| os: ubuntu-latest | |
| target: linux_x86_64 | |
| artifact: desktop_linux_x86_64 | |
| - name: macOS aarch64 | |
| os: macos-latest | |
| target: macos_aarch64 | |
| artifact: desktop_macos_aarch64 | |
| - name: windows x86_64 | |
| os: windows-latest | |
| target: windows_x86_64 | |
| artifact: desktop_windows_x86_64.exe | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: erlef/setup-beam@v1 | |
| with: | |
| version-file: .tool-versions | |
| version-type: strict | |
| # The Zig version is read from .tool-versions rather than written here. Burrito 1.6.0 | |
| # compares Zig for equality, not a range, so a second copy of the number in this file | |
| # would be a second thing to keep in step, and the one that drifts is always the copy. | |
| - name: Read the pinned Zig version from .tool-versions | |
| id: zig | |
| shell: bash | |
| run: echo "version=$(awk '$1=="zig"{print $2}' .tool-versions)" >> "$GITHUB_OUTPUT" | |
| - uses: mlugg/setup-zig@v2 | |
| with: | |
| version: ${{ steps.zig.outputs.version }} | |
| - name: Confirm the toolchain is the pinned one | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| zig version | |
| test "$(zig version)" = "${{ steps.zig.outputs.version }}" | |
| elixir --version | |
| - run: mix deps.get | |
| # config/prod.exs sets cache_static_manifest; the endpoint raises at boot without it. | |
| - run: mix assets.deploy | |
| # --overwrite is not optional. Without it, and with a release directory already | |
| # present, mix release prompts, gets no stdin, and exits 0 having built nothing. | |
| - name: Build the Burrito binary | |
| shell: bash | |
| env: | |
| BURRITO_TARGET: ${{ matrix.target }} | |
| MIX_ENV: prod | |
| run: mix release desktop --overwrite | |
| - name: The artifact exists and is not empty | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| ls -l burrito_out/ | |
| test -s "burrito_out/${{ matrix.artifact }}" | |
| # --no-halt is what makes the exit mean anything. Burrito launches the release as | |
| # `-s elixir start_cli`, and the Elixir CLI halts when its command list is empty, so | |
| # without --no-halt the binary exits 0 on its own and `--smoke` proves nothing. | |
| - name: Smoke — boots, serves, exits by itself, leaves nothing behind | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| ps -eo pid,ppid,comm > ps-before.txt | |
| chmod +x "burrito_out/${{ matrix.artifact }}" | |
| "./burrito_out/${{ matrix.artifact }}" --no-halt --smoke | tee smoke.log | |
| sleep 3 | |
| ps -eo pid,ppid,comm > ps-after.txt | |
| grep -q '^TRINITY_SMOKE_PORT=[0-9][0-9]*$' smoke.log | |
| diff ps-before.txt ps-after.txt | |
| - name: Smoke — Windows | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| & ".\burrito_out\${{ matrix.artifact }}" --no-halt --smoke | Tee-Object smoke.log | |
| if ($LASTEXITCODE -ne 0) { throw "smoke exited $LASTEXITCODE" } | |
| if (-not (Select-String -Path smoke.log -Pattern '^TRINITY_SMOKE_PORT=\d+$')) { | |
| throw "no port line" | |
| } | |
| # AC1's property, on a runner: the binary does not merely start, it serves. | |
| - name: Serves HTTP 200 | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| PHX_SERVER=true "./burrito_out/${{ matrix.artifact }}" --no-halt > serve.log 2>&1 & | |
| PID=$! | |
| for _ in $(seq 1 120); do | |
| PORT=$(grep -o '127\.0\.0\.1:[0-9]*' serve.log | head -1 | cut -d: -f2 || true) | |
| [ -n "${PORT:-}" ] && break | |
| sleep 0.5 | |
| done | |
| test -n "${PORT:-}" | |
| code=$(curl -sS -o /dev/null -w '%{http_code}' --retry 10 --retry-all-errors "http://127.0.0.1:$PORT/") | |
| echo "HTTP $code on port $PORT" | |
| test "$code" = "200" | |
| CHILD=$(pgrep -P "$PID" || true) | |
| kill "$PID" || true | |
| # The wrapper does not forward termination to the BEAM it launched — measured at | |
| # slice 001 line 5, and the reason AC8's property is not currently true. Kill the | |
| # child explicitly or the runner leaves it behind. | |
| [ -n "$CHILD" ] && kill "$CHILD" || true | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: burrito_out/${{ matrix.artifact }} | |
| if-no-files-found: error | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: launch-log-${{ matrix.target }} | |
| path: | | |
| smoke.log | |
| serve.log | |
| if-no-files-found: warn | |
| # Line 10. Each job states, in its own summary, which of the two things it did — and | |
| # every job here did the second one. | |
| - name: State what this job did not prove | |
| if: always() | |
| shell: bash | |
| run: | | |
| { | |
| echo "## ${{ matrix.name }} — what this run does and does not establish" | |
| echo | |
| echo "**Established:** the artifact builds on ${{ matrix.os }}; it launches and" | |
| echo "reaches serving; under \`--no-halt --smoke\` it exits by itself and the" | |
| echo "process list is unchanged either side; the launch log is attached." | |
| echo | |
| echo "**Not established, and not claimed:** no native window was opened." | |
| echo "This job smoked the **sidecar alone, with no display** — it did not run the" | |
| echo "shell under \`xvfb-run\` and it did not use a desktop session, because this" | |
| echo "runner has none. No screenshot exists. First paint was not measured." | |
| echo "Nothing here speaks to signing or notarisation." | |
| } >> "$GITHUB_STEP_SUMMARY" |