diff --git a/nix/hosts/cc-ci-orchestrator-hetzner/configuration.nix b/nix/hosts/cc-ci-orchestrator-hetzner/configuration.nix index 9972d2e..c06c00e 100644 --- a/nix/hosts/cc-ci-orchestrator-hetzner/configuration.nix +++ b/nix/hosts/cc-ci-orchestrator-hetzner/configuration.nix @@ -182,4 +182,34 @@ SSHCFG echo "workspace not staged yet โ€” skipping loop start" ''; }; + + # Weekly recipe upgrade โ€” runs /upgrade-all over every enrolled recipe (opens recipe PRs + # verified by !testme, never merges). Replaces the boot-fragile busybox-crond-in-tmux from + # phase 5 ยง4 with a reboot-safe systemd timer. The service is timer-triggered only (NOT + # wantedBy multi-user.target) so it never runs on boot/activation โ€” only on the schedule. + systemd.services.cc-ci-upgrade-all = { + description = "cc-ci weekly /upgrade-all run (recipe upgrade survey + PRs, never merges)"; + after = [ "network-online.target" "tailscaled.service" "claude-install.service" ]; + wants = [ "network-online.target" ]; + serviceConfig = { + Type = "oneshot"; # launch-upgrader.py spawns the cc-ci-upgrader tmux session and returns + User = "loops"; Group = "users"; + WorkingDirectory = "/srv/cc-ci"; + }; + environment = { HOME = "/home/loops"; CLAUDE_BIN = "/home/loops/.local/bin/claude"; }; + path = [ pkgs.bash pkgs.tmux pkgs.git pkgs.python3 pkgs.openssh pkgs.nettools ]; + script = '' + export PATH="/home/loops/.local/bin:$PATH" + python3 /srv/cc-ci/cc-ci-plan/launch-upgrader.py start >> /srv/cc-ci/.cc-ci-logs/upgrader-cron.log 2>&1 + ''; + }; + + systemd.timers.cc-ci-upgrade-all = { + description = "Weekly trigger for cc-ci-upgrade-all (Sundays 02:00 UTC)"; + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "Sun *-*-* 02:00:00 UTC"; + Persistent = true; # if the box was down at the scheduled time, run once on next boot + }; + }; }