CI Workflows¶
Workflow (.github/workflows/) |
Trigger | Fails when |
|---|---|---|
Policy Validate (validate.yml) |
Changes to stack/, lifecycle/, install/, values/, values.yaml, fleet/, tools/sample-element/, tools/validator/ |
Validator error, bad fleet pin, broken install chart, failing test |
Documentation Check (docs-check.yml) |
Changes to stack/ or the doc generator |
An element README is stale |
Render Diff (render-diff.yml) |
PRs to the default branch changing stack/, lifecycle/, values/, values.yaml, fleet/ |
Not a gate |
Update Documentation (docs-update.yml) |
update-docs label on a PR |
Not a gate |
Documentation Site (docs-site.yml) |
Every PR and main push |
A relative link, anchor or snippet does not resolve |
Checks run on PRs and pushes to main. A new push to a PR cancels its running checks. Policy Validate, Documentation Check and Documentation Site can also be started from the Actions tab.
Policy Validate¶
Findings are annotated on the PR at the file and line to fix. Errors fail the job, warnings only annotate.
# Every validator run also gets --repo-root .; steps 2 and 4 also get --extra-values tools/validator/testdata/baseline.yaml
make -C tools/validator lint build # (1)!
policystack-validator --github --include-sample-element --skip POLICY080,POLICY081 # (2)!
policystack-validator --github --extra-values "tools/validator/testdata/baseline.yaml,$profile" --only RENDER000,POLICY081 # (3)!
policystack-validator --github --fixtures-dir fleet --skip POLICY080 # (4)!
# fleet pin check, install chart check (below)
make -C tools/validator test # (5)!
- gofmt, vet, build. Go version comes from
tools/validator/go.mod. - Fixture clusters plus
tools/sample-element/. POLICY080 is always skipped: it ignores every kind the chart emits. - Once per file in
tools/validator/testdata/profiles/. They turn every element on, so every converter's ACM templates are evaluated (ACM templates). Runs even if step 2 failed. - Only when
fleet/*.yamlorfleet/hubs/*.yamlexist. Renders the PR's tree, not each file'srevision(Render Diff does that). - Last, so a failing test does not hide the annotations.
Fleet pin check. Each revision must be a tag, branch or commit SHA (5 to 40 hex characters) whose commit contains what the file uses. A pin to the PR's base branch is checked against the merge commit.
v1.4.0must containstack/. A typo or a branch likegh-pagesfails.- Also needs
lifecycle/converters/hypershift/. versionorchannelalso needs anupgradeelement that reads them.
Warning
A pinned branch deleted after merge is not caught, and stops Argo CD generating Applications for every cluster. See Revision.
Install chart check. Runs even if an earlier step failed. helm lint install passes, an empty hubName or gitRepo fails the install, policyNamespace matches between install/values.yaml and values.yaml, and install/operators renders the ACM and GitOps operators plus a MultiClusterHub (Installation).
Note
HELM_VERSION pins Helm in validate.yml and render-diff.yml. Keep them equal, on the major the hub's Argo CD bundles. Dependabot does not update it.
Run it locally: Validation.
Render Diff¶
Comments on the PR with what the merge changes in each fleet/ cluster's rendered Policies. No fleet files or no change means no comment.
### Fleet render: 3 cluster(s) change
> [!WARNING]
> `edge-3` pins `v1.4`, which is not a tag, branch or commit. Merging stops Argo CD from generating Applications for every cluster until it is fixed.
| Cluster | Revision | Changes |
|---|---|---|
| `prod-east-1` | `main` | user-monitoring: 1 Policy changed |
| `nonprod-west-1` | `v1.0.0` → `main` | metallb: **render failed** |
| `edge-2` | new at `main` | 6 elements, 21 objects added |
Each cluster gets a collapsed diff per element below the table, or the Helm error. render fixed means it failed on the base branch and renders now. An element that fails the same way on both sides is not listed. A cluster added or removed shows totals only.
Each fleet file renders at its own revision, before and after the merge (.github/scripts/render-diff.sh). A cluster pinned to main or HEAD shows the PR. One pinned to a tag changes only when its pin moves.
Limits
- Comments stop near 60,000 characters. The full patch is the run's
render-diff.patchartifact. - Fork and Dependabot PRs have a read-only token and get the result in the job summary.
- About 30 seconds per distinct commit rendered.
Documentation Check¶
- Regenerates each
stack/<element>/README.mdin memory and compares, ignoring theGenerated:timestamp.
When Verify Documentation fails, fix it either way:
Update Documentation¶
On the update-docs label, regenerates stack/*/README.md, commits any change as docs: update documentation [auto-generated], pushes it to the PR branch, and removes the label. A GITHUB_TOKEN push starts no workflows, so it dispatches Documentation Check and Policy Validate itself. Fork PRs are skipped.
Documentation Site¶
Builds docs/ with zensical build --strict. On main, a second job publishes site/ to the gh-pages branch as a single commit, using a GitHub App. The site is unversioned: for an older revision, read docs/ at that revision on GitHub.
pip install -r tools/requirements-docs.txt
zensical serve # live preview, run from the repo root
zensical build --strict # the CI check
Not checked by strict mode
Absolute links, nav in zensical.toml, and snippet content. Keep the rules section of tools/validator/README.md free of relative links, and restart serve after editing it.
One-time publish setup
GITHUB_TOKEN cannot bypass rulesets and its pushes do not start a Pages build, hence the App.
| Where | Setting |
|---|---|
| Org Settings > GitHub Apps | No webhook, only Contents: Read and write, installed on this repository only |
Settings > Environments > github-pages |
Deployment branches: main and gh-pages (the Pages build from gh-pages deploys to this environment too). Variable DOCS_APP_CLIENT_ID, secret DOCS_APP_PRIVATE_KEY |
| Settings > Rules > Rulesets | On gh-pages: Restrict creations, updates, deletions, Block force pushes. Bypass: the App only, Always allow |
| Settings > Pages | Deploy from branch gh-pages, root. Custom domain policystk.io, Enforce HTTPS |
| Org Settings > Pages | Verified domain policystk.io |
| Cloudflare DNS | policystk.io A and AAAA to GitHub's Pages IPs, www CNAME to policystack.github.io, DNS only. Proxied needs SSL mode Full (strict) |
Keep all four rules: every publish force-pushes. The domain lives in site_url and the CNAME the publish job writes; change both together.
Dependencies¶
Actions are pinned to commit SHAs. Dependabot opens weekly PRs for actions, the validator's Go modules, and tools/requirements*.txt.