Skip to content

fix(s001): assets.deploy did not compile first, so it failed on every… #2

fix(s001): assets.deploy did not compile first, so it failed on every…

fix(s001): assets.deploy did not compile first, so it failed on every… #2

Workflow file for this run

# 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"