Skip to content

feat(pi): deploy on CI green instead of waiting for nightly#482

Open
etrobert-bot wants to merge 2 commits into
mainfrom
pi-deploy-ci-push
Open

feat(pi): deploy on CI green instead of waiting for nightly#482
etrobert-bot wants to merge 2 commits into
mainfrom
pi-deploy-ci-push

Conversation

@etrobert-bot

@etrobert-bot etrobert-bot commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Closes #481

Candidate B (CI push) of the two implementations #481 calls for — to be compared against candidate A (#483); the loser does not merge.

Adds a deploy-pi job to .github/workflows/build.yml that runs
nixos-rebuild switch --flake .#pi --target-host root@100.68.23.44 from
tower's self-hosted runner once all-builds passes. Eval/build happen on
tower (substituting the aarch64 closure that CI already pushed to Cachix); pi
only receives store paths and activates.

Design

  • Gate: needs: all-builds — default success semantics mean the deploy
    never runs unless every host build passed, so we never deploy raw main.
    if: github.event_name == 'push' limits it to merges (skipped on PRs).
  • Deploy user: root@pi. PermitRootLogin = "prohibit-password" (NixOS
    default) allows key-only root login and nixos-rebuild switch needs root on
    the target, so no --use-remote-sudo.
  • Key scope: private key lives only at tower:/home/soft/.ssh/pi-deploy,
    exposed to CI through the pi-deploy environment secret PI_DEPLOY_SSH_KEY
    (deployment-branch policy restricted to main, so PR/branch runs can't read
    it). Public key is pinned in pi's authorized_keys with
    from="100.103.91.42,192.168.0.10" (tower's Tailscale + LAN addresses), so
    an exfiltrated key is useless off tower.
  • Backstop: the nightly system.autoUpgrade is unchanged — it catches pi up
    if it was offline when a deploy fired.

Manual setup (create the environment + secret) is required before this deploys;
steps are documented for the repo owner.

🤖 Generated with Claude Code

etrobert-bot and others added 2 commits July 10, 2026 04:13
Add a deploy-pi job to the build workflow that runs
`nixos-rebuild switch --flake .#pi --target-host root@pi` from tower's
self-hosted runner once all-builds passes. Gating on all-builds keeps the
invariant that we never deploy raw main: the aarch64 closure is already in
Cachix, pushed by tower's post-build hook during CI.

The deploy key is scoped to main via the pi-deploy environment
(deployment-branch policy) and pinned to tower's addresses via `from=` in
pi's authorized_keys, so an exfiltrated key is useless off tower. The nightly
system.autoUpgrade stays as the offline-catch-up backstop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deploy pi from main within minutes: gated pull vs CI push

1 participant