diff --git a/.gitea/workflows/update-flake-lock.yaml b/.gitea/workflows/update-flake-lock.yaml new file mode 100644 index 0000000..cb2535e --- /dev/null +++ b/.gitea/workflows/update-flake-lock.yaml @@ -0,0 +1,51 @@ +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, nix] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Update flake.lock + run: nix flake update + + - name: Create PR if changed + env: + GITEA_TOKEN: ${{ secrets.KLAATU_TOKEN }} + GITEA_URL: https://src.thehellings.com + REPO: greg/nixos + run: | + if git diff --quiet flake.lock; then + echo "flake.lock unchanged, nothing to do" + exit 0 + fi + + BRANCH="auto/update-flake-lock-$(date +%Y%m%d)" + git config user.email "klaatu@thehellings.com" + git config user.name "klaatu" + git checkout -b "$BRANCH" + git add flake.lock + git commit -m "chore: update flake.lock $(date +%Y-%m-%d)" + + # Push branch using token auth + git remote set-url origin "https://klaatu:${GITEA_TOKEN}@${GITEA_URL#https://}/${REPO}.git" + git push origin "$BRANCH" + + # Create PR via Gitea API + curl -s -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + "${GITEA_URL}/api/v1/repos/${REPO}/pulls" \ + -d "{ + \"title\": \"chore: update flake.lock $(date +%Y-%m-%d)\", + \"head\": \"$BRANCH\", + \"base\": \"main\", + \"body\": \"Automated weekly flake.lock update.\\n\\nGenerated by Gitea Actions.\", + \"assignees\": [\"greg\"] + }" diff --git a/.gitea/workflows/update-manifests.yaml b/.gitea/workflows/update-manifests.yaml new file mode 100644 index 0000000..1723dc9 --- /dev/null +++ b/.gitea/workflows/update-manifests.yaml @@ -0,0 +1,58 @@ +name: Update manifest chart versions + +on: + schedule: + - cron: "0 0 * * 1" # Every Monday at midnight UTC + workflow_dispatch: + +jobs: + update-manifests: + runs-on: [self-hosted, nix] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Scan manifests for chart version updates + run: | + echo "TODO: implement manifest update scanning" + echo "" + echo "Planned implementation:" + echo " 1. Parse each manifests/*/chart.yaml for HelmRelease chart versions" + echo " 2. Query artifact hub or helm repo for latest versions" + echo " 3. Emit a diff of available updates" + echo "" + echo "Scanned manifests directories:" + ls manifests/ + + - name: Create PR if changes found + env: + GITEA_TOKEN: ${{ secrets.KLAATU_TOKEN }} + GITEA_URL: https://src.thehellings.com + REPO: greg/nixos + run: | + if git diff --quiet; then + echo "No manifest changes, nothing to do" + exit 0 + fi + + BRANCH="auto/update-manifests-$(date +%Y%m%d)" + git config user.email "klaatu@thehellings.com" + git config user.name "klaatu" + git checkout -b "$BRANCH" + git add manifests/ + git commit -m "chore: update manifest chart versions $(date +%Y-%m-%d)" + + git remote set-url origin "https://klaatu:${GITEA_TOKEN}@${GITEA_URL#https://}/${REPO}.git" + git push origin "$BRANCH" + + curl -s -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + "${GITEA_URL}/api/v1/repos/${REPO}/pulls" \ + -d "{ + \"title\": \"chore: update manifest chart versions $(date +%Y-%m-%d)\", + \"head\": \"$BRANCH\", + \"base\": \"main\", + \"body\": \"Automated weekly manifest chart version update.\\n\\nGenerated by Gitea Actions.\", + \"assignees\": [\"greg\"] + }" diff --git a/manifests/gitea-runner/chart.yaml b/manifests/gitea-runner/chart.yaml new file mode 100644 index 0000000..c0a35f8 --- /dev/null +++ b/manifests/gitea-runner/chart.yaml @@ -0,0 +1,56 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: gitea +spec: + interval: "24h" + url: https://dl.gitea.com/charts/ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: gitea-runner + namespace: gitea-runner +spec: + interval: 10m + chart: + spec: + chart: actions + version: "0.0.4" + sourceRef: + kind: HelmRepository + name: gitea + interval: "1h" + values: + rbac: + create: true + serviceAccount: + create: true + gitea: + instanceURL: https://src.thehellings.com + runnerToken: + existingSecret: gitea-runner + existingSecretKey: token + imagePullSecrets: + - name: image-pull-secrets + config: + runner: + labels: + # Ubuntu + - "ubuntu-22.04:docker://ubuntu:22.04" + - "ubuntu-24.04:docker://ubuntu:24.04" + - "ubuntu-24.10:docker://ubuntu:24.10" + # Fedora + - "fedora-41:docker://fedora:41" + - "fedora-42:docker://fedora:42" + # CentOS Stream + - "centos-stream-9:docker://quay.io/centos/centos:stream9" + - "centos-stream-10:docker://quay.io/centos/centos:stream10" + # Nix + - "nix:docker://nixos/nix:latest" + # ci-images (internal registry: src.thehellings.com/greg) + - "ci-builder:docker://src.thehellings.com/greg/builder:latest" + - "ci-vm-test:docker://src.thehellings.com/greg/vm-test:latest" + - "ci-sword:docker://src.thehellings.com/greg/sword-container-builder:latest" + - "ci-bitwarden:docker://src.thehellings.com/greg/bitwarden:latest" + - "ci-immich:docker://src.thehellings.com/greg/immich:latest" diff --git a/manifests/gitea-runner/kustomization.yaml b/manifests/gitea-runner/kustomization.yaml new file mode 100644 index 0000000..cdbf9fe --- /dev/null +++ b/manifests/gitea-runner/kustomization.yaml @@ -0,0 +1,6 @@ +namespace: gitea-runner + +resources: + - namespace.yaml + - secrets.yaml + - chart.yaml diff --git a/manifests/gitea-runner/namespace.yaml b/manifests/gitea-runner/namespace.yaml new file mode 100644 index 0000000..79e8af0 --- /dev/null +++ b/manifests/gitea-runner/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: gitea-runner diff --git a/manifests/gitea-runner/secrets.yaml b/manifests/gitea-runner/secrets.yaml new file mode 100644 index 0000000..4fb1503 --- /dev/null +++ b/manifests/gitea-runner/secrets.yaml @@ -0,0 +1,18 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: gitea-runner + namespace: gitea-runner +spec: + refreshInterval: 1h + secretStoreRef: + name: bitwarden-login + kind: ClusterSecretStore + target: + name: gitea-runner + creationPolicy: Owner + data: + - secretKey: token + remoteRef: + key: 11419680-5338-4f19-bdd9-b422007046af + property: password diff --git a/modules/nixos/gitea-runner.nix b/modules/nixos/gitea-runner.nix new file mode 100644 index 0000000..ada7a8c --- /dev/null +++ b/modules/nixos/gitea-runner.nix @@ -0,0 +1,65 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.greg.gitea-runner; + hostname = config.networking.hostName; + + # Determine extra labels based on host role + roleLabels = + if builtins.elem hostname [ "isaiah" "jeremiah" "zeke" ] then + [ "bare-metal" ] + else if hostname == "linode" then + [ "linode" ] + else + [ ]; +in +{ + options.greg.gitea-runner = { + enable = lib.mkEnableOption "Enable Gitea Actions runner (exec/shell mode)"; + + hostnameLabel = lib.mkOption { + type = lib.types.str; + default = config.networking.hostName; + description = "Label identifying this host in the runner pool (defaults to hostname)"; + }; + + tokenFile = lib.mkOption { + type = lib.types.path; + description = '' + Path to the file containing the runner registration token. + Wire in your agenix secret path here, e.g.: + config.age.secrets.gitea-runner-token.path + ''; + }; + + threads = lib.mkOption { + type = lib.types.int; + default = 4; + description = "Maximum number of concurrent jobs"; + }; + }; + + config = lib.mkIf cfg.enable { + services.gitea-actions-runner = { + package = pkgs.gitea-actions-runner; + instances.${hostname} = { + enable = true; + url = "https://src.thehellings.com"; + tokenFile = cfg.tokenFile; + labels = + [ + "self-hosted" + cfg.hostnameLabel + ] + ++ roleLabels; + settings = { + runner.capacity = cfg.threads; + }; + }; + }; + }; +}