summary refs log tree commit diff stats
path: root/modules/by-name/gi/git-server/module.nix
diff options
context:
space:
mode:
Diffstat (limited to 'modules/by-name/gi/git-server/module.nix')
-rw-r--r--modules/by-name/gi/git-server/module.nix178
1 files changed, 178 insertions, 0 deletions
diff --git a/modules/by-name/gi/git-server/module.nix b/modules/by-name/gi/git-server/module.nix
new file mode 100644
index 0000000..a374f4c
--- /dev/null
+++ b/modules/by-name/gi/git-server/module.nix
@@ -0,0 +1,178 @@
+{
+  config,
+  lib,
+  pkgs,
+  ...
+}: let
+  cfg = config.vhack.git-server;
+
+  cgitCss = import ./css.nix {
+    inherit pkgs;
+    cgitPkg =
+      config.services.cgit."${cfg.domain}".package;
+  };
+in {
+  options.vhack.git-server = {
+    enable = lib.mkEnableOption ''
+      a lightweight git-server, realised with cgit and gitolite.
+    '';
+
+    domain = lib.mkOption {
+      type = lib.types.str;
+      default = "git.vhack.eu";
+      description = ''
+        The domain this git instance will run under.
+      '';
+    };
+
+    gitolite = {
+      adminPubkey = lib.mkOption {
+        description = ''
+          The initial key to use for gitolite. This will only be used for the initial
+          clone of the `gitolite-admin` repository.
+        '';
+        type = lib.types.str;
+        default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAe4o1PM6VasT3KZNl5NYvgkkBrPOg36dqsywd10FztS openpgp:0x21D20D6A";
+      };
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    programs.git = {
+      enable = true;
+      config = {
+        init = {
+          defaultBranch = "main";
+        };
+      };
+    };
+
+    # Needed for the nginx proxy and the virtual host
+    vhack.nginx.enable = true;
+
+    services = {
+      gitolite = {
+        inherit (cfg.gitolite) adminPubkey;
+        enable = true;
+        dataDir = "/srv/gitolite";
+        user = "git";
+        group = "git";
+        extraGitoliteRc = ''
+          $RC{UMASK} = 0027; # Enable group access, important for cgit.
+
+          # Enable modifing git variables (for cgit.owner and such things)
+          # These must be enable in the gitolite-admin repo (option user-configs = ...)
+          push( @{$RC{ENABLE}}, 'config' );
+          push( @{$RC{ENABLE}}, 'git-config' );
+
+          push( @{$RC{ENABLE}}, 'expand-deny-messages' );
+          push( @{$RC{ENABLE}}, 'Motd' );
+
+          push( @{$RC{ENABLE}}, 'cgit' );
+        '';
+      };
+
+      cgit."${cfg.domain}" = {
+        enable = true;
+        package = pkgs.cgit-pink;
+        scanPath = "${config.services.gitolite.dataDir}/repositories";
+        user = "git";
+        group = "git";
+        settings = {
+          branch-sort = "age";
+
+          # Allow users to download a repo checkout with these compression formats
+          snapshots = ["tar.gz" "zip"];
+          # The template used to generate the clone url for https clone.
+          clone-url = [
+            "https://${cfg.domain}/$CGIT_REPO_URL"
+            "ssh://git@${cfg.domain}/$CGIT_REPO_URL"
+          ];
+          enable-http-clone = true;
+
+          # TODO: We might want to add an logo and readme here <2024-07-31>
+          # logo = "<url>";
+          # root-readme = "/some/readme/file"
+          root-desc = "The cgit instance of ${cfg.domain}!";
+          root-title = "${
+            lib.strings.toUpper (builtins.substring 0 1 cfg.domain) + builtins.substring 1 (builtins.stringLength cfg.domain) cfg.domain
+          } cgit instace";
+
+          # Set the default maximum statistics period. Valid values are "week",
+          # "month", "quarter" and "year".
+          max-stats = "week";
+
+          readme = [
+            ":README.md"
+            ":readme.md"
+            ":README.mkd"
+            ":readme.mkd"
+            ":README.rst"
+            ":readme.rst"
+            ":README.html"
+            ":readme.html"
+            ":README.htm"
+            ":readme.htm"
+            ":README.txt"
+            ":readme.txt"
+            ":README"
+            ":readme"
+            ":INSTALL.md"
+            ":install.md"
+            ":INSTALL.mkd"
+            ":install.mkd"
+            ":INSTALL.rst"
+            ":install.rst"
+            ":INSTALL.html"
+            ":install.html"
+            ":INSTALL.htm"
+            ":install.htm"
+            ":INSTALL.txt"
+            ":install.txt"
+            ":INSTALL"
+            ":install"
+          ];
+
+          enable-blame = true;
+          enable-commit-graph = true;
+          enable-subject-links = true;
+          enable-follow-links = true;
+          enable-index-links = true;
+          enable-index-owner = true;
+
+          # NOTE: This allows cgit to take configuration from the bare git repositories:
+          # All `repo.<key>` can be set by setting `cgit.<key>` in the git config. E.g.:
+          # setting the owner (i.e. `repo.owner`) would be done by setting the
+          # `cgit.owner` config. All repo options are outline in the cgitrc (5) man page.
+          enable-git-config = true;
+
+          # Remove the `.git` suffix from scanned repositories (this must be set _before_ `scan-path`)
+          remove-suffix = true;
+
+          css = "/custom_cgit.css";
+
+          # This is a number of path elements to treat as section.
+          # `-1` means that we treat the last element as name, all others as sections
+          section-from-path = -1;
+
+          project-list = "${config.services.gitolite.dataDir}/projects.list";
+
+          # TODO:  We might want to use the kernel.org `libravatar.lua` email-filter <2024-07-31>
+          source-filter = "${config.services.cgit."${cfg.domain}".package}/lib/cgit/filters/syntax-highlighting.py";
+          about-filter = "${config.services.cgit."${cfg.domain}".package}/lib/cgit/filters/about-formatting.sh";
+        };
+      };
+
+      nginx.virtualHosts."${cfg.domain}" = {
+        enableACME = true;
+        forceSSL = true;
+
+        locations = {
+          "= /custom_cgit.css" = {
+            alias = cgitCss.outPath;
+          };
+        };
+      };
+    };
+  };
+}