{ description = "a makeshift CI solution"; inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; pyproject-nix = { url = "github:nix-community/pyproject.nix"; inputs.nixpkgs.follows = "nixpkgs"; }; }; outputs = { self, nixpkgs, pyproject-nix, }: let system = "x86_64-linux"; pkgs = import nixpkgs {inherit system;}; python = pkgs.python3; msci = (pkgs.writeScriptBin "msci" (builtins.readFile ./msci)).overrideAttrs (old: { buildCommand = "${old.buildCommand}\n patchShebangs $out"; }); msci-web = pyproject-nix.lib.project.loadPyproject { projectRoot = ./.; }; msci-web-attrs = msci-web.renderers.buildPythonPackage {inherit python;}; in { packages."${system}" = { msci = pkgs.symlinkJoin { name = "msci"; paths = [msci pkgs.jq pkgs.git pkgs.openssl]; buildInputs = [pkgs.makeWrapper]; postBuild = "wrapProgram $out/bin/msci --prefix PATH : $out/bin"; }; msci-web = python.pkgs.buildPythonPackage msci-web-attrs; }; nixosModules.default = { lib, config, ... }: let cfg = config.makeshiftci; in { options = with lib; { makeshiftci = mkOption { type = types.submodule { options = { enable = mkEnableOption "enable makeshiftci"; dataDir = mkOption { type = types.str; default = "/var/lib/makeshiftci"; description = "data directory of makeshiftci"; }; createUser = mkEnableOption "create a non-root user"; webUI = mkOption { type = types.submodule { options = { enable = mkEnableOption "enable makeshiftci web UI"; port = mkOption { type = types.int; default = 5000; description = "port to run the web UI on"; }; timeout = mkOption { type = types.int; default = 3600; description = "gunicorn timeout"; }; workers = mkOption { type = types.int; default = 4; description = "number of gunicorn workers"; }; }; }; default = {}; }; }; }; default = {}; }; }; config = lib.mkIf cfg.enable (lib.mkMerge [ { environment = { variables.MSCI_HOME = cfg.dataDir; systemPackages = [self.packages."${system}".msci]; }; systemd.tmpfiles.settings."makeshiftci" = { "${cfg.dataDir}" = { d = { user = if cfg.createUser then "makeshiftci" else "root"; group = if cfg.createUser then "makeshiftci" else "root"; mode = "0750"; }; }; }; services.cron.enable = true; users = lib.mkIf cfg.createUser { users."makeshiftci" = { group = "makeshiftci"; home = cfg.dataDir; useDefaultShell = true; }; }; } (lib.mkIf cfg.webUI.enable { systemd.services.makeshiftci-web = { wantedBy = ["multi-user.target"]; unitConfig.ConditionUser = if cfg.createUser then "makeshiftci" else "root"; serviceConfig = let webui = pkgs.python3.withPackages (p: with p; [ gunicorn self.packages."${system}".msci-web ]); in { ExecStart = "${webui}/bin/gunicorn " + "-w ${builtins.toString cfg.webUI.workers} " + "--timeout ${builtins.toString cfg.webUI.timeout} " + "-b 127.0.0.1:${builtins.toString cfg.webUI.port} " + "'web:create_app()'"; }; }; }) ]); }; }; }