This document provides guidance for AI coding agents (GitHub Copilot, Codex, Claude, etc.) working in this repository.
- Never commit changes unless explicitly instructed to do so.
- Never create a branch unless explicitly instructed to do so.
- Never open a pull request unless explicitly instructed to do so.
- Leave all changes as unstaged working-tree modifications by default.
This repository uses mise (mise.toml) to provide
the required tooling.
Always run bash commands through mise-managed tools. After installing
mise and trusting the repo (mise trust && mise install), the tools defined
in mise.toml are available directly on PATH via mise's shims/activation,
so commands can be run as-is:
scripts/generate-template
yamllint .If mise is not activated in your shell, prefix commands with mise exec --:
mise exec -- scripts/generate-template
mise exec -- yamllint .Do not assume system-installed tools are correct or present. All managed tools must be resolved through mise.
mise.toml provides:
- clusterctl
- kubectl
- kubectl-slice via the
github:patrickdappollonio/kubectl-slicebackend - yamlfmt
- yamllint
- yq
- pre-commit (available if hooks are added again later)
json-patch v5.9.11 is still required by scripts/generate-template, but it
could not be resolved portably through a working mise backend in this
environment. Install it manually before regenerating the template, for example
with go install github.com/evanphx/json-patch/v5/cmd/json-patch@v5.9.11.
This repository generates the published template.yaml for provisioning a Cluster API workload cluster on Hetzner Cloud. The final template keeps the standard kubeadm-based control plane, Hetzner infrastructure objects, remediation templates, and worker MachineDeployment resources for the fsn1, nbg1, and hel1 failure domains.
.github/workflows/ CI automation (testing, release, automerge)
patches/ RFC6902 JSON patches applied to each split manifest
*.json One patch file per generated resource basename
scripts/
generate-template Regenerates template.yaml from clusterctl output + patches
template.yaml Published multi-document Cluster API template
README.md Developer and usage documentation
mise.toml Mise-managed toolchain definition
.yamllint YAML lint rules used by CI
AGENTS.md Primary AI agent instructions
CLAUDE.md Reference to AGENTS.md
GEMINI.md Reference to AGENTS.md
scripts/generate-templatestarts fromclusterctl generate cluster dummy --infrastructure hetzner:v1.0.6and writes the upstream output into a temporaryprocessing/directory.- The generated multi-document YAML is split with
kubectl slice; each split file is then patched by the same-named JSON patch frompatches/viajson-patch. - Every split manifest is formatted with
yamlfmt, wrapped with---/..., then concatenated back into the roottemplate.yaml. - The
machinedeployment-fsn1.yamloutput is the source for the additionalnbg1andhel1worker deployments, created by copying and retargeting the failure domain.
The primary validation flow is:
scripts/generate-template
yamllint .CI runs those same checks from .github/workflows/testing.yml.
There is no Taskfile or broader compiled test suite in this repository.
| Workflow | Trigger | Purpose |
|---|---|---|
testing.yml |
workflow_dispatch, push to master, pull requests to master |
Sets up mise, regenerates template.yaml, and runs yamllint . |
release.yml |
workflow_dispatch, weekly cron (0 8 * * 1) |
Runs semantic-release and commits the .github/RELEASE build timestamp update |
automerge.yml |
workflow_dispatch, pull requests to master |
Auto-approves and enables auto-merge for Dependabot pull requests |
- Commit messages should follow Conventional Commits; valid types are
defined in
.github/semantic.yml. - PRs are squash-merged (confirmed via
.github/settings.yml). - Releases are automated via semantic-release (see
.github/workflows/release.ymlfor the weekly schedule). - Security issues → email
security@cloudhippie.debefore opening a public issue.
- Regenerate, do not handcraft: when the upstream Hetzner Cluster API output changes, update
scripts/generate-templateandpatches/*.json, then regeneratetemplate.yamlinstead of manually editing the assembled file. - Keep patch/file name parity: every JSON patch is matched by basename (
patches/<name>.json↔ generated<name>.yaml). Preserve that convention when adding or renaming resources. - Use placeholders, not environment-specific literals: the published template must keep
${...}variables such as${CLUSTER_NAME},${KUBERNETES_VERSION}, and machine types intact for downstream consumers. - Treat
machinedeployment-fsn1.yamlas the canonical worker template: thenbg1andhel1documents are derived copies, so structural worker changes should start from thefsn1version. - Preserve Hetzner-specific control-plane and remediation resources: this repo intentionally keeps kubeadm control-plane manifests and both remediation templates in the generated output.
When updating AGENTS.md, GEMINI.md, and CLAUDE.md, treat AGENTS.md as
the primary instructions file, and GEMINI.md/CLAUDE.md as copies that
simply reference it (@AGENTS.md).
These files are collectively called the "agent instruction files".