Compare commits

...
Author SHA1 Message Date
claude-botandClaude Opus 5.5 5528ccbd0b chore: default branch main
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
Pipeline branch filters and PR bases, Flux GitRepository ref, image automation
checkout and push, restore-test, vmtest and bootstrap.sh. Merge right before
the master -> main rename.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 10:57:20 +02:00
22 changed files with 49 additions and 49 deletions
+1 -1
View File
@@ -31,7 +31,7 @@
# - cron : a cron NAMED exactly "alert-monitor" (name filter, same # - cron : a cron NAMED exactly "alert-monitor" (name filter, same
# mechanism as update-audit.yml): # mechanism as update-audit.yml):
# woodpecker repo cron add --repo konairius/homelab \ # woodpecker repo cron add --repo konairius/homelab \
# --name alert-monitor --branch master --schedule '*/15 * * * *' # --name alert-monitor --branch main --schedule '*/15 * * * *'
# - deploy : woodpecker-cli pipeline deploy konairius/homelab <n> alert-monitor # - deploy : woodpecker-cli pipeline deploy konairius/homelab <n> alert-monitor
# where <n> is an existing pipeline to promote. # where <n> is an existing pipeline to promote.
when: when:
+2 -2
View File
@@ -27,7 +27,7 @@
# Note this pipeline runs no LLM agent, so the exfil path that motivated the # Note this pipeline runs no LLM agent, so the exfil path that motivated the
# other cutovers does not apply to it. # other cutovers does not apply to it.
# #
# Push builds run on master only. Without the branch filter a feature branch # Push builds run on main only. Without the branch filter a feature branch
# that touches this file started all steps at once: it pushed unreviewed # that touches this file started all steps at once: it pushed unreviewed
# images and used the whole woodpecker-ci-quota, so the PR checks could not # images and used the whole woodpecker-ci-quota, so the PR checks could not
# get a pod (REN-286). # get a pod (REN-286).
@@ -36,7 +36,7 @@
# image, and in parallel they exceed the woodpecker-ci-quota. # image, and in parallel they exceed the woodpecker-ci-quota.
when: when:
- event: push - event: push
branch: master branch: main
path: path:
- "ci/images/**" - "ci/images/**"
- "secret-rotator/**" - "secret-rotator/**"
+7 -7
View File
@@ -46,20 +46,20 @@
# push/cron/manual events this pipeline fires on. # push/cron/manual events this pipeline fires on.
# #
# OWNER SETUP — the token + secret above are already provisioned. The one # OWNER SETUP — the token + secret above are already provisioned. The one
# remaining step, to be run AFTER this merges to master (a cron references a # remaining step, to be run AFTER this merges to main (a cron references a
# pipeline that must exist on the target branch), is to register the schedule: # pipeline that must exist on the target branch), is to register the schedule:
# woodpecker repo cron add --repo konairius/homelab \ # woodpecker repo cron add --repo konairius/homelab \
# --name ci-claude-refresh --branch master --schedule '@weekly' # --name ci-claude-refresh --branch main --schedule '@weekly'
# Weekly is plenty; the pipelines tolerate being a few days behind a release. # Weekly is plenty; the pipelines tolerate being a few days behind a release.
# #
# Triggering: # Triggering:
# - cron : the cron NAMED exactly "ci-claude-refresh" (see above). # - cron : the cron NAMED exactly "ci-claude-refresh" (see above).
# - deploy : woodpecker-cli pipeline deploy konairius/homelab <n> ci-claude-refresh # - deploy : woodpecker-cli pipeline deploy konairius/homelab <n> ci-claude-refresh
# where <n> is an existing pipeline to promote. # where <n> is an existing pipeline to promote.
# - push : a change to the Containerfile (or this file) ON master forces a # - push : a change to the Containerfile (or this file) ON main forces a
# rebuild of the current latest version so Containerfile fixes ship # rebuild of the current latest version so Containerfile fixes ship
# promptly. Restricted to master ON PURPOSE — a feature branch must # promptly. Restricted to main ON PURPOSE — a feature branch must
# never build/push an image or open a bump PR (only master pushes # never build/push an image or open a bump PR (only main pushes
# images), and without this filter every PR that edits these paths # images), and without this filter every PR that edits these paths
# would do exactly that from its own branch. # would do exactly that from its own branch.
when: when:
@@ -68,7 +68,7 @@ when:
- event: deployment - event: deployment
evaluate: 'CI_PIPELINE_DEPLOY_TARGET == "ci-claude-refresh"' evaluate: 'CI_PIPELINE_DEPLOY_TARGET == "ci-claude-refresh"'
- event: push - event: push
branch: master branch: main
path: path:
- "ci/images/claude/**" - "ci/images/claude/**"
- ".woodpecker/ci-claude-refresh.yml" - ".woodpecker/ci-claude-refresh.yml"
@@ -208,7 +208,7 @@ steps:
jq -n --arg title "chore(ci): bump ci-claude image to $$NEW" \ jq -n --arg title "chore(ci): bump ci-claude image to $$NEW" \
--rawfile body /tmp/pr-body.md \ --rawfile body /tmp/pr-body.md \
--arg head "$$BRANCH" \ --arg head "$$BRANCH" \
'{title: $$title, body: $$body, head: $$head, base: "master"}' > /tmp/pr.json '{title: $$title, body: $$body, head: $$head, base: "main"}' > /tmp/pr.json
code=$$(curl -s -o /tmp/resp.json -w '%{http_code}' \ code=$$(curl -s -o /tmp/resp.json -w '%{http_code}' \
-X POST -H "Authorization: token $$PUSH_TOKEN" \ -X POST -H "Authorization: token $$PUSH_TOKEN" \
-H "Content-Type: application/json" --data @/tmp/pr.json "$$API/pulls") -H "Content-Type: application/json" --data @/tmp/pr.json "$$API/pulls")
+2 -2
View File
@@ -1,7 +1,7 @@
when: when:
# Deploy only on master (merge) + manual — never auto-deploy from a branch. # Deploy only on main (merge) + manual — never auto-deploy from a branch.
- event: push - event: push
branch: master branch: main
path: path:
- "ansible/roles/claude-workstation/**" - "ansible/roles/claude-workstation/**"
- "ansible/plays/install-claude-workstation.yml" - "ansible/plays/install-claude-workstation.yml"
+2 -2
View File
@@ -1,7 +1,7 @@
when: when:
# Deploy only on master (merge) + manual — never auto-deploy from a branch. # Deploy only on main (merge) + manual — never auto-deploy from a branch.
- event: push - event: push
branch: master branch: main
path: path:
- "ansible/roles/mqtt-bridge/**" - "ansible/roles/mqtt-bridge/**"
- "ansible/plays/edge-mqtt-bridge.yml" - "ansible/plays/edge-mqtt-bridge.yml"
+2 -2
View File
@@ -1,10 +1,10 @@
when: when:
# Plan only on master (merge) + manual — a push trigger without this gate # Plan only on main (merge) + manual — a push trigger without this gate
# would run `tofu plan` (which evaluates provider/data-source code) with # would run `tofu plan` (which evaluates provider/data-source code) with
# all proxmox/hetzner/unifi secrets mounted for any pushed branch, # all proxmox/hetzner/unifi secrets mounted for any pushed branch,
# including malicious feature-branch .tf. # including malicious feature-branch .tf.
- event: push - event: push
branch: master branch: main
path: path:
- "opentofu/**" - "opentofu/**"
- ".woodpecker/deploy-infrastructure.yml" - ".woodpecker/deploy-infrastructure.yml"
+2 -2
View File
@@ -1,7 +1,7 @@
when: when:
# Deploy only on master (merge) + manual — never auto-deploy from a branch. # Deploy only on main (merge) + manual — never auto-deploy from a branch.
- event: push - event: push
branch: master branch: main
path: path:
- "ansible/roles/netbird-client/**" - "ansible/roles/netbird-client/**"
- "ansible/plays/install-netbird-client.yml" - "ansible/plays/install-netbird-client.yml"
+2 -2
View File
@@ -1,7 +1,7 @@
when: when:
# Deploy only on master (merge) + manual — never auto-deploy from a branch. # Deploy only on main (merge) + manual — never auto-deploy from a branch.
- event: push - event: push
branch: master branch: main
path: path:
- "ansible/roles/netbird-proxy/**" - "ansible/roles/netbird-proxy/**"
# install-netbird-proxy.yml also applies the netbird-proxy-watchdog role, # install-netbird-proxy.yml also applies the netbird-proxy-watchdog role,
+2 -2
View File
@@ -1,7 +1,7 @@
when: when:
# Deploy only on master (merge) + manual — never auto-deploy from a branch. # Deploy only on main (merge) + manual — never auto-deploy from a branch.
- event: push - event: push
branch: master branch: main
path: path:
- "ansible/roles/netbird-server/**" - "ansible/roles/netbird-server/**"
- "ansible/plays/install-netbird-server.yml" - "ansible/plays/install-netbird-server.yml"
+2 -2
View File
@@ -1,7 +1,7 @@
when: when:
# Deploy only on master (merge) + manual — never auto-deploy from a branch. # Deploy only on main (merge) + manual — never auto-deploy from a branch.
- event: push - event: push
branch: master branch: main
path: path:
- "ansible/roles/uptime-kuma/**" - "ansible/roles/uptime-kuma/**"
- "ansible/plays/install-uptime-kuma.yml" - "ansible/plays/install-uptime-kuma.yml"
+1 -1
View File
@@ -2,7 +2,7 @@
# gitea.renner.uno/konairius/hermes:build.<unix-ts> and :latest. # gitea.renner.uno/konairius/hermes:build.<unix-ts> and :latest.
when: when:
- event: push - event: push
branch: master branch: main
path: path:
- "ci/images/hermes/**" - "ci/images/hermes/**"
- ".woodpecker/hermes-image.yml" - ".woodpecker/hermes-image.yml"
+2 -2
View File
@@ -33,7 +33,7 @@
# Triggering: # Triggering:
# - cron : a cron NAMED exactly "issue-fix": # - cron : a cron NAMED exactly "issue-fix":
# woodpecker repo cron add --repo konairius/homelab \ # woodpecker repo cron add --repo konairius/homelab \
# --name issue-fix --branch master --schedule '41 * * * *' # --name issue-fix --branch main --schedule '41 * * * *'
# - deploy : woodpecker-cli pipeline deploy konairius/homelab <n> issue-fix # - deploy : woodpecker-cli pipeline deploy konairius/homelab <n> issue-fix
# where <n> is an existing pipeline to promote. # where <n> is an existing pipeline to promote.
when: when:
@@ -199,7 +199,7 @@ steps:
git push "https://$$PUSH_TOKEN@gitea.renner.uno/konairius/homelab.git" HEAD:"$$BRANCH" git push "https://$$PUSH_TOKEN@gitea.renner.uno/konairius/homelab.git" HEAD:"$$BRANCH"
jq -n --arg title "$$TITLE" --rawfile body /tmp/alert-fix/summary.md \ jq -n --arg title "$$TITLE" --rawfile body /tmp/alert-fix/summary.md \
--arg head "$$BRANCH" \ --arg head "$$BRANCH" \
'{title: $$title, body: $$body, head: $$head, base: "master"}' > /tmp/gitea-pr.json '{title: $$title, body: $$body, head: $$head, base: "main"}' > /tmp/gitea-pr.json
code=$$(curl -s -o /tmp/gitea-resp.json -w '%{http_code}' \ code=$$(curl -s -o /tmp/gitea-resp.json -w '%{http_code}' \
-X POST -H "Authorization: token $$PUSH_TOKEN" \ -X POST -H "Authorization: token $$PUSH_TOKEN" \
-H "Content-Type: application/json" --data @/tmp/gitea-pr.json \ -H "Content-Type: application/json" --data @/tmp/gitea-pr.json \
+1 -1
View File
@@ -13,7 +13,7 @@
# Triggers on pull_request: PR opened AND new commits pushed to an open PR. # Triggers on pull_request: PR opened AND new commits pushed to an open PR.
# Approves only when the review found nothing red/yellow (see run.sh); humans merge. # Approves only when the review found nothing red/yellow (see run.sh); humans merge.
# #
# The central code is cloned from public homelab@master on every run, never taken # The central code is cloned from public homelab@main on every run, never taken
# from the PR checkout, so a PR cannot alter the rubric or helper scripts it is # from the PR checkout, so a PR cannot alter the rubric or helper scripts it is
# reviewed with. # reviewed with.
# #
+3 -3
View File
@@ -65,11 +65,11 @@ steps:
failure: ignore failure: ignore
- name: security-fix-agent - name: security-fix-agent
# Auto-fix run: only on master (cron / manual / direct push). On the # Auto-fix run: only on main (cron / manual / direct push). On the
# bot's own PR branches, the scans re-run as a re-validation gate but # bot's own PR branches, the scans re-run as a re-validation gate but
# this step is skipped — otherwise we'd fork-bomb PRs. # this step is skipped — otherwise we'd fork-bomb PRs.
when: when:
- branch: master - branch: main
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.303 image: gitea.renner.uno/gitea_admin/ci-claude:2.1.303
environment: environment:
CLAUDE_CODE_OAUTH_TOKEN: CLAUDE_CODE_OAUTH_TOKEN:
@@ -152,7 +152,7 @@ steps:
--arg title "$$TITLE" \ --arg title "$$TITLE" \
--arg body "$$BODY" \ --arg body "$$BODY" \
--arg head "$$BRANCH" \ --arg head "$$BRANCH" \
'{title: $$title, body: $$body, head: $$head, base: "master"}' \ '{title: $$title, body: $$body, head: $$head, base: "main"}' \
| curl -sfL -X POST \ | curl -sfL -X POST \
-H "Authorization: token $$GITEA_TOKEN" \ -H "Authorization: token $$GITEA_TOKEN" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
+1 -1
View File
@@ -15,7 +15,7 @@
# name filter is the only thing that can select a workflow for a # name filter is the only thing that can select a workflow for a
# scheduled run: # scheduled run:
# woodpecker repo cron add --repo konairius/homelab \ # woodpecker repo cron add --repo konairius/homelab \
# --name update-audit --branch master --schedule '@weekly' # --name update-audit --branch main --schedule '@weekly'
# - deploy : woodpecker-cli pipeline deploy konairius/homelab <n> update-audit # - deploy : woodpecker-cli pipeline deploy konairius/homelab <n> update-audit
# where <n> is an existing pipeline to promote. # where <n> is an existing pipeline to promote.
# #
+2 -2
View File
@@ -65,7 +65,7 @@ AUTH="Authorization: token $REVIEW_TOKEN"
WS="$PWD" # workspace = this repo, checked out at the PR head by Woodpecker WS="$PWD" # workspace = this repo, checked out at the PR head by Woodpecker
MAX_DIFF_LINES=20000 MAX_DIFF_LINES=20000
# This script, the prompts and scripts/ci/ all come from the homelab@master # This script, the prompts and scripts/ci/ all come from the homelab@main
# clone the per-repo stub made (see .woodpecker/pr-review.yml) — never from the # clone the per-repo stub made (see .woodpecker/pr-review.yml) — never from the
# PR checkout, so a PR cannot change the rubric or the helper scripts it is # PR checkout, so a PR cannot change the rubric or the helper scripts it is
# reviewed with. # reviewed with.
@@ -115,7 +115,7 @@ while IFS= read -r ITEM; do
# event, so Woodpecker's built-in clone already checked THIS repo out # event, so Woodpecker's built-in clone already checked THIS repo out
# at the PR head in $WS — the agents (which cd into $WS) read it # at the PR head in $WS — the agents (which cd into $WS) read it
# directly for context. The old cron model had to clone each target # directly for context. The old cron model had to clone each target
# repo by hand (its workspace was homelab@master), and that clone # repo by hand (its workspace was homelab@main), and that clone
# embedded REVIEW_TOKEN in the URL, persisting a write-scoped PAT in # embedded REVIEW_TOKEN in the URL, persisting a write-scoped PAT in
# work/target/.git/config — readable by the review agent whose report # work/target/.git/config — readable by the review agent whose report
# is posted publicly. Per-repo pull_request triggering makes the manual # is posted publicly. Per-repo pull_request triggering makes the manual
+1 -1
View File
@@ -309,7 +309,7 @@ data:
# Mosquitto MQTT broker (ClusterIP, home-assistant ns). A TCP-connect # Mosquitto MQTT broker (ClusterIP, home-assistant ns). A TCP-connect
# check on :1883: the broker's image tag is auto-bumped by Flux # check on :1883: the broker's image tag is auto-bumped by Flux
# image-automation straight to master (no CI gate), and the deployment # image-automation straight to main (no CI gate), and the deployment
# is a single Recreate/rolling pod, so a bad bump that fails to come up # is a single Recreate/rolling pod, so a bad bump that fails to come up
# would otherwise be silent. This turns that into an alert. # would otherwise be silent. This turns that into an alert.
- name: Infrastructure 4 - name: Infrastructure 4
+6 -6
View File
@@ -93,18 +93,18 @@ GITHUB_REPO="${GITHUB_REPO:-Homelab}"
GHCR_PULL_USER="${GHCR_PULL_USER:-konairius}" GHCR_PULL_USER="${GHCR_PULL_USER:-konairius}"
FLUX_PATH="kubernetes/clusters/homelab" FLUX_PATH="kubernetes/clusters/homelab"
# Branch Flux reconciles from, and that `flux bootstrap` commits its own sync # Branch Flux reconciles from, and that `flux bootstrap` commits its own sync
# manifests into. master for a real rebuild. # manifests into. main for a real rebuild.
# #
# Overridable so the phase can be rehearsed without writing to master — point it # Overridable so the phase can be rehearsed without writing to main — point it
# at a throwaway branch, which has to exist already: `flux bootstrap` clones the # at a throwaway branch, which has to exist already: `flux bootstrap` clones the
# branch and fails with `couldn't find remote ref` rather than creating it. # branch and fails with `couldn't find remote ref` rather than creating it.
# #
# git push origin origin/master:refs/heads/rehearsal-1 # git push origin origin/main:refs/heads/rehearsal-1
# FLUX_BRANCH=rehearsal-1 ./bootstrap.sh flux # FLUX_BRANCH=rehearsal-1 ./bootstrap.sh flux
# #
# Nothing else about the phase changes, which is the point. Delete the branch # Nothing else about the phase changes, which is the point. Delete the branch
# afterwards. # afterwards.
FLUX_BRANCH="${FLUX_BRANCH:-master}" FLUX_BRANCH="${FLUX_BRANCH:-main}"
SOPS_KEY="$HOME/.config/sops/age/keys.txt" SOPS_KEY="$HOME/.config/sops/age/keys.txt"
PHASE="${1:-all}" PHASE="${1:-all}"
@@ -1475,8 +1475,8 @@ if [[ "$PHASE" == "vmtest" ]]; then
# GITEA_TOKEN and a FLUX_BRANCH to write to, because `flux bootstrap` # GITEA_TOKEN and a FLUX_BRANCH to write to, because `flux bootstrap`
# commits its sync manifests into the branch it reconciles. # commits its sync manifests into the branch it reconciles.
if [[ "${VMTEST_FULL:-0}" == "1" ]]; then if [[ "${VMTEST_FULL:-0}" == "1" ]]; then
[[ "$FLUX_BRANCH" != "master" ]] \ [[ "$FLUX_BRANCH" != "main" ]] \
|| fail "VMTEST_FULL would have flux bootstrap commit into master — point FLUX_BRANCH at a throwaway branch that already exists" || fail "VMTEST_FULL would have flux bootstrap commit into main — point FLUX_BRANCH at a throwaway branch that already exists"
echo -e "${YELLOW}Continuing into the flux phase against branch ${FLUX_BRANCH}.${NC}" echo -e "${YELLOW}Continuing into the flux phase against branch ${FLUX_BRANCH}.${NC}"
PHASE=all PHASE=all
else else
@@ -8,7 +8,7 @@ metadata:
spec: spec:
interval: 1m0s interval: 1m0s
ref: ref:
branch: master branch: main
secretRef: secretRef:
name: flux-system name: flux-system
url: https://gitea.renner.uno/konairius/homelab.git url: https://gitea.renner.uno/konairius/homelab.git
@@ -11,9 +11,9 @@ spec:
# owner, which is the `flux` Gitea account (uid 9) — not # owner, which is the `flux` Gitea account (uid 9) — not
# gitea_admin, as this comment used to say. Evidence: the flux # gitea_admin, as this comment used to say. Evidence: the flux
# account's contribution history matches every # account's contribution history matches every
# `chore(image-automation)` commit on master 1:1, while # `chore(image-automation)` commit on main 1:1, while
# gitea_admin's own contributions stop at 2026-07-21. That account # gitea_admin's own contributions stop at 2026-07-21. That account
# therefore has to keep push access to master, or writeback fails # therefore has to keep push access to main, or writeback fails
# silently — no commit is attempted unless a tracked image moves. # silently — no commit is attempted unless a tracked image moves.
# The commit author overridden below to security-bot@renner.uno is # The commit author overridden below to security-bot@renner.uno is
# the author field only; it says nothing about who pushes. # the author field only; it says nothing about who pushes.
@@ -23,7 +23,7 @@ spec:
git: git:
checkout: checkout:
ref: ref:
branch: master branch: main
commit: commit:
author: author:
email: security-bot@renner.uno email: security-bot@renner.uno
@@ -33,7 +33,7 @@ spec:
Updates managed by image-automation-controller. Updates managed by image-automation-controller.
push: push:
branch: master branch: main
update: update:
path: ./kubernetes path: ./kubernetes
strategy: Setters strategy: Setters
+1 -1
View File
@@ -13,7 +13,7 @@ spec:
interval: 10m interval: 10m
url: ssh://git@github.com/konairius/Homelab.git url: ssh://git@github.com/konairius/Homelab.git
ref: ref:
branch: master branch: main
# Read-only deploy key, created per run by bootstrap.sh. # Read-only deploy key, created per run by bootstrap.sh.
secretRef: secretRef:
name: restore-test-git name: restore-test-git
+2 -2
View File
@@ -85,9 +85,9 @@ spec:
# monitor socket under it and sun_path caps the path at 108 bytes. # monitor socket under it and sun_path caps the path at 108 bytes.
- name: VM_STATE - name: VM_STATE
value: /work/vm value: /work/vm
# Which branch to test. master unless a run is checking a change. # Which branch to test. main unless a run is checking a change.
- name: BRANCH - name: BRANCH
value: master value: main
# Secrets are streamed in here at the moment the run needs them, # Secrets are streamed in here at the moment the run needs them,
# never baked into the image and never stored as a Secret. They live # never baked into the image and never stored as a Secret. They live
# in this emptyDir for the length of the Job and go with it — so # in this emptyDir for the length of the Job and go with it — so