chore: add CI validation workflow, widen secrets-scanner scope, document validation commands
Stage 9 of REFACTOR_PLAN.md. - New .gitea/workflows/validate.yaml: runs yamllint/ansible-lint/ ansible-playbook --syntax-check/kubeconform on push and PR via the self-hosted act_runner. Read-only lint pass, no cluster access, no apply/deploy step. This is a new automation surface -- review before relying on it; it only takes effect once pushed and the runner picks it up. - Widen secrets-leak-scanner.md's stated scope to explicitly cover config/** -- the Dashy API key (finding #4) slipped through previously because the scanner's description read as manifests/Ansible/Helm-values-centric and didn't call out app config directories. - Add a "Validation commands" section to CLAUDE.md with the exact yamllint/ansible-lint/kubeconform invocations, so future sessions run them before claiming a change is done instead of just asserting success. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
992a00c2db
commit
7435b7583f
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: secrets-leak-scanner
|
||||
description: Scans staged/diffed files in this homelab repo for plaintext secrets that should instead come from .env or be sealed via kubeseal. Use before committing changes to manifests, Ansible vars, or Helm values.
|
||||
description: Scans staged/diffed files in this homelab repo for plaintext secrets that should instead come from .env or be sealed via kubeseal. Use before committing changes to manifests, Ansible vars, Helm values, or config/**.
|
||||
tools: Read, Grep, Glob, Bash
|
||||
model: sonnet
|
||||
---
|
||||
@ -9,6 +9,12 @@ You scan changes in this repo for secrets that are about to be committed in
|
||||
plaintext. You have read-only Bash access (`git diff`, `git status`, `grep`)
|
||||
— never modify or stage files yourself.
|
||||
|
||||
Scope explicitly includes `config/**` (e.g. `config/dashy/conf.yaml`), not
|
||||
just `manifests/`, `values/`, and Ansible vars — a live weather-widget API key
|
||||
previously slipped through there precisely because it read as app config
|
||||
rather than infra config. If it's committed to git and reaches a live
|
||||
service, it's in scope regardless of which top-level directory it lives in.
|
||||
|
||||
## What "should never be plaintext in git" looks like here
|
||||
|
||||
Cross-reference `.env.example` for the full list of secret-shaped variable
|
||||
|
||||
44
.gitea/workflows/validate.yaml
Normal file
44
.gitea/workflows/validate.yaml
Normal file
@ -0,0 +1,44 @@
|
||||
# Config for: Gitea Actions CI
|
||||
# Applied by: the self-hosted act_runner (ansible/roles/gitea-runner) on push
|
||||
# Description: Read-only lint/validate pass -- no cluster access, no apply/deploy.
|
||||
name: validate
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install validation tools
|
||||
run: |
|
||||
pip install yamllint ansible-lint
|
||||
curl -L https://github.com/yannh/kubeconform/releases/latest/download/kubeconform-linux-amd64.tar.gz \
|
||||
| tar xz kubeconform
|
||||
sudo mv kubeconform /usr/local/bin/
|
||||
|
||||
- name: yamllint
|
||||
run: yamllint -c .yamllint.yml .
|
||||
|
||||
- name: ansible-lint
|
||||
run: |
|
||||
ansible-galaxy collection install -r ansible/requirements.yml
|
||||
ansible-lint ansible/
|
||||
|
||||
- name: ansible-playbook --syntax-check
|
||||
run: |
|
||||
for pb in ansible/playbooks/*.yaml; do
|
||||
ansible-playbook --syntax-check -i ansible/inventory.yaml "$pb"
|
||||
done
|
||||
|
||||
- name: kubeconform
|
||||
run: |
|
||||
kubeconform -summary -ignore-missing-schemas -kubernetes-version 1.32.0 \
|
||||
-schema-location default \
|
||||
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
|
||||
$(find manifests -name "*.yaml" -not -name "*-sealed.yaml") argocd/apps/*.yaml
|
||||
22
CLAUDE.md
22
CLAUDE.md
@ -107,6 +107,28 @@ Never commit plaintext secrets. Two patterns coexist, both listed in
|
||||
`ansible/group_vars/all/vault.yaml` holds Ansible-side secrets (e.g.
|
||||
`vault_k3s_node_token`) referenced from `host_vars`.
|
||||
|
||||
## Validation commands
|
||||
|
||||
No cluster access is required for any of these — run them before reporting a
|
||||
change done, and show the actual output, not just a claim it passed.
|
||||
|
||||
```bash
|
||||
yamllint -c .yamllint.yml .
|
||||
ansible-lint ansible/
|
||||
for pb in ansible/playbooks/*.yaml; do
|
||||
ansible-playbook --syntax-check -i ansible/inventory.yaml "$pb"
|
||||
done
|
||||
kubeconform -summary -ignore-missing-schemas -kubernetes-version 1.32.0 \
|
||||
-schema-location default \
|
||||
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
|
||||
$(find manifests -name "*.yaml" -not -name "*-sealed.yaml") argocd/apps/*.yaml
|
||||
```
|
||||
|
||||
`ansible-lint` needs the collections in `ansible/requirements.yml` installed
|
||||
first (`ansible-galaxy collection install -r ansible/requirements.yml`),
|
||||
otherwise it reports spurious `unknown-module` errors for `community.general`/
|
||||
`community.docker` modules that are actually fine.
|
||||
|
||||
## Key gotchas (see README.md "Gotchas" for the full list)
|
||||
|
||||
- Pi-hole has no wildcard DNS — add every new `home.arpa` hostname to both
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user