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
23 changed files with 50 additions and 50 deletions
+1 -1
View File
@@ -31,7 +31,7 @@
# - cron : a cron NAMED exactly "alert-monitor" (name filter, same
# mechanism as update-audit.yml):
# 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
# where <n> is an existing pipeline to promote.
when:
+2 -2
View File
@@ -27,7 +27,7 @@
# Note this pipeline runs no LLM agent, so the exfil path that motivated the
# 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
# images and used the whole woodpecker-ci-quota, so the PR checks could not
# get a pod (REN-286).
@@ -36,7 +36,7 @@
# image, and in parallel they exceed the woodpecker-ci-quota.
when:
- event: push
branch: master
branch: main
path:
- "ci/images/**"
- "secret-rotator/**"
+7 -7
View File
@@ -46,20 +46,20 @@
# push/cron/manual events this pipeline fires on.
#
# 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:
# 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.
#
# Triggering:
# - cron : the cron NAMED exactly "ci-claude-refresh" (see above).
# - deploy : woodpecker-cli pipeline deploy konairius/homelab <n> ci-claude-refresh
# 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
# promptly. Restricted to master ON PURPOSE — a feature branch must
# never build/push an image or open a bump PR (only master pushes
# promptly. Restricted to main ON PURPOSE — a feature branch must
# never build/push an image or open a bump PR (only main pushes
# images), and without this filter every PR that edits these paths
# would do exactly that from its own branch.
when:
@@ -68,7 +68,7 @@ when:
- event: deployment
evaluate: 'CI_PIPELINE_DEPLOY_TARGET == "ci-claude-refresh"'
- event: push
branch: master
branch: main
path:
- "ci/images/claude/**"
- ".woodpecker/ci-claude-refresh.yml"
@@ -208,7 +208,7 @@ steps:
jq -n --arg title "chore(ci): bump ci-claude image to $$NEW" \
--rawfile body /tmp/pr-body.md \
--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}' \
-X POST -H "Authorization: token $$PUSH_TOKEN" \
-H "Content-Type: application/json" --data @/tmp/pr.json "$$API/pulls")
+2 -2
View File
@@ -1,7 +1,7 @@
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
branch: master
branch: main
path:
- "ansible/roles/claude-workstation/**"
- "ansible/plays/install-claude-workstation.yml"
+2 -2
View File
@@ -1,7 +1,7 @@
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
branch: master
branch: main
path:
- "ansible/roles/mqtt-bridge/**"
- "ansible/plays/edge-mqtt-bridge.yml"
+2 -2
View File
@@ -1,10 +1,10 @@
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
# all proxmox/hetzner/unifi secrets mounted for any pushed branch,
# including malicious feature-branch .tf.
- event: push
branch: master
branch: main
path:
- "opentofu/**"
- ".woodpecker/deploy-infrastructure.yml"
+2 -2
View File
@@ -1,7 +1,7 @@
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
branch: master
branch: main
path:
- "ansible/roles/netbird-client/**"
- "ansible/plays/install-netbird-client.yml"
+2 -2
View File
@@ -1,7 +1,7 @@
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
branch: master
branch: main
path:
- "ansible/roles/netbird-proxy/**"
# install-netbird-proxy.yml also applies the netbird-proxy-watchdog role,
+2 -2
View File
@@ -1,7 +1,7 @@
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
branch: master
branch: main
path:
- "ansible/roles/netbird-server/**"
- "ansible/plays/install-netbird-server.yml"
+2 -2
View File
@@ -1,7 +1,7 @@
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
branch: master
branch: main
path:
- "ansible/roles/uptime-kuma/**"
- "ansible/plays/install-uptime-kuma.yml"
+1 -1
View File
@@ -2,7 +2,7 @@
# gitea.renner.uno/konairius/hermes:build.<unix-ts> and :latest.
when:
- event: push
branch: master
branch: main
path:
- "ci/images/hermes/**"
- ".woodpecker/hermes-image.yml"
+2 -2
View File
@@ -33,7 +33,7 @@
# Triggering:
# - cron : a cron NAMED exactly "issue-fix":
# 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
# where <n> is an existing pipeline to promote.
when:
@@ -199,7 +199,7 @@ steps:
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 \
--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}' \
-X POST -H "Authorization: token $$PUSH_TOKEN" \
-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.
# 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
# reviewed with.
#
+3 -3
View File
@@ -65,11 +65,11 @@ steps:
failure: ignore
- 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
# this step is skipped — otherwise we'd fork-bomb PRs.
when:
- branch: master
- branch: main
image: gitea.renner.uno/gitea_admin/ci-claude:2.1.303
environment:
CLAUDE_CODE_OAUTH_TOKEN:
@@ -152,7 +152,7 @@ steps:
--arg title "$$TITLE" \
--arg body "$$BODY" \
--arg head "$$BRANCH" \
'{title: $$title, body: $$body, head: $$head, base: "master"}' \
'{title: $$title, body: $$body, head: $$head, base: "main"}' \
| curl -sfL -X POST \
-H "Authorization: token $$GITEA_TOKEN" \
-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
# scheduled run:
# 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
# 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
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
# PR checkout, so a PR cannot change the rubric or the helper scripts it is
# reviewed with.
@@ -115,7 +115,7 @@ while IFS= read -r ITEM; do
# 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
# 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
# work/target/.git/config — readable by the review agent whose report
# 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
# 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
# would otherwise be silent. This turns that into an alert.
- name: Infrastructure 4
+1 -1
View File
@@ -25,7 +25,7 @@ spec:
fsGroup: 33
containers:
- name: wordpress
image: wordpress:7.1.3-php8.5-apache@sha256:ce31904fa1e51b73543fa2e35cc8f1747589b2abf48dc747b422749b88b77e9e
image: wordpress:7.1.3-php8.3-apache@sha256:8ecd8d8e374167ea22235acf30f80d1165b82f07ffa5bcef90c1cad8f7be251f
ports:
- name: http
containerPort: 80
+6 -6
View File
@@ -93,18 +93,18 @@ GITHUB_REPO="${GITHUB_REPO:-Homelab}"
GHCR_PULL_USER="${GHCR_PULL_USER:-konairius}"
FLUX_PATH="kubernetes/clusters/homelab"
# 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
# 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
#
# Nothing else about the phase changes, which is the point. Delete the branch
# afterwards.
FLUX_BRANCH="${FLUX_BRANCH:-master}"
FLUX_BRANCH="${FLUX_BRANCH:-main}"
SOPS_KEY="$HOME/.config/sops/age/keys.txt"
PHASE="${1:-all}"
@@ -1475,8 +1475,8 @@ if [[ "$PHASE" == "vmtest" ]]; then
# GITEA_TOKEN and a FLUX_BRANCH to write to, because `flux bootstrap`
# commits its sync manifests into the branch it reconciles.
if [[ "${VMTEST_FULL:-0}" == "1" ]]; then
[[ "$FLUX_BRANCH" != "master" ]] \
|| fail "VMTEST_FULL would have flux bootstrap commit into master — point FLUX_BRANCH at a throwaway branch that already exists"
[[ "$FLUX_BRANCH" != "main" ]] \
|| 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}"
PHASE=all
else
@@ -8,7 +8,7 @@ metadata:
spec:
interval: 1m0s
ref:
branch: master
branch: main
secretRef:
name: flux-system
url: https://gitea.renner.uno/konairius/homelab.git
@@ -11,9 +11,9 @@ spec:
# owner, which is the `flux` Gitea account (uid 9) — not
# gitea_admin, as this comment used to say. Evidence: the flux
# 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
# 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.
# The commit author overridden below to security-bot@renner.uno is
# the author field only; it says nothing about who pushes.
@@ -23,7 +23,7 @@ spec:
git:
checkout:
ref:
branch: master
branch: main
commit:
author:
email: security-bot@renner.uno
@@ -33,7 +33,7 @@ spec:
Updates managed by image-automation-controller.
push:
branch: master
branch: main
update:
path: ./kubernetes
strategy: Setters
+1 -1
View File
@@ -13,7 +13,7 @@ spec:
interval: 10m
url: ssh://git@github.com/konairius/Homelab.git
ref:
branch: master
branch: main
# Read-only deploy key, created per run by bootstrap.sh.
secretRef:
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.
- name: VM_STATE
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
value: master
value: main
# 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
# in this emptyDir for the length of the Job and go with it — so