Skip to content

Linux build (x86_64) #24

Linux build (x86_64)

Linux build (x86_64) #24

Workflow file for this run

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