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:
- Guard clause: Only attempt migration if
legacy_state_dir differs from state_dir, the legacy directory exists, and it is not already a symlink.
- Case 1 — target absent:
mv the legacy directory directly to the new path.
- 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.
- Case 3 — target exists with content: Do nothing (assume migration already happened or state was manually placed).
- 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 key | New key |
pika_news_github_token | pika_git_github_token |
pika_news_claude_oauth_token | pika_git_claude_oauth_token |
pika_news_webhook_secret | pika_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.