Linux build (x86_64) #24
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
| name: Linux build (x86_64) | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| fast: | |
| description: "Use the Blacksmith fast runner (paid) instead of free GitHub-hosted" | |
| type: boolean | |
| default: false | |
| workflow_call: | |
| inputs: | |
| fast: | |
| type: boolean | |
| default: false | |
| jobs: | |
| build: | |
| runs-on: ${{ inputs.fast && 'blacksmith-16vcpu-ubuntu-2404' || 'ubuntu-24.04' }} | |
| timeout-minutes: 300 | |
| env: | |
| FF_VERSION: "152.0" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # Firefox's objdir is ~30GB; the runner ships ~14GB free on /. The Jun-13 | |
| # build stalled 34 min then SIGTERM (143) — disk exhaustion. Reclaim ~25GB | |
| # of preinstalled toolchains we don't use before anything else. | |
| - name: Free disk space | |
| if: ${{ !inputs.fast }} | |
| run: | | |
| sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc \ | |
| /opt/hostedtoolcache/CodeQL /usr/local/share/boost \ | |
| /usr/lib/jvm /usr/share/swift "${AGENT_TOOLSDIRECTORY:-/opt/hostedtoolcache}" || true | |
| sudo docker image prune --all --force || true | |
| df -h / | |
| - name: Install bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Install dependencies | |
| run: bun install | |
| - name: Install system deps | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| build-essential libgtk-3-dev libdbus-glib-1-dev \ | |
| libpulse-dev libasound2-dev libxt-dev \ | |
| libx11-xcb-dev libxcomposite-dev libxdamage-dev \ | |
| libxrandr-dev libxcursor-dev libxi-dev \ | |
| libcups2-dev libdrm-dev \ | |
| nasm yasm m4 unzip zip \ | |
| python3 python3-pip \ | |
| mercurial pkg-config nodejs | |
| - name: Maximize build space | |
| if: ${{ !inputs.fast }} | |
| run: | | |
| sudo swapoff -a | |
| sudo rm -f /swapfile | |
| sudo fallocate -l 16G /swapfile | |
| sudo chmod 600 /swapfile | |
| sudo mkswap /swapfile | |
| sudo swapon /swapfile | |
| sudo swapon --show | |
| - name: Download Firefox source | |
| run: | | |
| mkdir -p ~/.cache/gjoa/sources | |
| curl -L -o ~/.cache/gjoa/sources/firefox-${FF_VERSION}.source.tar.xz \ | |
| "https://archive.mozilla.org/pub/firefox/releases/${FF_VERSION}/source/firefox-${FF_VERSION}.source.tar.xz" | |
| ls -lh ~/.cache/gjoa/sources/firefox-${FF_VERSION}.source.tar.xz | |
| # F9 hardening: verify the downloaded tarball against the IN-REPO pinned | |
| # SHA-256 (configs/firefox-${FF_VERSION}.sha256) BEFORE extracting. The | |
| # pin is committed + reviewed, so unlike a same-origin SHA256SUMS it can't | |
| # be swapped by an origin/TLS compromise. Compare the computed hash to the | |
| # pinned value (first field of the pin file) — path-independent. | |
| - name: Verify tarball checksum (pinned) | |
| run: | | |
| PIN="configs/firefox-${FF_VERSION}.sha256" | |
| test -f "$PIN" || { echo "missing pinned checksum: $PIN"; exit 1; } | |
| expected=$(grep -v '^#' "$PIN" | awk 'NF{print $1; exit}') | |
| actual=$(sha256sum ~/.cache/gjoa/sources/firefox-${FF_VERSION}.source.tar.xz | awk '{print $1}') | |
| echo "expected: $expected" | |
| echo "actual: $actual" | |
| if [ "$expected" != "$actual" ]; then | |
| echo "::error::Firefox tarball SHA-256 does not match pinned value in $PIN" | |
| exit 1 | |
| fi | |
| echo "tarball checksum OK (matches pinned $PIN)" | |
| - name: Extract source | |
| run: | | |
| mkdir -p engine | |
| tar -xJf ~/.cache/gjoa/sources/firefox-${FF_VERSION}.source.tar.xz -C engine --strip-components=1 | |
| # gjoa's build tooling is written in beagle (a Racket compiler), invoked | |
| # as a sibling at ../beagle. CI only checks out gjoa, so without these two | |
| # steps `bun run import` dies with "../beagle/bin/beagle-build: No such | |
| # file or directory" (exit 127). beagle-build runs standalone with just | |
| # Racket + the repo (no raco-pkg-install / direnv setup needed). | |
| - name: Install Racket (beagle compiler runtime) | |
| uses: Bogdanp/setup-racket@v1.15 | |
| with: | |
| version: 'stable' | |
| - name: Checkout beagle (sibling compiler) | |
| run: git clone --depth 1 https://github.com/tompassarelli/beagle.git ../beagle | |
| # beagle-build resolves modules from the 'beagle' Racket collection, which | |
| # is provided by beagle-lib (info.rkt: collection "beagle", deps just base). | |
| # Register it as a linked package so `(require beagle/...)` resolves. | |
| - name: Register beagle collection | |
| run: raco pkg install --link --batch --no-docs ../beagle/beagle-lib | |
| - name: Apply overlays and patches | |
| run: bun run import | |
| - name: Write mozconfig | |
| run: | | |
| cat > engine/mozconfig <<'MOZCONFIG' | |
| ac_add_options --with-branding=browser/branding/gjoa | |
| ac_add_options --with-distribution-id=org.gjoa | |
| ac_add_options --with-app-name=gjoa | |
| ac_add_options --with-app-basename=Gjoa | |
| ac_add_options --without-wasm-sandboxed-libraries | |
| ac_add_options --disable-updater | |
| ac_add_options --disable-tests | |
| ac_add_options --enable-optimize | |
| ac_add_options --enable-release | |
| # Debug symbols dominate link-time RAM, objdir size, and final binary | |
| # size. A distribution build doesn't need them — dropping them is what | |
| # keeps the link inside the runner's memory + disk envelope. (lld is the | |
| # toolchain's default linker on clang/Linux, so it's used without a flag.) | |
| ac_add_options --disable-debug-symbols | |
| MOZCONFIG | |
| sed -i 's/^ //' engine/mozconfig | |
| cat engine/mozconfig | |
| - name: Bootstrap mach | |
| working-directory: engine | |
| run: | | |
| export MOZBUILD_STATE_PATH="$HOME/.mozbuild" | |
| echo 1 | ./mach bootstrap --application-choice=browser 2>&1 || true | |
| - name: Build | |
| working-directory: engine | |
| run: ./mach build -j${{ inputs.fast && '16' || '2' }} | |
| # Dark-mode contrast verification — runs the WCAG-AA harness against the | |
| # freshly-built binary in a clean xvfb env (the agent shell can't launch the | |
| # browser). NON-FATAL + time-bounded: baselines are record-only and an infra | |
| # hiccup must never red the build; the per-fixture scores land in the | |
| # uploaded contrast-results.log regardless. | |
| - name: Dark-mode contrast verification (non-fatal) | |
| run: | | |
| sudo apt-get install -y xvfb >/dev/null 2>&1 || true | |
| bun tools/test-driver/contrast-fixture-server.mjs > /tmp/fix.log 2>&1 & | |
| sleep 2 | |
| GJOA_BIN="$PWD/engine/obj-x86_64-pc-linux-gnu/dist/bin/gjoa" \ | |
| timeout 600 xvfb-run -a bun run test:contrast > contrast-results.log 2>&1 || true | |
| echo "=== dark-mode contrast scores ===" | |
| grep "\[contrast\]" contrast-results.log || echo "(no scores captured — see contrast-results.log artifact)" | |
| - name: Upload contrast results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: contrast-results | |
| path: contrast-results.log | |
| if-no-files-found: warn | |
| - name: Package | |
| working-directory: engine | |
| run: ./mach package | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: gjoa-linux-x86_64 | |
| # mach packages Linux as .tar.xz (not .bz2). Match any tarball, and | |
| # FAIL if none is found — a silent `warn` produced a green build with | |
| # no artifact, which is worse than a red build. | |
| path: engine/obj-*/dist/gjoa-*.tar.* | |
| if-no-files-found: error |