Contributing¶
Thank you for contributing to the StaffOps Helm Charts repository. This guide covers everything you need to develop, test, and submit changes.
Prerequisites¶
Install the following tools before you begin:
| Tool | Minimum version | Install |
|---|---|---|
| Helm | 3.10 | brew install helm |
| chart-testing (ct) | 3.10 | brew install chart-testing |
| kind | 0.20 | brew install kind |
| kubectl | 1.27 | brew install kubectl |
| yamllint | 1.32 | brew install yamllint |
Repository structure¶
helm-charts/
├── charts/
│ ├── aigent-squad/ # Chart source
│ │ ├── Chart.yaml
│ │ ├── values.yaml
│ │ ├── values-distributed.yaml
│ │ ├── ci/
│ │ │ └── ct-values.yaml # Values used during `ct install`
│ │ └── templates/
│ └── anomaly-detection/
│ ├── Chart.yaml
│ ├── values.yaml
│ ├── ci/
│ │ └── ct-values.yaml
│ └── templates/
├── docs/ # MkDocs source
├── .github/
│ └── workflows/
│ ├── lint-test.yaml # PR: lint + install
│ ├── release.yaml # merge to main: chart-releaser
│ └── docs.yml # merge to main: MkDocs deploy
├── mkdocs.yml
└── README.md
Lint locally¶
ct lint validates chart structure, Chart.yaml fields, and runs helm lint against every values file under ci/.
ct detects which charts changed relative to main and lints only those. If you want to lint all charts regardless of changes:
Common lint failures and fixes:
| Error | Fix |
|---|---|
icon is recommended |
Add icon: URL to Chart.yaml |
version not incremented |
Bump version in Chart.yaml — required for every chart change |
yaml: line N: ... |
Fix YAML syntax — run yamllint charts/<name>/ for details |
| Missing required value | Add the required value to ci/ct-values.yaml |
Test locally with kind¶
ct install spins up a kind cluster, installs the chart with each values file under ci/, runs Helm tests (helm test), and tears down.
Note
ct install installs the chart with each file found under charts/<name>/ci/. Keep ct-values.yaml minimal — only the values required for the chart to render and pass helm test on a plain Kubernetes cluster (no cloud dependencies, no CRD-dependent features).
Versioning conventions¶
This repository follows Semantic Versioning with two independent version fields in Chart.yaml:
version: 0.6.0 # Helm chart package version — bump on every chart change
appVersion: "0.1.0" # Application (container image) version — bump when the image changes
Rules:
version— increment on every PR that touches chart templates, values, orChart.yaml. Use PATCH for backwards-compatible fixes, MINOR for new opt-in features, MAJOR for breaking changes to values or behavior.appVersion— update only when the container image tag changes. Wrap in quotes (it is treated as a string by Helm).- Never set
versionandappVersionto the same value unless they happen to coincide — they track different things. - Do not use pre-release suffixes (
-alpha,-beta) for chartversion; the chart-releaser action publishes every version it finds.
Opening a pull request¶
-
Fork the repository and create a feature branch from
main: -
Make your changes. Bump
versioninChart.yamlfor every chart you touch. -
Run lint and test locally before pushing:
-
Push your branch and open a PR against
main: -
The lint-test CI workflow runs automatically. All checks must pass before the PR can be merged.
-
A maintainer will review and merge. The release workflow publishes the new chart version automatically on merge to
main.
Adding a new chart¶
Minimum required structure¶
charts/<chart-name>/
├── Chart.yaml # apiVersion, name, version, appVersion, description, type
├── values.yaml # All configurable values with inline comments
├── .helmignore # Standard Helm ignore file
├── ci/
│ └── ct-values.yaml # Minimal values for ct install (no cloud dependencies)
└── templates/
├── _helpers.tpl # Named templates: fullname, labels, selectorLabels
├── deployment.yaml
├── service.yaml
├── serviceaccount.yaml
├── NOTES.txt
└── tests/
└── test-connection.yaml
Chart.yaml example¶
apiVersion: v2
name: my-chart
description: One-line description of what this chart does
type: application
version: 0.1.0
appVersion: "1.0.0"
keywords:
- staffops
- kubernetes
home: https://github.com/StaffOps/helm-charts
sources:
- https://github.com/StaffOps/helm-charts
maintainers:
- name: StaffOps Contributors
url: https://github.com/StaffOps
icon: https://staffops.github.io/helm-charts/assets/logo.png
ci/ct-values.yaml rules¶
- Must contain only values that make the chart install successfully on a bare kind cluster.
- Do not set image tags to
latest— pin to a real tag. - Do not enable CRD-dependent features (
serviceMonitor,vmRule,externalSecrets, KEDA, etc.). - Do not include cloud-specific endpoints — use
localhostor stub values where required.
NOTES.txt¶
Always include a useful NOTES.txt that prints the release name, namespace, and next steps. This is shown to users after helm install.
Helm test¶
Include at least one test pod under templates/tests/ that verifies the service is reachable:
# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "my-chart.fullname" . }}-test-connection"
labels:
{{- include "my-chart.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
restartPolicy: Never
containers:
- name: wget
image: busybox
command: ["wget"]
args: ["--spider", "--timeout=5", "http://{{ include "my-chart.fullname" . }}:{{ .Values.service.port }}/healthz"]
Add docs¶
Create a documentation page at docs/charts/<chart-name>.md following the structure of existing chart docs: TL;DR, prerequisites, values reference table, production example, and troubleshooting.
Update mkdocs.yml to add the page to the nav:
CI/CD pipeline¶
PR opened / updated
│
▼
lint-test.yaml
├─ ct lint --target-branch main (checks changed charts only)
└─ ct install --target-branch main (kind cluster, helm test)
│
▼ (PR merged to main)
release.yaml (chart-releaser-action)
├─ Packages changed charts → .tgz
├─ Creates a GitHub Release + tag (e.g. aigent-squad-0.6.0)
├─ Uploads .tgz to the release assets
└─ Updates gh-pages/index.yaml ← Helm repository index
│
▼ (if docs/** or mkdocs.yml changed)
docs.yml (MkDocs + peaceiris/actions-gh-pages)
├─ mkdocs build --site-dir site
└─ peaceiris/actions-gh-pages (keep_files: true)
└─ Deploys HTML to gh-pages alongside index.yaml
Never manually push to gh-pages
The gh-pages branch is managed by two automated workflows. Manual pushes may corrupt the Helm index.yaml or the MkDocs site. If something goes wrong, re-run the relevant workflow from the GitHub Actions UI.