main
  1{
  2  den,
  3  lib,
  4  ...
  5}: {
  6  den.aspects.services.forgejo.server = {
  7    settings.host = {
  8      domain = lib.mkOption {
  9        type = lib.types.str;
 10      };
 11      address = lib.mkOption {
 12        type = lib.types.str;
 13        default = "127.0.0.1";
 14      };
 15      port = lib.mkOption {
 16        type = lib.types.port;
 17        default = 3155;
 18      };
 19    };
 20
 21    reverseProxy = {host, ...}: let
 22      cfg = host.settings.services.forgejo.server;
 23    in {
 24      ${cfg.domain} = {
 25        port = cfg.port;
 26      };
 27    };
 28
 29    persist = {config, ...}: {
 30      directories = [
 31        {
 32          directory = config.services.forgejo.stateDir;
 33          inherit (config.services.forgejo) user group;
 34          mode = "0700";
 35        }
 36      ];
 37    };
 38
 39    nixos = {
 40      host,
 41      config,
 42      ...
 43    }: let
 44      hostCfg = host.settings.services.forgejo.server;
 45    in {
 46      services.forgejo = {
 47        enable = true;
 48        user = "git";
 49        group = "forgejo";
 50        database = {
 51          type = "sqlite3";
 52        };
 53        lfs.enable = true;
 54        settings = {
 55          DEFAULT = {
 56            APP_NAME = "Gate Of Infinity";
 57            APP_SLOGAN = "Walk toward the tomorrow where the stars gleam.";
 58            APP_DISPLAY_NAME_FORMAT = "{APP_NAME}";
 59          };
 60          server = {
 61            DOMAIN = hostCfg.domain;
 62            HTTP_ADDR = hostCfg.address;
 63            HTTP_PORT = hostCfg.port;
 64            # Tailnet deployments (domain under the tailnet domain) use the
 65            # tailnet SSH daemon on 22; public deployments use the openssh
 66            # server port.
 67            SSH_PORT =
 68              if lib.hasSuffix ".${den.aspects.services.caddy.tailnetDomain}" hostCfg.domain
 69              then 22
 70              else host.settings.core.openssh.server.port;
 71            PROTOCOL = "http";
 72            ROOT_URL = "https://${hostCfg.domain}/";
 73          };
 74          service = {
 75            DISABLE_REGISTRATION = true;
 76            ENABLE_BASIC_AUTHENTICATION = false;
 77          };
 78          repository = {
 79            DEFAULT_REPO_UNITS = "repo.code,repo.releases,repo.issues,repo.pulls";
 80            DEFAULT_FORK_REPO_UNITS = "repo.code,repo.pulls";
 81            DEFAULT_MIRROR_REPO_UNITS = "repo.code";
 82          };
 83          actions = {
 84            ENABLED = true;
 85            DEFAULT_ACTIONS_URL = "https://${hostCfg.domain}";
 86          };
 87          webhook = {
 88            ALLOWED_HOST_LIST = "external,loopback";
 89          };
 90          log = {
 91            LEVEL = "Info";
 92            LOGGER_ROUTER_MODE = "Error";
 93          };
 94          ui = {
 95            THEMES = lib.concatStringsSep "," [
 96              "forgejo-auto"
 97              "forgejo-light"
 98              "forgejo-dark"
 99              "gitea-auto"
100              "gitea-light"
101              "gitea-dark"
102            ];
103          };
104        };
105      };
106
107      users.users."git" = {
108        isSystemUser = true;
109        useDefaultShell = true;
110        group = config.services.forgejo.group;
111        home = config.services.forgejo.stateDir;
112      };
113
114      services.openssh = {
115        extraConfig = ''
116          Match User git
117            AcceptEnv GIT_PROTOCOL
118        '';
119      };
120    };
121  };
122}