# Nomarchy scheduled lock bump — the automated half of "rock-stable
# without rotting": once a week, update flake.lock (inputs track pinned
# release branches, so this never jumps a NixOS release — that's a
# deliberate hand-edited v2, see agent/GOALS.md), gate it, and land it
# on main only on green. `v1` promotion stays human, always.
#
# Fast lane: workflow_dispatch. For a security fix upstream, run this
# workflow manually from the Actions tab instead of waiting for Monday.
#
# Gate scope: `nix flake check --no-build` (eval tier) followed by a V1 build
# (home-manager activation package + nixos toplevel) to catch compilation errors.
# (this runner has no KVM; see item 20 for the VM-suite
# upgrade path). The py_compile/bash -n steps are skipped on purpose:
# they don't read flake.lock, so a lock bump cannot break them. The
# bump commit's own push then triggers check.yml as a second net.
# A green bump therefore guards evaluation and compilation, not VM behaviour —
# the checks.* suite still runs locally / at promotion time.
#
# Failure mode: a red gate fails this run visibly and pushes nothing;
# next schedule retries. A push race (someone landed on main mid-run)
# also just fails the final push — rerun or wait a week.
#
# Container recipe (nixbld users, sandbox=false, pinned Nix, plain-shell
# install) inherited from check.yml — the gotchas are documented there.

name: Lock bump

on:
  schedule:
    - cron: '17 5 * * 1'   # Mondays 05:17 UTC
  workflow_dispatch:

jobs:
  bump:
    runs-on: ubuntu-latest
    timeout-minutes: 90
    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
        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: Update flake.lock
        # Inputs track release branches (nixos-26.05, release-26.05), so
        # the update stays within them by construction. The human-readable
        # change list goes into the commit body below.
        run: |
          nix flake update 2>&1 | tee /tmp/bump-log
          if git diff --quiet flake.lock; then
            echo "Lock already up to date — nothing to do."
            echo "changed=0" >> "$GITHUB_OUTPUT"
          else
            echo "changed=1" >> "$GITHUB_OUTPUT"
          fi
        id: update

      - name: Gate — nix flake check (eval only)
        if: steps.update.outputs.changed == '1'
        run: nix flake check --no-build

      - name: Gate — V1 build (toplevel + home-manager)
        if: steps.update.outputs.changed == '1'
        run: |
          nix build .#homeConfigurations.nomarchy.activationPackage --no-link
          nix build .#nixosConfigurations.nomarchy.config.system.build.toplevel --no-link

      - name: Commit + push on green
        if: steps.update.outputs.changed == '1'
        # The checkout step persists the Actions token, so this push
        # authenticates as the workflow; its push triggers check.yml as
        # the second net. Only flake.lock is committed — pathspec-limited,
        # nothing else can ride along.
        run: |
          {
            echo "chore(lock): scheduled upstream bump"
            echo
            grep -E '^(• |  )' /tmp/bump-log || true
            echo
            echo "Gate: nix flake check --no-build (eval tier — see bump.yml header)."
          } > /tmp/bump-msg
          git -c user.name="nomarchy-bump" -c user.email="actions@git.bemagri.xyz" \
            commit --only flake.lock -F /tmp/bump-msg
          git push origin HEAD:main
