summary refs log tree commit diff stats
path: root/system/settings
diff options
context:
space:
mode:
Diffstat (limited to 'system/settings')
-rw-r--r--system/settings/services/git-server.nix67
1 files changed, 67 insertions, 0 deletions
diff --git a/system/settings/services/git-server.nix b/system/settings/services/git-server.nix
index 916a4880..946bf4ba 100644
--- a/system/settings/services/git-server.nix
+++ b/system/settings/services/git-server.nix
@@ -4,8 +4,60 @@
 , ...
 }:
 let
+  inherit (builtins) mapAttrs attrValues;
+  inherit (lib) pipe flatten mergeAttrsList mapAttrsToList;
   inherit (import ../../../lib/caddy.nix { inherit lib; }) security-headers;
   repos = "${config.services.gitolite.dataDir}/repositories";
+
+  mirrors = {
+    sourcehut = {
+      hostname = "git.sr.ht";
+      username = "~alanpearce";
+    };
+    codeberg = {
+      hostname = "codeberg.org";
+      username = "alanpearce";
+    };
+    github = {
+      hostname = "github.com";
+      username = "alanpearce";
+    };
+  };
+
+  repoMirrors = {
+    nixfiles = [ "sourcehut" ];
+    searchix = [ "sourcehut" ];
+    website = [ "sourcehut" ];
+    nix-packages = [ "sourcehut" "github" ];
+    zola-bearblog = [ "sourcehut" "codeberg" ];
+  };
+
+  createMirrorService =
+    name: { hostname, username }:
+    {
+      services."mirror-to-${name}@" = {
+        path = with pkgs; [ gitMinimal openssh ];
+        serviceConfig = {
+          Type = "oneshot";
+          User = "gitolite";
+          WorkingDirectory = "${repos}/%i.git";
+          ExecStart = "${pkgs.gitMinimal}/bin/git push --mirror git@${hostname}:${username}/%i";
+        };
+        unitConfig = {
+          # only mirror public repositories
+          ConditionPathExists = "${repos}/%i.git/git-daemon-export-ok";
+        };
+      };
+      paths."mirror-to-${name}@" = {
+        pathConfig = {
+          PathChanged = "${repos}/%i.git/refs/heads";
+          StartLimitIntervalSec = "1h";
+          StartLimitBurst = 5;
+        };
+      };
+    };
+
+  mkMirrorWants = repo: map (target: "mirror-to-${target}@${repo}.path");
 in
 {
   services.fcgiwrap = {
@@ -209,4 +261,19 @@ in
       '')
     ];
   };
+
+  systemd = (pipe
+    mirrors [
+    (mapAttrsToList createMirrorService)
+    mergeAttrsList
+  ]) // {
+    targets.git-mirroring = {
+      wantedBy = [ "multi-user.target" ];
+      wants = pipe
+        repoMirrors [
+        (mapAttrsToList mkMirrorWants)
+        flatten
+      ];
+    };
+  };
 }