Skip to content

fix(checks): anchor the shared-texture teardown check on the function… #145

fix(checks): anchor the shared-texture teardown check on the function…

fix(checks): anchor the shared-texture teardown check on the function… #145

Workflow file for this run

# Canonical CI workflow — Nix Packaging Standard.
# Source of truth: github:Daaboulex/nix-packaging-standard. Synced into each
# packaging repo by sync.sh; its byte-identity is then enforced by the
# `std-conformance` flake check (flakeModules.base), so it cannot drift.
#
# Archetype-blind by design: this file knows nothing about what kind of repo
# it runs in. It builds every output the flake declares for the runner's
# system (`nix-fast-build` over `.#checks.<system>`, which includes every
# package aliased in by flakeModules.base, the git-hooks lint/format check,
# the conformance + schema checks, and any repo-specific smoke check).
# Per-arch native runners: declared == built (a flake that declares no
# outputs for an arch simply no-ops on that runner).
name: CI
on:
push:
branches: [main, master]
pull_request:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
no-tracked-ignored-files:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Fail if a tracked file is gitignored
run: |
set -eu
tracked_ignored=$(git ls-files -i -c --exclude-per-directory=.gitignore)
if [ -n "$tracked_ignored" ]; then
echo "::error::These tracked files match .gitignore and must not be committed:"
printf '%s\n' "$tracked_ignored" | while IFS= read -r f; do echo " - $f"; done
exit 1
fi
echo "Clean -- no tracked file is gitignored."
build:
needs: no-tracked-ignored-files
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: DeterminateSystems/determinate-nix-action@61cbfe2efc2d4e7a8a6d56967c3c1058e846c858 # v3.21.9
with:
extra-conf: |
lazy-trees = false
keep-outputs = true
keep-derivations = true
- name: Cache the Nix store
id: nix-cache
uses: nix-community/cache-nix-action@7df957e333c1e5da7721f60227dbba6d06080569 # v7.0.2
with:
primary-key: nix-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/flake.lock', '**/*.nix') }}
restore-prefixes-first-match: nix-${{ runner.os }}-${{ runner.arch }}-
gc-max-store-size-linux: 8G
purge: true
purge-prefixes: nix-${{ runner.os }}-${{ runner.arch }}-
purge-last-accessed: P1DT12H
purge-primary-key: never
# Large source builds (mesa, portmaster, scx) can exhaust the runner's
# ~14 GB default disk mid-build ("No space left on device"). Drop
# preinstalled toolchains nix never uses to reclaim ~20 GB. Best-effort:
# `|| true` so it never fails the job, and paths absent on a given runner
# (e.g. the arm image) are simply skipped.
- name: Reclaim runner disk
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc \
/opt/hostedtoolcache/CodeQL /usr/local/.ghcup || true
sudo docker image prune --all --force >/dev/null 2>&1 || true
df -h /
- name: Flag a build-the-world bump
if: steps.nix-cache.outputs.restored-key != ''
run: |
SYS=$(nix eval --impure --raw --expr 'builtins.currentSystem')
nix eval ".#checks.$SYS" --apply 'x: builtins.attrNames x != [ ]' 2>/dev/null | grep -qx true || exit 0
mapfile -t D < <(nix run --inputs-from . nixpkgs#nix-eval-jobs -- --flake ".#checks.$SYS" 2>/dev/null | jq -r '.drvPath')
[ ${#D[@]} -eq 0 ] && exit 0
B=$(nix build "${D[@]/%/^*}" --dry-run --narinfo-cache-negative-ttl 0 2>&1 | sed -n 's/^these \([0-9]\+\) derivations will be built.*/\1/p')
B=${B:-0}
echo "will build from source this run: $B"
if [ "$B" -gt 5000 ]; then
echo "::error::$B derivations would build from source -- a flake.lock bump moved far ahead of cache.nixos.org (runaway that would risk the 6h timeout). Investigate the lock, or wait for cache.nixos.org to catch up, before rerunning."
exit 1
elif [ "$B" -gt 500 ]; then
echo "::warning::$B derivations build from source -- a flake.lock bump moved ahead of cache.nixos.org. The store cache absorbs it after this run."
fi
- name: Build + check every output declared for this system
run: |
SYS=$(nix eval --impure --raw --expr 'builtins.currentSystem')
if ! nix eval ".#checks.$SYS" --apply 'x: builtins.attrNames x != [ ]' 2>/dev/null | grep -qx true; then
echo "Flake declares no checks for $SYS — skipping (declared == built)."
exit 0
fi
# Substitution (cache.nixos.org) reuses every unmodified path for free;
# --skip-cached builds ONLY what no substituter already has.
build() {
nix run --inputs-from . nixpkgs#nix-fast-build -- --skip-cached --no-nom --flake ".#checks.$SYS" 2>&1 | tee /tmp/build.log
return "${PIPESTATUS[0]}"
}
# A genuine compile failure fails fast. Transient EXTERNAL-fetch failures
# — crates.io rate-limiting bulk crate pulls (403/429), or a registry/CDN
# blip — are retried ONCE after a backoff so the rate-limit window passes.
# The marker grep keeps real build bugs from being silently retried.
if ! build; then
if grep -qiE 'crates\.io|error: cannot download|status code: (403|429)|curl: \(|couldn.t resolve host|connection reset by peer|temporary failure in name resolution|operation timed out' /tmp/build.log; then
echo "::warning::Transient external-fetch failure (likely crates.io rate-limit); retrying once in 60s."
sleep 60
build || { echo "::error::Build failed after transient-fetch retry."; exit 1; }
else
echo "::error::Build failed (no transient-fetch marker — not retrying)."
exit 1
fi
fi