diff --git a/.gitea/workflows/update-flake-lock.yaml b/.gitea/workflows/update-flake-lock.yaml new file mode 100644 index 0000000..23fa868 --- /dev/null +++ b/.gitea/workflows/update-flake-lock.yaml @@ -0,0 +1,57 @@ +name: Update flake.lock + +on: + schedule: + - cron: '0 0 * * 0' # Every Sunday at midnight UTC + workflow_dispatch: + +jobs: + update-flake-lock: + runs-on: [self-hosted, bare-metal] + container: + image: nixos/nix:latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Configure Nix + run: | + mkdir -p /etc/nix + echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf + + - name: Update flake.lock + run: nix flake update + + - name: Check for changes + id: changes + run: | + if git diff --quiet flake.lock; then + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Commit and open PR + if: steps.changes.outputs.changed == 'true' + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + run: | + BRANCH="automated/flake-lock-$(date +%Y%m%d)" + git config user.name "klaatu" + git config user.email "klaatu@thehellings.com" + git checkout -b "$BRANCH" + git add flake.lock + git commit -m "chore: update flake.lock" + git push origin "$BRANCH" + + # Open PR via Gitea API + curl -s -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{ + \"title\": \"chore: update flake.lock\", + \"head\": \"${BRANCH}\", + \"base\": \"main\", + \"body\": \"Automated weekly flake.lock update.\n\nGenerated by the update-flake-lock workflow.\" + }" \ + "${GITHUB_SERVER_URL%/}/api/v1/repos/${GITHUB_REPOSITORY}/pulls" diff --git a/hosts/unstable/isaiah/default.nix b/hosts/unstable/isaiah/default.nix index c50e64d..6b8ec8d 100644 --- a/hosts/unstable/isaiah/default.nix +++ b/hosts/unstable/isaiah/default.nix @@ -13,6 +13,8 @@ gitea-runner-isaiah-podman.file = ../../../secrets/gitea/runner-isaiah-podman.age; gitea-workerPassword.file = ../../../secrets/gitea/workerPassword.age; runner-reg.file = ../../../secrets/gitlab/kubernetes-k3s-local.age; + # TODO: Greg add agenix secret at secrets/gitea-runner-isaiah.age + # gitea-runner-isaiah.file = ../../../secrets/gitea-runner-isaiah.age; }; boot = { @@ -53,6 +55,12 @@ enable = true; qemu = true; }; + gitea-runner = { + enable = true; + labels = [ "self-hosted" "bare-metal" "host:isaiah" ]; + # TODO: Greg add agenix secret at secrets/gitea-runner-isaiah.age + # tokenFile = config.age.secrets.gitea-runner-isaiah.path; + }; }; networking = { diff --git a/hosts/unstable/jeremiah/default.nix b/hosts/unstable/jeremiah/default.nix index 167e324..d9a5223 100644 --- a/hosts/unstable/jeremiah/default.nix +++ b/hosts/unstable/jeremiah/default.nix @@ -29,6 +29,8 @@ in gitea-oauthSecret = mk ../../../secrets/gitea/oauthSecret.age; gitea-webhookSecret = mk ../../../secrets/gitea/webhookSecret.age; gitea-workerPassword = mk ../../../secrets/gitea/workerPassword.age; + # TODO: Greg add agenix secret at secrets/gitea-runner-jeremiah.age + # gitea-runner-jeremiah.file = ../../../secrets/gitea-runner-jeremiah.age; }; # Bootloader. @@ -96,6 +98,12 @@ in threads = 3; qemu = true; }; + gitea-runner = { + enable = true; + labels = [ "self-hosted" "bare-metal" "host:jeremiah" ]; + # TODO: Greg add agenix secret at secrets/gitea-runner-jeremiah.age + # tokenFile = config.age.secrets.gitea-runner-jeremiah.path; + }; }; hardware = { diff --git a/hosts/unstable/linode/default.nix b/hosts/unstable/linode/default.nix index b25127b..d93c1e5 100644 --- a/hosts/unstable/linode/default.nix +++ b/hosts/unstable/linode/default.nix @@ -23,6 +23,11 @@ pgloader ]; + age.secrets = { + # TODO: Greg add agenix secret at secrets/gitea-runner-linode.age + # gitea-runner-linode.file = ../../../secrets/gitea-runner-linode.age; + }; + greg = { home = false; linode.enable = true; @@ -36,6 +41,12 @@ ssl = true; }; tailscale.enable = true; + gitea-runner = { + enable = true; + labels = [ "self-hosted" "host:linode" ]; + # TODO: Greg add agenix secret at secrets/gitea-runner-linode.age + # tokenFile = config.age.secrets.gitea-runner-linode.path; + }; }; networking = { diff --git a/hosts/unstable/zeke/default.nix b/hosts/unstable/zeke/default.nix index 0ecfa6f..20c8fde 100644 --- a/hosts/unstable/zeke/default.nix +++ b/hosts/unstable/zeke/default.nix @@ -16,6 +16,8 @@ age.secrets = { gitea-workerPassword.file = ../../../secrets/gitea/workerPassword.age; + # TODO: Greg add agenix secret at secrets/gitea-runner-zeke.age + # gitea-runner-zeke.file = ../../../secrets/gitea-runner-zeke.age; }; boot.extraModulePackages = [ config.boot.kernelPackages.v4l2loopback ]; @@ -32,6 +34,12 @@ enable = true; vbox = false; }; + gitea-runner = { + enable = true; + labels = [ "self-hosted" "bare-metal" "host:zeke" ]; + # TODO: Greg add agenix secret at secrets/gitea-runner-zeke.age + # tokenFile = config.age.secrets.gitea-runner-zeke.path; + }; tailscale = { enable = true; tags = [ "home" ]; diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 9296ee6..f13915b 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -8,6 +8,7 @@ ./backup.nix ./ceph.nix ./db.nix + ./gitea-runner.nix ./gitlab-runner.nix ./gnome.nix ./home.nix diff --git a/modules/nixos/gitea-runner.nix b/modules/nixos/gitea-runner.nix new file mode 100644 index 0000000..f1cfb50 --- /dev/null +++ b/modules/nixos/gitea-runner.nix @@ -0,0 +1,88 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.greg.gitea-runner; +in +{ + options.greg.gitea-runner = { + enable = lib.mkEnableOption "Enable Gitea act_runner (shell mode)"; + + instanceURL = lib.mkOption { + type = lib.types.str; + default = "https://src.thehellings.com"; + description = "URL of the Gitea instance to connect to"; + }; + + name = lib.mkOption { + type = lib.types.str; + default = config.networking.hostName; + description = "Name of the runner (defaults to hostname)"; + }; + + labels = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ "self-hosted" ]; + description = "Labels to assign to this runner"; + }; + + tokenFile = lib.mkOption { + type = lib.types.path; + description = "Path to a file containing the runner registration token (from agenix)"; + }; + }; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ pkgs.gitea-actions-runner ]; + + systemd.services.gitea-runner = { + description = "Gitea Actions Runner"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + environment = { + GITEA_INSTANCE_URL = cfg.instanceURL; + GITEA_RUNNER_NAME = cfg.name; + GITEA_RUNNER_LABELS = lib.concatStringsSep "," cfg.labels; + HOME = "/var/lib/gitea-runner"; + }; + + serviceConfig = { + Type = "simple"; + User = "gitea-runner"; + Group = "gitea-runner"; + StateDirectory = "gitea-runner"; + WorkingDirectory = "/var/lib/gitea-runner"; + ExecStartPre = pkgs.writeShellScript "gitea-runner-register" '' + set -euo pipefail + CONFIG_FILE="/var/lib/gitea-runner/.runner" + if [ ! -f "$CONFIG_FILE" ]; then + TOKEN="$(cat ${cfg.tokenFile})" + ${pkgs.gitea-actions-runner}/bin/act_runner register \ + --no-interactive \ + --instance "$GITEA_INSTANCE_URL" \ + --token "$TOKEN" \ + --name "$GITEA_RUNNER_NAME" \ + --labels "$GITEA_RUNNER_LABELS" + fi + ''; + ExecStart = "${pkgs.gitea-actions-runner}/bin/act_runner daemon"; + Restart = "on-failure"; + RestartSec = "5s"; + }; + }; + + users.users.gitea-runner = { + isSystemUser = true; + group = "gitea-runner"; + home = "/var/lib/gitea-runner"; + createHome = true; + description = "Gitea Actions Runner service user"; + }; + + users.groups.gitea-runner = { }; + }; +}