{ config, lib, pkgs, ... }: let cfg = config.vhack.git-server; cgitCss = import ./css.nix { inherit pkgs; cgitPkg = config.services.cgit."${cfg.domain}".package; }; /* Until is merged into nixpkgs, we have to do the list to string conversion ourselves: */ toCgitRc = list: lib.strings.concatStringsSep " " list; 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 = { fcgiwrap = { # NOTE: This is needed as `cgit` otherwise fails to run `git` commands in the git # repositories (for example, when cloning a repository over http). <2024-08-02> # FIXME: Is there a way to not run _all_ wrapped cgi things as `git`? <2024-08-02> user = "git"; group = "nginx"; }; 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) $RC{GIT_CONFIG_KEYS} = 'cgit\.owner cgit\.desc cgit\.section cgit\.homepage gitweb\.owner gitweb\.description'; 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"; settings = { branch-sort = "age"; # Allow users to download a repo checkout with these compression formats snapshots = toCgitRc ["tar.gz" "zip"]; # The template used to generate the clone url for https clone. clone-url = toCgitRc ["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 = toCgitRc [ ":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: # eg. `cgit.section` should set the section, `cgit.homepage` the homepage, # `gitweb.owner` the owner and `gitweb.description` the description of the repo. <2024-08-02> 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. # Set this to a big number to ensure all path elements are treated as sections. section-from-path = 1000; 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; }; }; }; }; }; }