From ed796a19fe55ac73d51306f23397967a137a6faa Mon Sep 17 00:00:00 2001 From: pazpi Date: Wed, 3 Dec 2025 17:20:23 +0100 Subject: [PATCH] Add Forgejo runner and check update action --- .forgejo/workflows/auto-update.yaml | 72 ++++++++++++++++++++ hosts/forgejo-runner/default.nix | 55 +++++++++++++++ hosts/hosts.nix | 9 +++ hosts/parameters.nix | 1 + modules/services/default.nix | 1 + modules/services/forgejo-runner.nix | 100 ++++++++++++++++++++++++++++ modules/services/forgejo.nix | 3 + secrets.nix | 1 + secrets/forgejo-runner-token.age | 11 +++ ssh-keys.nix | 1 + 10 files changed, 254 insertions(+) create mode 100644 .forgejo/workflows/auto-update.yaml create mode 100644 hosts/forgejo-runner/default.nix create mode 100644 modules/services/forgejo-runner.nix create mode 100644 secrets/forgejo-runner-token.age diff --git a/.forgejo/workflows/auto-update.yaml b/.forgejo/workflows/auto-update.yaml new file mode 100644 index 0000000..23df1a9 --- /dev/null +++ b/.forgejo/workflows/auto-update.yaml @@ -0,0 +1,72 @@ +name: Weekly Flake Update + +on: + schedule: + # Every Friday at 22:00 UTC + - cron: '0 22 * * 5' + workflow_dispatch: {} + +jobs: + update: + runs-on: nix + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "Flake Update Bot" + git config user.email "bot@noreply.local" + + - name: Update flake inputs + 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: Build all hosts + if: steps.changes.outputs.changed == 'true' + run: | + nix develop -c colmena build + + - name: Create branch and commit + if: steps.changes.outputs.changed == 'true' + run: | + BRANCH_NAME="auto-update/$(date +%Y-%m-%d)" + git checkout -b "$BRANCH_NAME" + git add flake.lock + git commit -m "chore: update flake inputs $(date +%Y-%m-%d)" + git push origin "$BRANCH_NAME" + echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT + id: branch + + - name: Create Pull Request + if: steps.changes.outputs.changed == 'true' + env: + FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }} + run: | + curl -X POST \ + -H "Authorization: token $FORGEJO_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "title": "chore: weekly flake update", + "body": "Automated flake update from CI.\n\nThis PR updates all flake inputs and has been verified to build successfully.\n\nGenerated on: '"$(date -Iseconds)"'", + "head": "'"${{ steps.branch.outputs.branch_name }}"'", + "base": "master" + }' \ + "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/pulls" + + - name: Cleanup + if: always() + run: | + nix-collect-garbage -d + rm -rf result .direnv + diff --git a/hosts/forgejo-runner/default.nix b/hosts/forgejo-runner/default.nix new file mode 100644 index 0000000..c98974e --- /dev/null +++ b/hosts/forgejo-runner/default.nix @@ -0,0 +1,55 @@ +{ + config, + pkgs, + lib, + ... +}: +let + p = import ../parameters.nix; +in +{ + + age.secrets.forgejo-runner-token.file = ../../secrets/forgejo-runner-token.age; + + nix.settings = { + download-buffer-size = 524288000; # 500 MiB + }; + + my = { + utils = { + commons.enable = true; + lxc-standard.enable = true; + }; + + services.forgejo-runner = { + enable = true; + url = "https://git.${p.domains.public}"; + tokenFile = config.age.secrets.forgejo-runner-token.path; + name = "nix-runner"; + labels = [ + "nix:host" + "native:host" + ]; + }; + + virtualisation.proxmox.enable = true; + }; + + # Extra packages needed for CI operations + environment.systemPackages = with pkgs; [ + git + colmena + jq + curl + just + ]; + + # Allow the runner to use nix-daemon + nix.settings.trusted-users = [ + "root" + "gitea-runner" + ]; + + system.stateVersion = "25.11"; +} + diff --git a/hosts/hosts.nix b/hosts/hosts.nix index 69e96bb..b120895 100644 --- a/hosts/hosts.nix +++ b/hosts/hosts.nix @@ -82,6 +82,15 @@ ]; }; + forgejo-runner = { + module = ./forgejo-runner; + tags = [ + "lxc" + "bacco" + "forgejo" + ]; + }; + immich = { module = ./immich; tags = [ diff --git a/hosts/parameters.nix b/hosts/parameters.nix index 958c736..5e36ba4 100644 --- a/hosts/parameters.nix +++ b/hosts/parameters.nix @@ -29,6 +29,7 @@ in paperless = "paperless.${private-domain}"; zigbee2mqtt = "zigbee2mqtt.${private-domain}"; forgejo = "forgejo.${private-domain}"; + forgejo-runner = "forgejo-runner.${private-domain}"; n8n = "n8n.${private-domain}"; }; email = "davide@${public-domain}"; diff --git a/modules/services/default.nix b/modules/services/default.nix index 31fc954..3941b66 100644 --- a/modules/services/default.nix +++ b/modules/services/default.nix @@ -4,6 +4,7 @@ ./dashy.nix ./firefly-iii.nix ./forgejo.nix + ./forgejo-runner.nix ./immich.nix ./media-mgr.nix ./n8n.nix diff --git a/modules/services/forgejo-runner.nix b/modules/services/forgejo-runner.nix new file mode 100644 index 0000000..d586da1 --- /dev/null +++ b/modules/services/forgejo-runner.nix @@ -0,0 +1,100 @@ +{ + lib, + config, + pkgs, + ... +}: +let + cfg = config.my.services.forgejo-runner; +in +{ + + options.my.services.forgejo-runner = { + enable = lib.mkEnableOption "Enable Forgejo Actions runner"; + + url = lib.mkOption { + type = lib.types.str; + description = "URL of the Forgejo instance"; + example = "https://git.example.com"; + }; + + tokenFile = lib.mkOption { + type = lib.types.path; + description = "Path to file containing the runner registration token"; + }; + + name = lib.mkOption { + type = lib.types.str; + default = config.networking.hostName; + description = "Name of the runner"; + }; + + labels = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ + "nix:host" + "native:host" + ]; + description = "Labels for the runner"; + }; + }; + + config = lib.mkIf cfg.enable { + + # Ensure Nix is available with flakes enabled (should already be the case) + nix.settings.experimental-features = [ + "nix-command" + "flakes" + ]; + + # Install packages needed for CI jobs + environment.systemPackages = with pkgs; [ + git + nix + colmena + jq + curl + ]; + + services.gitea-actions-runner = { + package = pkgs.forgejo-runner; + instances.default = { + enable = true; + name = cfg.name; + url = cfg.url; + tokenFile = cfg.tokenFile; + labels = cfg.labels; + settings = { + runner = { + # Capacity defines how many jobs can run concurrently + capacity = 1; + # Timeout for a job + timeout = "6h"; + }; + container = { + # Disable container mode - run directly on host + # This allows using nix commands directly + network = ""; + privileged = false; + options = ""; + workdir_parent = ""; + }; + }; + hostPackages = with pkgs; [ + bash + coreutils + curl + gawk + git + gnused + jq + nix + nodejs + wget + ]; + }; + }; + + }; +} + diff --git a/modules/services/forgejo.nix b/modules/services/forgejo.nix index 30ee6a0..052adad 100644 --- a/modules/services/forgejo.nix +++ b/modules/services/forgejo.nix @@ -86,6 +86,9 @@ in SSH_PORT = sshPort; HTTP_PORT = httpPort; }; + actions = { + ENABLED = true; + }; } cfg.settings; }; diff --git a/secrets.nix b/secrets.nix index 42e023b..826e165 100644 --- a/secrets.nix +++ b/secrets.nix @@ -30,6 +30,7 @@ let machines.forgejo machines.firefly-iii ]; + forgejo-runner-token = [ machines.forgejo-runner ]; }; in builtins.listToAttrs ( diff --git a/secrets/forgejo-runner-token.age b/secrets/forgejo-runner-token.age new file mode 100644 index 0000000..4ed8f05 --- /dev/null +++ b/secrets/forgejo-runner-token.age @@ -0,0 +1,11 @@ +age-encryption.org/v1 +-> ssh-ed25519 kElbzA boFBSR0io7H16hT82MZajpHBFD9TiJvHVgeF7bu0WVo +GJ2xblkP5ofTlXstlhdvM8uPsFu6bKacHznk3npxTR4 +-> ssh-ed25519 uqg2jw M+xMJUwVlUNZZuewkJJepaCNpJ1ZEMZ0CdeSaTsBS0Q +2q6qZSY8d9mOQr1RgfO7seqqrTn9JAQXR2tPBZfqYUI +-> ssh-ed25519 a0HhMw Fkyzj84jmJaegJxcC6hwpfH7uxgfNIuthNOM0nbF4ig +ouM9HuShAnQ612Ot6a0+FfzgOR60+HZQtB0qw8l/6jw +--- 99lNeBy8ngZyZ8KCY3tiI9tU1QqGJliFT6HZQrmDH4Q +¹§~¥FC›GÂk!@³(Úpèä×%¦ÁÖoüÕMA‰jˆ~¶7ìZ#òf‘ +· +-Qb:Sô˜.ÎÖëþ¹ÞCAj­†ú