fix(checks): anchor the shared-texture teardown check on the function… #145
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
| # 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 |