Skip to main content

Helm component

Usage​

  • Create a new chart helm create my-chart && mv my-chart chart
  • Create GitLab pipeline file .gitlab-ci.yml:
include:
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/common@stable
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/helm@stable
inputs:
name: my-chart
path: chart

The component includes helm-docs automatically. If you only need documentation generation, use the separate helm-docs component.

When GITHUB_TOKEN is available, Helm automatically authenticates to ghcr.io before downloading or publishing OCI charts. The token owner is discovered through the GitHub API. Set GITHUB_USER when API-based discovery is unavailable or when the registry login must use a specific GitHub username. The token needs the GitHub Packages scopes required by the charts being pulled or pushed. Automatic login is best-effort so unrelated chart operations can continue; a later GHCR operation still fails with its native error when credentials are required.

When the chart contains schema.json or values.schema.json, the packaged chart README receives an appended Schema section with property path, type, default, allowed values, and description columns.

Use needs to add extra upstream jobs to the Helm package job:

include:
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/helm@stable
inputs:
name: my-chart
path: chart
needs:
- job: build:assets
artifacts: true

Using automatic versioning in a chart template​

Automatic versioning injects the version into files that follow the working agreement.

  • The key version in chart/Chart.yaml to 0.0.0 indicates automatic versioning.
  • The key appVersion in chart/Chart.yaml to main indicates automatic versioning.
  • Any key *.image.tag in values.yaml to main indicates automatic versioning.

Development versions include the branch name as SemVer build metadata. Characters that SemVer does not permit in build metadata, including /, _, and +, are replaced with hyphens automatically.

Example chart/Chart.yaml

version: 0.0.0
appVersion: main

Example chart/values.yaml

image:
...
tag: main

sidecar:
image:
...
tag: main

If you have container build job with the name build:<chart-name> you can use appVersion to reference to them.

Automatic versioning will also work for sub charts. Add them as a dependency to the parent chart in the Chart.yaml.

dependencies:
- name: subchart
version: x.x.x

Option 1 without a dependency:

chart/values.yaml:

image:
registry: registry.gitlab.com
repository: xrow-public/helm-somechart/somechart
# tag: ""
pullPolicy: IfNotPresent

chart/templates/deployment.yaml:

image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}

Option 2 with a dependency on common:

As you can see in the example below, the image is built using the common.images.image helper from the common chart. This helper will automatically inject the version from the build job if it exists.

chart/Chart.yaml:

dependencies:
- name: common
repository: oci://registry.gitlab.com/xrow-public/helm-schema/charts
version: x.x.x

chart/values.yaml:

image:
registry: registry.gitlab.com
repository: xrow-public/helm-somechart/somechart
# tag: ""
pullPolicy: IfNotPresent

chart/templates/deployment.yaml:

image: {{ include "common.images.image" ( dict "imageRoot" .Values.image "global" .Values.global "chart" .Chart ) | quote }}
imagePullPolicy: {{ .Values.image.pullPolicy }}

Inject app version from a container into the chart​

This is a build job example to inject the app version into the chart. container and buildah components have already the capability. The working agreement is that the container image populates the file /tmp/appversion.

build:my-chart:
stage: .pre
script: |
mkdir release || true
echo "1.0.0" > release/appversion
artifacts:
paths:
- release/appversion
when: always
rules:
- when: always

Automated Tests​

The helm component will automatically run automated tests in a temporary namespace if configured.

For this to work you need to configure.

  • One or more test values files in chart/tests/*.yaml or chart/tests/*.yml. When multiple files exist, they are executed one after another in the same job. See azure-devops-agent for an example.
  • A KUBECONFIG GitLab variable in the CI/CD variables with a kubeconfig File to access the cluster in which you want to run the tests.
  • Optional: A valid helm test that can be executed with helm test. See the helm test documentation for more information.

When Kubernetes credentials are not available or cannot create and delete namespaces, the test job logs a warning and exits successfully. This keeps merge request pipelines useful on runners without cluster access while still running the live chart tests wherever a valid KUBECONFIG or runner service account is available.

After the chart and its Helm test hooks succeed, the job inspects every running Pod in the temporary namespace. It prints each container's current CPU and memory usage together with its configured requests and limits. The cluster must expose the Kubernetes Metrics API used by kubectl top pod. The job retries unavailable metrics for up to two minutes.

The resource check fails when current memory usage exceeds a configured memory request. Containers without a memory request are listed but do not participate in that comparison. Charts that do not create running Pods skip the resource check.

Additional helm hints​

Given a values.yaml and the Chart.yaml above Bitnami common chart will inject the proper tag from the appVersion into your resulting container URI.

{{ include "common.images.image" ( dict "imageRoot" .Values.image "global" .Values.global "chart" .Chart ) }}
image:
repository: path/to/image
tag: ""

Given you desire in certain places in the current chart or container tags you can user the magic env variables CI_CONTAINER_RELEASE_TAG or CI_HELM_RELEASE_TAG.

image:
repository: path/to/image
tag: $CI_CONTAINER_RELEASE_TAG
apiVersion: v2
name: test
description: A Helm chart for Kubernetes
type: application
version: 0.0.0
appVersion: $CI_CONTAINER_RELEASE_TAG

Trouble shooting​

Helm Deployment​

If a helm deployment fails because of a timeout, it's useful to rerun the deployment and look at the logs of the problematic containers in the namespace or even the event logs. In most cases you will find there the cause for the failure.

Inputs​

NameDescriptionDefaultType
------------
allow-failureShould the pipeline fail if the linting fails?falseboolean
environmentteststring
nameThe name of the Helm Chart.helmstring
needsAdditional jobs that the Helm package job depends on.[]array
pathRelative path to the Helm Chart.chartstring
review-domainDomain name to use for access to the review application.review.xrow.netstring
stageThe name of the stage.buildstring
tagsThe runners that this job depends on.[]array
test-contextdefaultstring
test-enabledShould the Helm Chart be tested?trueboolean