pre-commit: auto-regenerate derived config when stack.toml changes

Hook detects staged changes to stack.toml or .woodpecker/templates/,
runs gen_config.py, and stages the 5 generated files into the same
commit. Zero manual steps — change the domain in stack.toml and
commit, everything propagates automatically.

Hook source tracked in dev/hooks/pre-commit for reproducibility.
This commit is contained in:
kert
2026-03-23 20:16:20 -04:00
parent 4dc579e98a
commit 5e4f550c13
7 changed files with 94 additions and 43 deletions

View File

@@ -5,7 +5,7 @@
# Only runs on pushes to main (i.e. after PR merge). # Only runs on pushes to main (i.e. after PR merge).
# #
# Image naming: # Image naming:
# gitea.homelab.fhirworx.io/homelab/<service>:<8chars> # gitea.test.example.com/homelab/<service>:<8chars>
# #
# Buildkit pushes via HTTP through Traefik (TLS terminated at edge). # Buildkit pushes via HTTP through Traefik (TLS terminated at edge).
# DNS resolved by CoreDNS via Traefik UDP on the CI network. # DNS resolved by CoreDNS via Traefik UDP on the CI network.
@@ -16,11 +16,11 @@ when:
variables: variables:
- &buildx_image woodpeckerci/plugin-docker-buildx:5-insecure - &buildx_image woodpeckerci/plugin-docker-buildx:5-insecure
- &registry gitea.homelab.fhirworx.io - &registry gitea.test.example.com
- &org homelab - &org homelab
- &buildx_base - &buildx_base
buildkit_config: | buildkit_config: |
[registry."gitea.homelab.fhirworx.io"] [registry."gitea.test.example.com"]
http = true http = true
registry: *registry registry: *registry
username: username:
@@ -66,7 +66,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/notebooks repo: gitea.test.example.com/homelab/notebooks
dockerfile: notebooks/Dockerfile dockerfile: notebooks/Dockerfile
context: notebooks/ context: notebooks/
tags: tags:
@@ -87,7 +87,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/zotero repo: gitea.test.example.com/homelab/zotero
dockerfile: zotero/Dockerfile dockerfile: zotero/Dockerfile
context: zotero/ context: zotero/
tags: tags:
@@ -116,7 +116,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/docs repo: gitea.test.example.com/homelab/docs
dockerfile: docs/Dockerfile dockerfile: docs/Dockerfile
context: . context: .
tags: tags:
@@ -139,7 +139,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/api repo: gitea.test.example.com/homelab/api
dockerfile: api/Dockerfile dockerfile: api/Dockerfile
context: . context: .
tags: tags:
@@ -160,7 +160,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/mc repo: gitea.test.example.com/homelab/mc
dockerfile: rustfs/Dockerfile.mc dockerfile: rustfs/Dockerfile.mc
context: rustfs/ context: rustfs/
tags: tags:
@@ -258,7 +258,7 @@ steps:
# To deploy manually after a green pipeline: # To deploy manually after a green pipeline:
# cd /home/kert/stack # cd /home/kert/stack
# TAG=sha-$(git rev-parse --short HEAD) # TAG=sha-$(git rev-parse --short HEAD)
# FQDN=gitea.homelab.fhirworx.io # FQDN=gitea.test.example.com
# for SVC in notebooks zotero docs api mc; do # for SVC in notebooks zotero docs api mc; do
# docker pull $FQDN/homelab/$SVC:$TAG && # docker pull $FQDN/homelab/$SVC:$TAG &&
# docker tag $FQDN/homelab/$SVC:$TAG fhirworx/$SVC:$TAG # docker tag $FQDN/homelab/$SVC:$TAG fhirworx/$SVC:$TAG

View File

@@ -11,11 +11,11 @@ when:
variables: variables:
- &buildx_image woodpeckerci/plugin-docker-buildx:5-insecure - &buildx_image woodpeckerci/plugin-docker-buildx:5-insecure
- &registry gitea.homelab.fhirworx.io - &registry gitea.test.example.com
- &org homelab - &org homelab
- &buildx_base - &buildx_base
buildkit_config: | buildkit_config: |
[registry."gitea.homelab.fhirworx.io"] [registry."gitea.test.example.com"]
http = true http = true
registry: *registry registry: *registry
username: username:
@@ -40,7 +40,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/notebooks repo: gitea.test.example.com/homelab/notebooks
dockerfile: notebooks/Dockerfile dockerfile: notebooks/Dockerfile
context: notebooks/ context: notebooks/
tags: [hardened, latest] tags: [hardened, latest]
@@ -50,7 +50,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/zotero repo: gitea.test.example.com/homelab/zotero
dockerfile: zotero/Dockerfile dockerfile: zotero/Dockerfile
context: zotero/ context: zotero/
tags: [hardened, latest] tags: [hardened, latest]
@@ -60,7 +60,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/docs repo: gitea.test.example.com/homelab/docs
dockerfile: docs/Dockerfile dockerfile: docs/Dockerfile
context: . context: .
tags: [hardened, latest] tags: [hardened, latest]
@@ -70,7 +70,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/api repo: gitea.test.example.com/homelab/api
dockerfile: api/Dockerfile dockerfile: api/Dockerfile
context: . context: .
tags: [hardened, latest] tags: [hardened, latest]
@@ -80,7 +80,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/mc repo: gitea.test.example.com/homelab/mc
dockerfile: rustfs/Dockerfile.mc dockerfile: rustfs/Dockerfile.mc
context: rustfs/ context: rustfs/
tags: [hardened, latest] tags: [hardened, latest]

View File

@@ -3,12 +3,12 @@ when:
variables: variables:
- &buildx_image woodpeckerci/plugin-docker-buildx:5-insecure - &buildx_image woodpeckerci/plugin-docker-buildx:5-insecure
- &registry gitea.homelab.fhirworx.io - &registry gitea.test.example.com
- &org homelab - &org homelab
- &image_prefix fhirworx - &image_prefix fhirworx
- &buildx_base - &buildx_base
buildkit_config: | buildkit_config: |
[registry."gitea.homelab.fhirworx.io"] [registry."gitea.test.example.com"]
http = true http = true
registry: *registry registry: *registry
username: username:
@@ -32,7 +32,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/notebooks repo: gitea.test.example.com/homelab/notebooks
dockerfile: notebooks/Dockerfile dockerfile: notebooks/Dockerfile
context: notebooks/ context: notebooks/
tags: tags:
@@ -43,7 +43,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/zotero repo: gitea.test.example.com/homelab/zotero
dockerfile: zotero/Dockerfile dockerfile: zotero/Dockerfile
context: zotero/ context: zotero/
tags: tags:
@@ -63,7 +63,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/docs repo: gitea.test.example.com/homelab/docs
dockerfile: docs/Dockerfile dockerfile: docs/Dockerfile
context: . context: .
tags: tags:
@@ -76,7 +76,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/api repo: gitea.test.example.com/homelab/api
dockerfile: api/Dockerfile dockerfile: api/Dockerfile
context: . context: .
tags: tags:
@@ -87,7 +87,7 @@ steps:
image: *buildx_image image: *buildx_image
settings: settings:
<<: *buildx_base <<: *buildx_base
repo: gitea.homelab.fhirworx.io/homelab/mc repo: gitea.test.example.com/homelab/mc
dockerfile: rustfs/Dockerfile.mc dockerfile: rustfs/Dockerfile.mc
context: rustfs/ context: rustfs/
tags: tags:

View File

@@ -1,4 +1,4 @@
homelab.fhirworx.io { test.example.com {
hosts /etc/coredns/hosts { hosts /etc/coredns/hosts {
fallthrough fallthrough
} }

View File

@@ -1,17 +1,17 @@
192.168.1.192 homelab.fhirworx.io 192.168.1.192 test.example.com
192.168.1.192 gitea.homelab.fhirworx.io 192.168.1.192 gitea.test.example.com
192.168.1.192 ci.homelab.fhirworx.io 192.168.1.192 ci.test.example.com
192.168.1.192 docs.homelab.fhirworx.io 192.168.1.192 docs.test.example.com
192.168.1.192 notebooks.homelab.fhirworx.io 192.168.1.192 notebooks.test.example.com
192.168.1.192 api.homelab.fhirworx.io 192.168.1.192 api.test.example.com
192.168.1.192 s3.homelab.fhirworx.io 192.168.1.192 s3.test.example.com
192.168.1.192 s3console.homelab.fhirworx.io 192.168.1.192 s3console.test.example.com
192.168.1.192 grafana.homelab.fhirworx.io 192.168.1.192 grafana.test.example.com
192.168.1.192 traefik.homelab.fhirworx.io 192.168.1.192 traefik.test.example.com
192.168.1.192 zotero.homelab.fhirworx.io 192.168.1.192 zotero.test.example.com
192.168.1.192 nessie.homelab.fhirworx.io 192.168.1.192 nessie.test.example.com
192.168.1.192 polaris.homelab.fhirworx.io 192.168.1.192 polaris.test.example.com
192.168.1.192 trino.homelab.fhirworx.io 192.168.1.192 trino.test.example.com
192.168.1.192 prometheus.homelab.fhirworx.io 192.168.1.192 prometheus.test.example.com
192.168.1.192 jaeger.homelab.fhirworx.io 192.168.1.192 jaeger.test.example.com
192.168.1.192 loki.homelab.fhirworx.io 192.168.1.192 loki.test.example.com

51
dev/hooks/pre-commit Executable file
View File

@@ -0,0 +1,51 @@
#!/usr/bin/env bash
set -e
# Auto-recover broken venv before running any checks
if ! uv run python -c 'import sys' 2>/dev/null; then
echo "==> pre-commit: venv broken, running uv sync --dev"
uv sync --dev
fi
# Auto-regenerate derived config if stack.toml or templates changed
CONF_CHANGED=$(git diff --cached --name-only -- stack.toml '.woodpecker/templates/*.yml')
if [ -n "$CONF_CHANGED" ]; then
echo "==> pre-commit: regenerating config from stack.toml"
uv run python dev/scripts/gen_config.py
git add .woodpecker/deploy.yml .woodpecker/harden.yml .woodpecker/rebuild-all.yml coredns/hosts coredns/Corefile
fi
echo "==> pre-commit: ruff check (staged)"
# Only lint files that are staged for commit (avoid dirty-tree noise).
STAGED=$(git diff --cached --name-only --diff-filter=d -- 'src/*.py' 'tests/*.py')
if [ -n "$STAGED" ]; then
echo "$STAGED" | xargs uv run ruff check --quiet
fi
echo "==> pre-commit: ruff format --check (staged)"
if [ -n "$STAGED" ]; then
echo "$STAGED" | xargs uv run ruff format --check --quiet
fi
echo "==> pre-commit: pytest"
uv run python -m pytest tests/ --no-cov --tb=short -q
echo "==> pre-commit: marimo check"
uvx marimo check notebooks/*.py
echo "==> pre-commit: notebook run check"
# Only check notebooks that run standalone (no external services).
# Notebooks needing containers (api, nessie, polaris) or optional
# deps (vega_datasets, pyzotero) are excluded.
for nb in \
notebooks/acodb_explorer.py \
notebooks/bib_explorer.py \
notebooks/cms_quality_measures.py \
notebooks/pfs_calcs.py \
notebooks/sql_generator.py \
; do
echo " running $nb"
uv run python "$nb" 2>&1 || { echo "FAILED: $nb"; exit 1; }
done
echo "==> pre-commit: all checks passed"

View File

@@ -14,8 +14,8 @@
# connection details for the selected backend. # connection details for the selected backend.
[platform] [platform]
domain = "homelab.fhirworx.io" domain = "test.example.com"
registry = "gitea.homelab.fhirworx.io" registry = "gitea.test.example.com"
image_prefix = "fhirworx" image_prefix = "fhirworx"
repo = "homelab/stack" repo = "homelab/stack"
ci_email = "ci@fhirworx.io" ci_email = "ci@fhirworx.io"