diff --git a/nix-darwin/flake.nix b/nix-darwin/flake.nix index 6637eacf..0fd30ff0 100644 --- a/nix-darwin/flake.nix +++ b/nix-darwin/flake.nix @@ -25,13 +25,69 @@ outputs = inputs@{ self, nix-darwin, nixpkgs, home-manager, ... }: let + libDir = ../dotfiles/lib; configuration = { pkgs, config, ... }: { + networking.hostName = "mac-demarco-mini"; + imports = [ (import ./gitea-actions-runner.nix) ]; + services.gitea-actions-runner = { + instances.nix = { + enable = true; + name = config.networking.hostName; + url = "https://dev.railbird.ai"; + token = "kf8TgHEf2JwWiusV80ZWo3t7lkEyB1pVgqRdK5ES"; + labels = [ + "nix-darwin-${pkgs.system}:host" + "nix:host" + ]; + settings = { + cache = { + enabled = true; + }; + container = { + workdir_parent = "/var/lib/gitea-runner/workspace"; + }; + host = { + workdir_parent = "/var/lib/gitea-runner/action-cache-dir"; + }; + }; + hostPackages = with pkgs; [ + bash + direnv + coreutils + curl + gawk + git-lfs + nixFlakes + gitFull + gnused + nodejs + openssh + wget + ]; + }; + }; + + # Create the necessary directories + system.activationScripts.giteaRunnerDirs = '' + mkdir -p /var/lib/gitea-runner/workspace + mkdir -p /var/lib/gitea-runner/action-cache-dir + chown -R kat:staff /var/lib/gitea-runner + ''; + + # Set environment variables + launchd.daemons.gitea-runner-nix.serviceConfig.EnvironmentVariables = { + XDG_CONFIG_HOME = "/var/lib/gitea-runner"; + XDG_CACHE_HOME = "/var/lib/gitea-runner/.cache"; + }; + nixpkgs.overlays = [(import ../nixos/overlay.nix)]; environment.systemPackages = with pkgs; [ + python-with-my-packages emacs alejandra cocoapods gitFull just + tmux nodePackages.prettier nodejs ripgrep @@ -53,14 +109,11 @@ # Necessary for using flakes on this system. nix.settings.experimental-features = "nix-command flakes"; - # Create /etc/zshrc that loads the nix-darwin environment. - programs.zsh.enable = true; # Set Git commit hash for darwin-version. system.configurationRevision = self.rev or self.dirtyRev or null; - # Used for backwards compatibility, please read the changelog before changing. - # $ darwin-rebuild changelog + # Used for backwards compatibility, please read the changelog before changing system.stateVersion = 4; # The platform the configuration will be used on. @@ -69,12 +122,42 @@ home-manager.useGlobalPkgs = true; home-manager.useUserPackages = true; + + users.users.kat = { + name = "kat"; + home = "/Users/kat"; + }; + + programs.zsh = { + enable = true; + shellInit = '' + fpath+="${libDir}/functions" + for file in "${libDir}/functions/"* + do + autoload "''${file##*/}" + done + ''; + interactiveShellInit = '' + # eval "$(register-python-argcomplete prb)" + # eval "$(register-python-argcomplete prod-prb)" + # eval "$(register-python-argcomplete railbird)" + # [ -n "$EAT_SHELL_INTEGRATION_DIR" ] && source "$EAT_SHELL_INTEGRATION_DIR/zsh" + + autoload -Uz bracketed-paste-magic + zle -N bracketed-paste bracketed-paste-magic + ''; + }; + + home-manager.users.kat = { + programs.starship = { + enable = true; + }; + home.stateVersion = "24.05"; + }; }; in { - # Build darwin flake using: - # $ darwin-rebuild build --flake .#Kats-Mac-mini - darwinConfigurations."Kats-Mac-mini" = nix-darwin.lib.darwinSystem { + darwinConfigurations."mac-demarco-mini" = nix-darwin.lib.darwinSystem { modules = [ home-manager.darwinModules.home-manager configuration diff --git a/nix-darwin/gitea-actions-runner.nix b/nix-darwin/gitea-actions-runner.nix new file mode 100644 index 00000000..4b560a44 --- /dev/null +++ b/nix-darwin/gitea-actions-runner.nix @@ -0,0 +1,145 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.gitea-actions-runner; + + settingsFormat = pkgs.formats.yaml { }; + + hasDockerScheme = instance: + instance.labels == [] || any (label: hasInfix ":docker:" label) instance.labels; + wantsContainerRuntime = any hasDockerScheme (attrValues cfg.instances); + + hasHostScheme = instance: any (label: hasSuffix ":host" label) instance.labels; + + tokenXorTokenFile = instance: + (instance.token == null && instance.tokenFile != null) || + (instance.token != null && instance.tokenFile == null); + +in { + options.services.gitea-actions-runner = { + package = mkPackageOption pkgs "gitea-actions-runner" { }; + + instances = mkOption { + default = {}; + description = "Gitea Actions Runner instances."; + type = types.attrsOf (types.submodule { + options = { + enable = mkEnableOption "Gitea Actions Runner instance"; + + name = mkOption { + type = types.str; + example = "my-runner"; + description = "The name identifying the runner instance towards the Gitea/Forgejo instance."; + }; + + url = mkOption { + type = types.str; + example = "https://forge.example.com"; + description = "Base URL of your Gitea/Forgejo instance."; + }; + + token = mkOption { + type = types.nullOr types.str; + default = null; + description = "Plain token to register at the configured Gitea/Forgejo instance."; + }; + + tokenFile = mkOption { + type = types.nullOr (types.either types.str types.path); + default = null; + description = "Path to a file containing the token to register at the configured Gitea/Forgejo instance."; + }; + + labels = mkOption { + type = types.listOf types.str; + default = []; + example = [ "macos:host" "x86_64:host" ]; + description = "Labels used to map jobs to their runtime environment."; + }; + + settings = mkOption { + description = "Configuration for `act_runner daemon`."; + type = types.submodule { + freeformType = settingsFormat.type; + }; + default = { }; + }; + + hostPackages = mkOption { + type = types.listOf types.package; + default = with pkgs; [ + bash + coreutils + curl + gawk + git + gnused + nodejs + wget + openssh + ]; + description = "List of packages available to actions when the runner is configured with a host execution label."; + }; + }; + }); + }; + }; + + config = mkIf (cfg.instances != {}) { + assertions = [ + { + assertion = all tokenXorTokenFile (attrValues cfg.instances); + message = "Instances of gitea-actions-runner can have `token` or `tokenFile`, not both."; + } + ]; + + launchd.daemons = mapAttrs' (name: instance: + nameValuePair "gitea-runner-${name}" { + serviceConfig = { + ProgramArguments = [ + "${pkgs.writeShellScript "gitea-runner-start-${name}" '' + export HOME="/var/lib/gitea-runner/${name}" + mkdir -p "$HOME" + cd "$HOME" + touch run_started + date -d > $HOME/last-run + + # Register the runner if not already registered + if [ ! -e "$HOME/.runner" ]; then + ${cfg.package}/bin/act_runner register --no-interactive \ + --instance ${escapeShellArg instance.url} \ + --token "$TOKEN" \ + --name ${escapeShellArg instance.name} \ + --labels ${escapeShellArg (concatStringsSep "," instance.labels)} \ + --config ${settingsFormat.generate "config.yaml" instance.settings} + fi + + # Start the runner + exec ${cfg.package}/bin/act_runner daemon --config ${settingsFormat.generate "config.yaml" instance.settings} + ''}" + ]; + KeepAlive = true; + RunAtLoad = true; + WorkingDirectory = "/var/lib/gitea-runner/${name}"; + StandardOutPath = "/var/log/gitea-runner-${name}.log"; + StandardErrorPath = "/var/log/gitea-runner-${name}.error.log"; + EnvironmentVariables = { + PATH = (lib.makeBinPath (instance.hostPackages ++ [ cfg.package ])) + ":/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin"; + } // optionalAttrs (instance.token != null) { + TOKEN = instance.token; + }; + } // optionalAttrs (instance.tokenFile != null) { + EnvironmentVariables.__TokenFile = instance.tokenFile; + }; + } + ) cfg.instances; + + # Ensure the log directory exists + system.activationScripts.gitea-runner-logs = '' + mkdir -p /var/log/gitea-runner + mkdir -p /var/lib/gitea-runner + ''; + }; +}