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