{ 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; persist.directories = [ { directory = "/var/lib/gitolite"; user = "git"; group = "git"; mode = "0755"; } ]; }; services = { gitolite = { inherit (cfg.gitolite) adminPubkey; enable = true; dataDir = "/var/lib/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 = ""; # 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.` can be set by setting `cgit.` 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; }; }; }; }; }; }