Back to feed

sledtools/pika branch #109

pika-git-rename-cleanup-1

Fix pika-git state migration on first deploy

Target branch: master

branch: closed tutorial: ready ci: success
Open CI Details

Continuous Integration

CI: success

Compact status on the review page, with full logs on the CI page.

Open CI Details

Latest run #136 success

10 passed

head 6837e1575bfa6ee23caeea2212261ab471dcca77 · queued 2026-03-26 02:46:09 · 10 lane(s)

queued 14h 20m · ran 14m 41s

check-pika-rust · success check-pika-followup · success check-notifications · success check-agent-contracts · success check-rmp · success check-pikachat · success check-pikachat-typescript · success check-apple-host-sanity · success check-pikachat-openclaw-e2e · success check-fixture · success

Summary

This branch completes the rename of the 'pika-news' service to 'pika-git' across the entire repository. It updates NixOS module definitions, systemd service names, SOPS secret key names, state directory paths, configuration examples, test fixtures, build scripts, and justfile aliases. Critically, it adds a state migration script in the NixOS module that safely moves data from /var/lib/pika-news to /var/lib/pika-git on first deploy, handling edge cases like an empty target directory or an already-migrated state, and leaves a symlink at the legacy path for backward compatibility.

Tutorial Steps

Add state directory migration logic to the NixOS module

Intent: Ensure that existing deployments with data in /var/lib/pika-news are seamlessly migrated to /var/lib/pika-git on the first deploy after the rename, without data loss. The script handles three cases: target doesn't exist yet (direct move), target exists but is empty (remove empty dir then move), and target already has data (no-op). A symlink from the legacy path to the new path is created afterward for any residual references.

Affected files: infra/nix/modules/pika-git.nix

Evidence
@@ -2,17 +2,36 @@
-  serviceUser = "pika-news";
-  serviceGroup = "pika-news";
+  serviceUser = "pika-git";
+  serviceGroup = "pika-git";
-  serviceStateDir = "/var/lib/pika-news";
+  serviceStateDir = "/var/lib/pika-git";
+  legacyServiceStateDir = "/var/lib/pika-news";
@@ +10,19 @@
+    if [ "$legacy_state_dir" != "$state_dir" ] && [ -d "$legacy_state_dir" ] && [ ! -L "$legacy_state_dir" ]; then
+      if [ ! -e "$state_dir" ]; then
+        ${pkgs.coreutils}/bin/mv "$legacy_state_dir" "$state_dir"
+      elif [ -d "$state_dir" ] && [ -z "$(${pkgs.findutils}/bin/find "$state_dir" -mindepth 1 -maxdepth 1 -print -quit)" ]; then
+        ${pkgs.coreutils}/bin/rmdir "$state_dir"
+        ${pkgs.coreutils}/bin/mv "$legacy_state_dir" "$state_dir"
+      fi
+    fi
@@ +20,5 @@
+    ${pkgs.coreutils}/bin/mkdir -p "$state_dir"
+    ${pkgs.coreutils}/bin/chown -R ${serviceUser}:${serviceGroup} "$state_dir"
+
+    if [ "$legacy_state_dir" != "$state_dir" ] && [ ! -e "$legacy_state_dir" ]; then
+      ${pkgs.coreutils}/bin/ln -s "$state_dir" "$legacy_state_dir"
+    fi

The core change in this branch is the prepareCanonicalRepo shell script in pika-git.nix. A new legacyServiceStateDir variable is introduced pointing to /var/lib/pika-news.

The migration runs as a ExecStartPre step before the service starts and follows this logic:

  1. Guard clause: Only attempt migration if legacy_state_dir differs from state_dir, the legacy directory exists, and it is not already a symlink.
  2. Case 1 — target absent: mv the legacy directory directly to the new path.
  3. Case 2 — target exists but empty: rmdir the empty target, then mv the legacy directory into place. This handles the scenario where systemd's StateDirectory= directive pre-creates an empty /var/lib/pika-git.
  4. Case 3 — target exists with content: Do nothing (assume migration already happened or state was manually placed).
  5. Post-migration: mkdir -p and chown the new state dir, then create a symlink from the legacy path to the new path so any stale references still resolve.

Rename systemd service and user/group from pika-news to pika-git

Intent: Align the systemd unit name, service user, and service group with the actual project name, eliminating the legacy 'pika-news' naming throughout the NixOS service definition.

Affected files: infra/nix/modules/pika-git.nix, infra/nix/modules/builder.nix

Evidence
@@ -118,7 +136,7 @@
-  systemd.services.pika-news = {
+  systemd.services.pika-git = {
@@ -184,7 +184,7 @@
-      systemctl status pika-news --no-pager -n 20
+      systemctl status pika-git --no-pager -n 20

The systemd service definition is renamed from pika-news to pika-git in pika-git.nix. This means the service will now be managed via systemctl start pika-git, journalctl -u pika-git, etc.

The builder.nix status-checking script is updated in lockstep so that the infrastructure health check queries the correct unit name.

Rename SOPS secret keys from pika_news_* to pika_git_*

Intent: Update encrypted secret key names in both the Nix module references and the SOPS-encrypted YAML file so they consistently use the pika_git prefix.

Affected files: infra/nix/modules/pika-git.nix, infra/secrets/pika-git.yaml

Evidence
@@ -51,7 +70,7 @@
-  sops.secrets."pika_news_github_token" = {
+  sops.secrets."pika_git_github_token" = {
@@ -59,7 +78,7 @@
-  sops.secrets."pika_news_claude_oauth_token" = {
+  sops.secrets."pika_git_claude_oauth_token" = {
@@ -67,7 +86,7 @@
-  sops.secrets."pika_news_webhook_secret" = {
+  sops.secrets."pika_git_webhook_secret" = {
@@ -1,6 +1,6 @@
-pika_news_github_token: ENC[...]
+pika_git_github_token: ENC[...]

Three SOPS secrets are renamed:

Old keyNew key
pika_news_github_tokenpika_git_github_token
pika_news_claude_oauth_tokenpika_git_claude_oauth_token
pika_news_webhook_secretpika_git_webhook_secret

The encrypted payloads (ciphertext, IV, tag) remain identical — only the YAML key names change. The environment file template in the Nix module is updated to reference the new placeholder names, and the duplicate PIKA_NEWS_WEBHOOK_SECRET env var is removed since PIKA_GIT_WEBHOOK_SECRET now serves as the sole source.

Update canonical_git_dir paths in documentation and config examples

Intent: Ensure that the README and example TOML configuration reflect the new /var/lib/pika-git base path.

Affected files: crates/pika-git/README.md, crates/pika-git/pika-git.example.toml

Evidence
@@ -24,7 +24,7 @@
-canonical_git_dir = "/var/lib/pika-news/pika.git"
+canonical_git_dir = "/var/lib/pika-git/pika.git"
@@ -12,7 +12,7 @@
-canonical_git_dir = "/var/lib/pika-news/pika.git"
+canonical_git_dir = "/var/lib/pika-git/pika.git"

Both README.md and pika-git.example.toml in the pika-git crate contained a canonical_git_dir pointing to the old /var/lib/pika-news/pika.git. These are updated to /var/lib/pika-git/pika.git so that anyone following the docs or copying the example config gets the correct path.

Fix test fixture path in pikaci

Intent: Update a unit test that hardcoded the legacy /var/lib/pika-news/pikaci path to use the new /var/lib/pika-git/pikaci path.

Affected files: crates/pikaci/src/main.rs

Evidence
@@ -1904,9 +1904,9 @@
-                Some(std::path::PathBuf::from("/var/lib/pika-news/pikaci"))
+                Some(std::path::PathBuf::from("/var/lib/pika-git/pikaci"))
-            std::path::PathBuf::from("/var/lib/pika-news/pikaci")
+            std::path::PathBuf::from("/var/lib/pika-git/pikaci")

The resolve_state_root test in pikaci/src/main.rs used /var/lib/pika-news/pikaci as both the input and expected output. Both occurrences are updated to /var/lib/pika-git/pikaci to match the renamed state directory.

Remove legacy aliases, shims, and duplicate package outputs

Intent: Clean up all transitional compatibility layers that existed solely to bridge the pika-news to pika-git rename, now that the rename is fully applied.

Affected files: flake.nix, infra/nix/modules/pika-news.nix, justfile, just/infra.just, scripts/news, scripts/pika-git

Evidence
@@ -935,7 +935,6 @@
-            pika-news = pikaGitPkg;
@@ -1,2 +0,0 @@
-args@{ ... }:
-import ./pika-git.nix args
@@ -272,7 +272,6 @@
-alias news := infra::news
@@ -67,7 +67,3 @@
-[private]
-news MAX_PRS="2":
-    ./scripts/pika-git {{ MAX_PRS }}
@@ -1,5 +0,0 @@
-#!/usr/bin/env bash
-exec "$ROOT/scripts/pika-git" "$@"
@@ -58,7 +58,7 @@
-  local bind_port="${PIKA_GIT_PORT:-${PIKA_NEWS_PORT:-$DEFAULT_PORT}}"
+  local bind_port="${PIKA_GIT_PORT:-$DEFAULT_PORT}"

Several compatibility shims are removed:

  • flake.nix: The pika-news package output (which was just an alias for pikaGitPkg) is deleted.
  • pika-news.nix: This entire file was a one-line proxy that imported pika-git.nix. It is deleted.
  • scripts/news: A shell wrapper that exec'd into scripts/pika-git is deleted.
  • just/infra.just: The news recipe (duplicate of pika-git) is removed.
  • justfile: The top-level alias news is removed.
  • scripts/pika-git: The fallback to PIKA_NEWS_PORT env var is removed; only PIKA_GIT_PORT is checked now.

These removals ensure there is exactly one name for the service going forward, reducing confusion and maintenance burden.

Diff