auto-update-daily-20260202
  1{
  2  config,
  3  lib,
  4  pkgs,
  5  ...
  6}:
  7
  8with lib;
  9
 10let
 11  cfg = config.services.nixpkgs-consolidate;
 12
 13  consolidateScript = pkgs.writeShellScript "nixpkgs-consolidate-wrapper" ''
 14    set -euo pipefail
 15
 16    export NIXPKGS_REPO_PATH="${cfg.repoPath}"
 17    export NIXPKGS_WORKTREE_PATH="${cfg.worktreePath}"
 18    export NIXPKGS_CONFIG_FILE="${cfg.configFile}"
 19    export NTFY_TOKEN_FILE="${cfg.ntfyTokenFile}"
 20    export LOG_DIR="${cfg.logDir}"
 21
 22    exec ${pkgs.nixpkgs-consolidate}/bin/nixpkgs-consolidate
 23  '';
 24in
 25{
 26  options.services.nixpkgs-consolidate = {
 27    enable = mkEnableOption "automated nixpkgs branch consolidation";
 28
 29    repoPath = mkOption {
 30      type = types.str;
 31      default = "/home/vincent/src/nixpkgs";
 32      description = "Path to nixpkgs repository";
 33    };
 34
 35    worktreePath = mkOption {
 36      type = types.str;
 37      default = "/home/vincent/src/nixpkgs-consolidate-work";
 38      description = "Path to worktree for consolidation work";
 39    };
 40
 41    configFile = mkOption {
 42      type = types.str;
 43      default = "/home/vincent/.config/nixpkgs-automation/branches.conf";
 44      description = "Path to branches configuration file";
 45    };
 46
 47    schedule = mkOption {
 48      type = types.str;
 49      default = "daily";
 50      example = "Mon,Thu *-*-* 02:00:00";
 51      description = ''
 52        Systemd timer schedule (OnCalendar format).
 53        Use "daily", "weekly", or systemd calendar syntax.
 54      '';
 55    };
 56
 57    user = mkOption {
 58      type = types.str;
 59      default = "vincent";
 60      description = "User to run consolidation as (needs git access)";
 61    };
 62
 63    ntfyTokenFile = mkOption {
 64      type = types.str;
 65      default = "/run/agenix/ntfy-token";
 66      description = "Path to ntfy authentication token";
 67    };
 68
 69    logDir = mkOption {
 70      type = types.str;
 71      default = "/var/log/nixpkgs-consolidate";
 72      description = "Directory for log files";
 73    };
 74
 75    randomizedDelaySec = mkOption {
 76      type = types.int;
 77      default = 1800; # 30 minutes
 78      description = "Random delay in seconds before starting";
 79    };
 80  };
 81
 82  config = mkIf cfg.enable {
 83    systemd.services.nixpkgs-consolidate = {
 84      description = "Nixpkgs branch consolidation automation";
 85
 86      serviceConfig = {
 87        Type = "oneshot";
 88        User = cfg.user;
 89        ExecStart = "${consolidateScript}";
 90        Environment = ''"GIT_SSH_COMMAND=ssh -o ControlMaster=no"'';
 91
 92        # Security hardening
 93        PrivateTmp = true;
 94        ProtectSystem = "strict";
 95        ProtectHome = "false"; # Need full access to home for git operations
 96        ReadWritePaths = [
 97          cfg.repoPath
 98          cfg.worktreePath
 99          cfg.logDir
100        ];
101        NoNewPrivileges = true;
102
103        # Logging
104        StandardOutput = "journal";
105        StandardError = "journal";
106        SyslogIdentifier = "nixpkgs-consolidate";
107      };
108
109      # Trigger notification on failure
110      unitConfig.OnFailure = [ "job-notify@%n.service" ];
111    };
112
113    systemd.timers.nixpkgs-consolidate = {
114      description = "Timer for nixpkgs branch consolidation";
115      wantedBy = [ "timers.target" ];
116
117      timerConfig = {
118        OnCalendar = cfg.schedule;
119        RandomizedDelaySec = cfg.randomizedDelaySec;
120        Persistent = true;
121      };
122    };
123
124    # Ensure directories exist
125    systemd.tmpfiles.rules = [
126      "d ${cfg.logDir} 0750 ${cfg.user} users -"
127      "d ${cfg.repoPath} 0750 ${cfg.user} users -"
128      "d ${cfg.worktreePath} 0750 ${cfg.user} users -"
129      "d ${builtins.dirOf cfg.configFile} 0755 ${cfg.user} users -"
130    ];
131  };
132}