# Nomarchy CI — eval + lint. # # Catches the regressions that hurt today: # 1. Flake stops evaluating (broken option ref, missing import, etc.). # 2. A `nomarchy-*` shell script has a syntax error or a shellcheck # error-severity issue. # 3. `docs/SCRIPTS.md` drifts from the repo state because somebody # added / removed / renamed a script and didn't run the generator # (the pre-commit hook handles this, but only when enabled per-clone). # 4. An opt-in nomarchy.* toggle stops evaluating. `nix flake check` # only evaluates the four default configs, so a bug that only fires # when a toggle is flipped sails through (e.g. the impermanence # systemd-stage-1 assertion). nomarchy-eval-matrix layers each toggle # onto the default config and forces system.build.toplevel. # # Doesn't build ISOs — that needs a binary cache. Add a separate job # once Cachix/Attic is in place. name: Check on: push: branches: [main] pull_request: jobs: eval-and-lint: runs-on: ubuntu-latest # Flakes for every `nix` invocation in the job (the bare `nix flake # check` below relies on this; the scripts pass the flag themselves). # sandbox=false because Stylix/base16.nix do import-from-derivation — # eval realizes fetched `-source` paths mid-check, and the single-user # Nix in this container can't set up the build sandbox (no user # namespaces), which otherwise surfaces as "path '…-source' is not # valid". NIX_SSL_CERT_FILE because we add nix to PATH without sourcing # the installer's profile (which is what normally exports it). env: NIX_CONFIG: | experimental-features = nix-command flakes sandbox = false NIX_SSL_CERT_FILE: /etc/ssl/certs/ca-certificates.crt steps: - name: Checkout uses: actions/checkout@v4 - name: Install Nix # Plain shell install rather than a JS action: act_runner's bundled # `act` only supports up to node20, and nix-installer-action@main # moved to node24 ("runs.using ... got node24"). A run step has no # node-runtime coupling. Single-user (--no-daemon) needs no systemd, # which the catthehacker container doesn't run as PID 1. # # The installer runs as root here and honours build-users-group= # nixbld from its bundled nix.conf, aborting unless that group exists # AND has members. Create the nixbld group + build users (what a # multi-user install does) before running it. # # Pin the Nix version: the latest (2.34) uses lazy-trees / a git # cache that doesn't materialise flake-input `-source` paths into # the store, so Stylix's import-from-derivation reads fail with # "path '…-source' is not valid". 2.31.5 matches the Nix that wrote # flake.lock locally and evaluates the flake cleanly. run: | NIX_VERSION=2.31.5 groupadd -r nixbld 2>/dev/null || true for i in $(seq 1 10); do useradd -r -g nixbld -G nixbld -d /var/empty \ -s /usr/sbin/nologin -c "Nix build user $i" "nixbld$i" 2>/dev/null || true done curl -L "https://releases.nixos.org/nix/nix-${NIX_VERSION}/install" | sh -s -- --no-daemon echo "$HOME/.nix-profile/bin" >> "$GITHUB_PATH" - name: Materialize flake inputs into the store # Nix keeps flake-input sources in a git cache and only materialises # the `-source` store paths lazily. Stylix/base16.nix do # import-from-derivation (readFile out of those sources) during eval, # which needs them as real store paths — on a cold CI store that # fails with "path '…-source' is not valid" (works locally only # because prior builds already materialised them). `flake archive` # copies every transitive input into the store up front. run: nix flake archive - name: nix flake check --no-build run: nix flake check --no-build - name: Evaluate opt-in toggle / palette / home matrix # flake check never flips a nomarchy.* toggle; this does. jq is # provided via nix shell so the step doesn't depend on the runner # image preinstalling it. run: nix shell nixpkgs#jq --command ./bin/utils/nomarchy-eval-matrix - name: Lint nomarchy-* scripts (bash -n + shellcheck) run: | # Mirror what .githooks/pre-commit runs locally, but across the # whole tree instead of just changed files. Pre-commit gates # individual commits; CI gates branches (including --no-verify # bypasses). set -e fail=0 while IFS= read -r script; do [[ -f "$script" ]] || continue # Python helpers ship under the same nomarchy- prefix # (e.g. nomarchy-haptic-touchpad). Skip non-bash. head -1 "$script" | grep -qE '^#!.*\bbash\b' || continue if ! bash -n "$script"; then echo "::error file=$script::bash syntax error" fail=1 fi if ! nix shell nixpkgs#shellcheck --command shellcheck \ --severity=error --shell=bash "$script"; then echo "::error file=$script::shellcheck error-severity issue" fail=1 fi done < <(find features/scripts/utils core/system/scripts \ themes/engine/scripts \ -maxdepth 1 -type f -name 'nomarchy-*') exit "$fail" - name: docs/SCRIPTS.md is up to date run: | # Regenerate to a temp file and compare. If different, the # contributor forgot to run the generator (or skipped the # pre-commit hook). Fail loudly and tell them the fix. ./bin/utils/nomarchy-docs-scripts --out /tmp/SCRIPTS.regen.md if ! diff -q docs/SCRIPTS.md /tmp/SCRIPTS.regen.md >/dev/null; then echo "::error::docs/SCRIPTS.md is stale." echo "Run: ./bin/utils/nomarchy-docs-scripts --out docs/SCRIPTS.md" echo "Then commit the regenerated file." echo "--- diff ---" diff -u docs/SCRIPTS.md /tmp/SCRIPTS.regen.md || true exit 1 fi - name: installer/hardware-db.sh references real nixos-hardware modules run: | # Every 4th-pipe-field in HARDWARE_DB is a nixos-hardware module # name. Half the DB used to point at modules that don't exist # (e.g. microsoft-surface-pro-8 — there's only -pro-intel and # -pro-9), which made the install fail at eval time with # cryptic "attribute not found" errors on real laptops. This # step catches that regression class. awk -F'|' '/^ "/ { gsub(/"/,"",$4); gsub(/^[[:space:]]+|[[:space:]]+$/,"",$4); if ($4) print $4 }' \ installer/hardware-db.sh | sort -u > /tmp/db-refs.txt nix eval --impure --json --expr ' let nh = (builtins.getFlake (toString ./.)).inputs.nixos-hardware.nixosModules; in builtins.attrNames nh' \ | nix shell nixpkgs#jq --command jq -r '.[]' | sort -u > /tmp/db-real.txt missing=$(comm -23 /tmp/db-refs.txt /tmp/db-real.txt) if [[ -n "$missing" ]]; then echo "::error::hardware-db.sh references nixos-hardware modules that don't exist:" printf ' - %s\n' $missing echo "Either fix the name (check the actual attr in nixos-hardware) or drop the row." exit 1 fi