Claude Code for Helm Chart Publishing (2026)
Claude Code for Helm Chart Publishing Workflow Guide
Helm charts are the standard package manager for Kubernetes, and publishing them efficiently is essential for DevOps teams. This guide shows you how to use Claude Code to automate and streamline your Helm chart publishing workflow, from chart creation to version management and registry publishing.
Why Use Claude Code for Helm Chart Publishing?
Manual Helm chart publishing involves repetitive tasks: updating Chart.yaml versions, running linting checks, packaging charts, and pushing to registries. These tasks are error-prone and time-consuming. Claude Code can help you:
- Generate chart scaffolding from requirements
- Automatically update versions across files
- Validate charts against best practices
- Handle multi-chart repositories
- Publish to various registries (Docker Hub, GitHub Container Registry, ChartMuseum)
The real gain is not just speed, it is consistency. When Claude handles the mechanical steps of chart publishing, you eliminate the class of errors that come from running commands slightly differently on different days or by different team members.
Registry Options at a Glance
Before diving into the workflow, it helps to understand which registry fits your situation. Here is a comparison of the most common choices:
| Registry | Auth Method | OCI Support | Versioning | Best For |
|---|---|---|---|---|
| GitHub Container Registry (ghcr.io) | GitHub token | Yes | Git tags + semver | Open-source and GitHub-hosted projects |
| Docker Hub | Docker credentials | Yes | Tag-based | Public charts with wide distribution |
| ChartMuseum | Basic auth / token | No (legacy) | index.yaml | Self-hosted, air-gapped environments |
| Harbor | Robot accounts | Yes | Policy-controlled | Enterprise with audit requirements |
| AWS ECR | IAM / OIDC | Yes | Immutable tags optional | AWS-native infrastructure |
For most teams starting in 2026, GitHub Container Registry with OCI is the path of least resistance. For regulated environments, Harbor or AWS ECR give you the access controls and audit trails compliance teams require.
Setting Up Your Chart Project
Before automating, ensure your Helm environment is ready. Claude Code can help you initialize a proper chart structure.
Initializing a New Chart
Ask Claude Code to create a new chart with all necessary files:
Have Claude create a new chart structure
claude "Create a new Helm chart called 'myapp' with values.yaml,
templates/deployment.yaml, templates/service.yaml, and Chart.yaml
with version 0.1.0"
Claude will generate the essential files following Helm best practices. Here’s what a typical Chart.yaml looks like:
apiVersion: v2
name: myapp
description: A Helm chart for my application
type: application
version: 0.1.0
appVersion: "1.0.0"
maintainers:
- name: platform-team
email: [email protected]
keywords:
- myapp
- kubernetes
home: https://github.com/myorg/myapp
sources:
- https://github.com/myorg/myapp
The maintainers, keywords, home, and sources fields are optional but strongly recommended. They appear in registries like Artifact Hub and help users find and trust your chart. Ask Claude to populate them during chart creation:
claude "Update Chart.yaml to add maintainer info, keywords, and
source URLs for the myapp chart. Use [email protected] as the
maintainer email and github.com/myorg/myapp as the source."
Understanding Chart Structure
A well-organized Helm chart follows this structure:
myapp/
Chart.yaml # Chart metadata
values.yaml # Default configuration
values.schema.json # Optional: validation schema
templates/ # Kubernetes manifests
deployment.yaml
service.yaml
ingress.yaml
serviceaccount.yaml
hpa.yaml
NOTES.txt # Post-install instructions
_helpers.tpl # Template helpers
charts/ # Sub-charts (dependencies)
The NOTES.txt file is frequently overlooked but makes a significant difference in usability. It displays after helm install and can guide users to the correct URL, show them how to retrieve credentials, or link to documentation. Ask Claude to generate a useful one:
claude "Create a templates/NOTES.txt for the myapp chart that:
- Shows the application URL based on the ingress or service type
- Explains how to get the admin password if auth is enabled
- Links to the README for configuration options"
A well-crafted NOTES.txt output looks like this:
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ index .Values.ingress.hosts 0 }}
{{- else if contains "LoadBalancer" .Values.service.type }}
It may take a few minutes for the LoadBalancer IP to be available.
kubectl get svc --namespace {{ .Release.Namespace }} {{ include "myapp.fullname" . }} -w
{{- else }}
kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ include "myapp.fullname" . }} 8080:{{ .Values.service.port }}
Then visit http://127.0.0.1:8080
{{- end }}
Automating Chart Versioning
Version management is critical for chart publishing. Claude Code can help maintain consistent versioning across your project.
Semantic Versioning with Claude
When you’re ready to release a new version, ask Claude to update all version references:
claude "Update the chart version from 0.1.0 to 0.2.0 in Chart.yaml
and update the appVersion to 1.1.0. Also update any version
comments in the templates."
This ensures all version references stay in sync, a common source of confusion in multi-file charts.
Versioning Strategy: Chart Version vs App Version
A common point of confusion is the relationship between version and appVersion in Chart.yaml. Here is the practical rule:
| Field | What it tracks | When to bump |
|---|---|---|
version |
The chart package itself | Any change to templates, values, or chart logic |
appVersion |
The application container image | When deploying a new container version |
You can bump appVersion without bumping version if you are just pinning to a new image tag in a hotfix. Conversely, you should bump version even if appVersion is unchanged when you refactor templates or add new chart features.
Claude can enforce this discipline:
claude "I updated the deployment template to add a readinessProbe.
The appVersion is unchanged. Determine the correct version bump
(major/minor/patch) for the chart version and update Chart.yaml."
Managing Chart Dependencies
For charts with dependencies, use Claude to update requirements:
claude "Add redis as a dependency in Chart.yaml with version
>= 12.0.0 and update requirements"
After adding dependencies, you need to update the lock file:
claude "Run helm dependency update on the myapp chart and confirm
all dependencies resolved correctly. Show me the resulting
Chart.lock content."
The resulting Chart.yaml dependencies section should look like:
dependencies:
- name: redis
version: ">=12.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
- name: postgresql
version: ">=11.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
Note the condition field, it allows users to disable sub-chart dependencies via values, which is important for environments where the dependency already exists externally (e.g., a shared RDS instance instead of a bundled PostgreSQL).
Validating Charts Before Publishing
Never publish a chart without validation. Claude Code can orchestrate comprehensive checks.
Running Helm Lint
claude "Run helm lint on the myapp chart and fix any warnings
or errors it reports"
This catches common issues like missing required fields, invalid YAML syntax, and template errors.
For stricter validation that catches more issues, use the strict flag:
claude "Run helm lint --strict on the myapp chart. Treat warnings
as errors and fix every one before we publish."
Common lint errors and their fixes:
| Error | Cause | Fix |
|---|---|---|
icon is recommended |
Missing icon URL in Chart.yaml | Add icon: field with a valid image URL |
[WARNING] destination for image is unknown |
Missing repository in image values | Add image.repository to values.yaml |
template: myapp/templates/deployment.yaml: function not defined |
Typo in template helper name | Check _helpers.tpl for correct helper names |
values don't meet the specifications of the schema |
values.yaml violates values.schema.json | Fix the offending value or relax the schema |
Template Rendering Validation
Verify your templates render correctly with:
claude "Render the myapp chart with the default values.yaml
and check for any template errors or missing values"
Go further by rendering with specific override values to test edge cases:
claude "Render the myapp chart with these overrides and verify
the output is valid Kubernetes YAML:
- ingress.enabled=true
- ingress.tls[0].secretName=myapp-tls
- replicaCount=3
- autoscaling.enabled=true"
You can also use helm template output directly as input to kubectl apply --dry-run=client to catch Kubernetes API validation errors that Helm itself does not check:
claude "Render the myapp chart to rendered.yaml, then run
kubectl apply --dry-run=client -f rendered.yaml and report
any validation failures."
Schema Validation
If you’ve defined a values.schema.json, have Claude validate against it:
claude "Validate values.yaml against values.schema.json and
report any validation failures"
Claude can also generate the schema from your existing values.yaml if you do not have one:
claude "Analyze the values.yaml for the myapp chart and generate
a values.schema.json that:
- Marks image.repository and image.tag as required strings
- Validates replicaCount is an integer >= 1
- Validates service.port is between 1 and 65535
- Makes ingress.hosts an array of strings when ingress is enabled"
A well-structured schema catches misconfiguration at install time rather than at runtime. Here is an example schema fragment:
{
"$schema": "https://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["image"],
"properties": {
"replicaCount": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"description": "Number of replicas to deploy"
},
"image": {
"type": "object",
"required": ["repository", "tag"],
"properties": {
"repository": {
"type": "string",
"description": "Container image repository"
},
"tag": {
"type": "string",
"description": "Container image tag"
},
"pullPolicy": {
"type": "string",
"enum": ["Always", "IfNotPresent", "Never"],
"default": "IfNotPresent"
}
}
},
"service": {
"type": "object",
"properties": {
"port": {
"type": "integer",
"minimum": 1,
"maximum": 65535
}
}
}
}
}
Packaging and Publishing Workflow
The actual publishing process involves packaging the chart into a .tgz file and uploading it to your registry.
Packaging the Chart
Package your chart with:
claude "Package the myapp chart into myapp-0.2.0.tgz"
This creates a distributable archive ready for publishing. Before packaging, always verify the chart directory is clean:
claude "Check that the myapp chart directory has no temporary
files, .DS_Store files, or other artifacts that should not be
included in the package, then package it."
Publishing to OCI Registries
Modern Helm (3.8+) supports OCI-based registries natively. For GitHub Container Registry (ghcr.io):
claude "Log in to ghcr.io using the GITHUB_TOKEN environment
variable, then push myapp-0.2.0.tgz as an OCI artifact to
ghcr.io/myorg/helm-charts/myapp"
The underlying commands Claude will execute:
echo $GITHUB_TOKEN | helm registry login ghcr.io -u myorg --password-stdin
helm push myapp-0.2.0.tgz oci://ghcr.io/myorg/helm-charts
For AWS ECR with OCI:
claude "Authenticate to ECR in us-east-1 using the current
AWS credentials, then push myapp-0.2.0.tgz to the myorg/helm-charts
ECR repository."
Publishing to ChartMuseum
For ChartMuseum or a private legacy registry:
claude "Push the chart to http://localhost:8080 using helm push
or the appropriate API endpoint"
ChartMuseum exposes a REST API, so Claude can also use curl for environments where the cm-push plugin is not available:
claude "Upload myapp-0.2.0.tgz to the ChartMuseum at
http://chartmuseum.internal using curl with basic auth.
The credentials are in environment variables CM_USER and CM_PASS."
This translates to:
curl -u "$CM_USER:$CM_PASS" \
--data-binary "@myapp-0.2.0.tgz" \
http://chartmuseum.internal/api/charts
Creating a Reusable Publishing Script
Claude can help you create a complete automation script for recurring publishing tasks:
claude "Create a shell script called publish-chart.sh that:
1. Takes version number as argument
2. Updates Chart.yaml with the new version
3. Runs helm lint to validate
4. Packages the chart
5. Pushes to the registry
6. Commits and tags the changes in git"
This script becomes a reusable tool for your team’s publishing workflow. Here is an example of what Claude produces:
#!/usr/bin/env bash
set -euo pipefail
CHART_NAME="myapp"
CHART_DIR="./${CHART_NAME}"
REGISTRY="oci://ghcr.io/myorg/helm-charts"
NEW_VERSION="${1:?Usage: $0 <version>}"
echo "Publishing ${CHART_NAME} version ${NEW_VERSION}..."
Update version in Chart.yaml
sed -i "s/^version:.*/version: ${NEW_VERSION}/" "${CHART_DIR}/Chart.yaml"
echo "Updated Chart.yaml to version ${NEW_VERSION}"
Lint the chart
echo "Running helm lint..."
helm lint --strict "${CHART_DIR}"
Package the chart
echo "Packaging chart..."
helm package "${CHART_DIR}" --destination ./dist
PACKAGE_FILE="./dist/${CHART_NAME}-${NEW_VERSION}.tgz"
Push to registry
echo "Pushing to registry..."
helm push "${PACKAGE_FILE}" "${REGISTRY}"
Commit and tag
git add "${CHART_DIR}/Chart.yaml"
git commit -m "Release ${CHART_NAME} ${NEW_VERSION}"
git tag "${CHART_NAME}-${NEW_VERSION}"
git push origin main --tags
echo "Successfully published ${CHART_NAME} ${NEW_VERSION}"
Ask Claude to extend this script over time as your workflow evolves, adding Slack notifications, Jira ticket updates, or deployment triggers is straightforward once the base script exists.
Best Practices for Chart Publishing
Follow these recommendations for maintainable chart publishing:
Use Semantic Versions
Always use semantic versioning (MAJOR.MINOR.PATCH) for your charts. This helps users understand the impact of upgrades.
| Version bump | When to use | Example |
|---|---|---|
| PATCH (0.0.x) | Bug fixes, typo corrections, documentation | 1.2.3 -> 1.2.4 |
| MINOR (0.x.0) | New optional values, new optional features | 1.2.3 -> 1.3.0 |
| MAJOR (x.0.0) | Breaking changes: removed values, renamed keys, changed defaults | 1.2.3 -> 2.0.0 |
Breaking changes in charts are particularly dangerous because helm upgrade may silently accept changed values and produce unexpected behavior. Document every breaking change in a CHANGELOG.md and use a migration section in your README.
Document Breaking Changes
When publishing major versions, include clear migration instructions in your chart’s README or values.yaml comments:
values.yaml
MIGRATION NOTE (v2.0.0): 'ingress.hosts' changed from a list of strings
to a list of objects. Old format:
ingress.hosts: ["myapp.example.com"]
New format:
ingress.hosts:
- host: myapp.example.com
paths:
- path: /
pathType: Prefix
ingress:
enabled: false
hosts: []
Maintain a Chart Repository Index
For private registries using the classic HTTP repository format, ensure your index.yaml stays updated:
claude "Regenerate the index.yaml for the charts/ directory
including all .tgz files with their appropriate URLs"
The resulting index.yaml serves as the directory for helm repo add and must be regenerated every time you publish a new chart version. Store it at the root of your chart repository served over HTTPS.
Use Git Tags for Versions
Tag your repository with versions matching your chart versions:
claude "Create a git tag 'myapp-0.2.0' and push it to origin"
For multi-chart repositories, use a prefix convention like myapp-0.2.0 and mydb-1.1.0 to disambiguate tags per chart.
Signing Charts for Supply Chain Security
In production environments, sign your chart packages to prevent tampering. Ask Claude to set up Helm chart signing:
claude "Configure Helm chart signing using GPG. Generate the
helm sign command for myapp-0.2.0.tgz and show me how users
can verify the signature with helm verify."
Signing produces a .prov provenance file alongside the .tgz. Consumers can then run helm install --verify to confirm the chart has not been modified since signing.
Integrating with CI/CD
Claude Code works well within CI/CD pipelines. Here’s a sample GitHub Actions workflow that incorporates Claude’s validation logic:
name: Publish Helm Chart
on:
push:
tags:
- 'myapp-*'
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Set up Helm
uses: azure/setup-helm@v3
with:
version: 'latest'
- name: Lint chart
run: helm lint --strict ./myapp
- name: Render templates
run: helm template myapp ./myapp > /tmp/rendered.yaml
- name: Validate Kubernetes manifests
run: kubectl apply --dry-run=client -f /tmp/rendered.yaml
- name: Package chart
run: |
VERSION="${GITHUB_REF_NAME#myapp-}"
helm package ./myapp --version "$VERSION" --destination ./dist
- name: Login to GHCR
run: echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Push chart
run: |
VERSION="${GITHUB_REF_NAME#myapp-}"
helm push ./dist/myapp-${VERSION}.tgz oci://ghcr.io/${{ github.repository_owner }}/helm-charts
For a broader pipeline covering multiple charts in a monorepo, ask Claude to generate a matrix strategy:
claude "Write a GitHub Actions workflow that:
1. Detects which charts changed in this PR using git diff
2. Runs helm lint and helm template on only the changed charts
3. On merge to main, publishes only the charts that changed
Use a matrix job strategy."
This avoids redundant linting and publishing of unchanged charts in large repositories, cutting CI time significantly.
Pre-publish Checklist
Use Claude to run a pre-publish checklist before every release:
In your CI pipeline
claude "Run the following checks:
1. helm lint on all charts in the charts/ directory
2. Check that Chart.yaml versions match git tags
3. Verify all templates render without errors
4. Confirm values.schema.json passes validation against values.yaml
5. Check that NOTES.txt exists and contains no syntax errors"
This ensures only validated charts reach your registry and catches the most common publishing mistakes before they reach users.
Troubleshooting Common Publishing Failures
Even with automation, publishing can fail. Here is a quick reference for the issues Claude can help diagnose and fix:
| Failure | Likely cause | Claude prompt to fix |
|---|---|---|
Error: chart requires kubeVersion: >=1.25.0 mismatch |
kubeVersion in Chart.yaml is too restrictive |
“Update the kubeVersion constraint in Chart.yaml to allow Kubernetes 1.24 and later” |
OCI: unexpected status code 403 |
Missing or expired registry token | “Show me the helm registry login command for ghcr.io using GITHUB_TOKEN” |
Error: found in Chart.yaml, but missing in charts/ |
Dependency downloaded but not committed | “Run helm dependency update and show me what changed in the charts/ directory” |
render error in template: nil pointer evaluating |
Template references a value that is nil | “Find all templates that reference .Values.x without a default and add defaults” |
index.yaml is out of date |
New chart added but index not regenerated | “Run helm repo index and show me the diff against the existing index.yaml” |
Conclusion
Claude Code transforms Helm chart publishing from manual effort into an automated, reliable process. By using Claude’s capabilities for code generation, validation, and workflow orchestration, you can establish consistent publishing practices that reduce errors and save time.
Start by automating your validation checks, then gradually build toward fully automated publishing workflows. Add schema validation next, then tackle the CI/CD integration. The investment pays off in improved reliability and developer productivity, teams that automate their chart publishing typically catch misconfiguration before it reaches production rather than after.
Remember: always validate charts before publishing, maintain consistent versioning, document breaking changes explicitly, and automate your publishing process so every release follows the same verified steps.
Try it: Paste your error into our Error Diagnostic for an instant fix.
Related Reading
- Claude Code for Artifact Publishing Workflow Tutorial
- Claude Code for Cargo Crate Publishing Workflow Guide
- Claude Code for Docker Image Publishing Workflow Guide
Built by theluckystrike. More at zovo.one
Find the right skill → Browse 155+ skills in our Skill Finder.