How to Create and Host Helm Chart Repository on Github Pages

In this post, we’ll create fully automated build pipeline to host a repository for Helm charts using GitHub Pages and GitHub Actions.

Helm is a package manager for Kubernetes and helps to manage Kubernetes applications. And helm chart repository is an HTTP server that houses an index.yaml file and optionally some packaged charts.

We can create a chart repository using GitHub Pages. It allows us to serve static web pages. All we need is to host a single index.yaml file along with a bunch of .tgz files.

# Create a Github Repository

Before proceeding, create a new repository in github. I will name mine helm-charts but be free to name yours as you want. Head over to github create new repository and fill in the new repository form.

To work on it locally, clone it.

1
git clone git@github.com:etowett/helm-charts.git

# Create a helm chart

Before proceeding, ensure you have helm installed. Checkout the helm install page for your OS installation instructions.

I’m going to use a directory ./charts/ for the sources of our charts. I’m creating the default chart for testing purposes, you might want to copy into ./charts/ your existing charts instead.

1
2
3
mkdir charts
cd charts
helm create app

In my case, I am creating a chart named app. You should see output similar to this:

1
2
$ helm create app
Creating app

Push to git repository on GitHub

1
git add . && git commit -m "added initial app helm chart" && git push origin main

# Setup GitHub Pages

Next, we need to create a new branch named gh-pages so as to publish helm charts.

First you need to go ahead and create a gh-pages branch in your repository. As I’m writing this there’s an issue open to do this automatically, but to do it manually you can run the following:

1
2
3
4
git checkout --orphan gh-pages
git rm -rf .
git commit -m "create gh-pages branch" --allow-empty
git push origin gh-pages

Once you’ve done that, you need to enable GitHub Pages in your repository. Go to the settings page on your repository and set the source branch to the gh-pages branch you just created.

# GitHub Actions

We need a Github actions workflow to create the release for every change we do the repo.

Create a GitHub Actions Workflow .github/workflows/release.yml in the main branch and add the following configurations as shown below. You can find more details here. This will now turn our repo to self-hosted Helm Chart repo. With every push to the main branch it will check the chart and if there is a new chart version creates a corresponding GitHub release, adds Helm chart artefacts to the release and creates the index.yaml on first push or updates the same afterwards with metadata about those releases, which will be then hosted on GitHub Pages.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
---
name: Release Helm Charts

on:
  push:
    branches:
      - main

jobs:
  release:
    # depending on default permission settings for your org (contents being read-only or read-write for workloads), you will have to add permissions
    # see: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token
    permissions:
      contents: write
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v3
      with:
        fetch-depth: 0

    - name: Configure Git
      run: |
        git config user.name "$GITHUB_ACTOR"
        git config user.email "$GITHUB_ACTOR@users.noreply.github.com"        

    - name: Install Helm
      uses: azure/setup-helm@v3

    - name: Run chart-releaser
      uses: helm/chart-releaser-action@v1.5.0
      env:
        CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

When you push some changes to the chart in main branch, you will notice that an index.yml gets automatically created. Navigate to Github actions tab to see the workflow triggers.

You can see now in the releases section a new release has been created at the bottom right for app and index.yaml would also be updated in gh-pages branch.

# Linting action

As a bonus, we can create another action to lint the charts when there is a pull request on our repo.

Pull request workflow will deal with Linting, Testing, and validating charts using a collection of automated tooling and against schemas generated from the Kubernetes OpenAPI specification. For chart Testing to installing Helm charts on a Kubernetes cluster GitHub Actions runner use Kubernetes in Docker (KIND) cluster.

To do that, go ahead and create a workflow in your repository by creating a file at .github/workflows/ci.yaml and add the following YAML to it:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
name: Helm Lint and Test Charts

on:
  pull_request:
    paths:
      - 'charts/**'

jobs:
  lint-chart:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Run chart-testing (lint)
        uses: helm/chart-testing-action@main
        with:
          command: lint
          config: .github/ct.yaml

  kubeval-chart:
    runs-on: ubuntu-latest
    needs:
      - lint-chart
    strategy:
      matrix:
        k8s:
          - v1.27
          - v1.28
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Run kubeval
        env:
          KUBERNETES_VERSION: ${{ matrix.k8s }}
        run: .github/kubeval.sh

  install-chart:
    name: install-chart
    runs-on: ubuntu-latest
    needs:
      - lint-chart
      - kubeval-chart
    strategy:
      matrix:
        k8s:
          - v1.27
          - v1.28
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Create kind ${{ matrix.k8s }} cluster
        uses: helm/kind-action@main
        with:
          node_image: kindest/node:${{ matrix.k8s }}

      - name: Run chart-testing (install)
        uses: helm/chart-testing-action@main
        with:
          command: install
          config: .github/ct.yaml

This will run the workflow on any pull request that changes files under the stable charts directory.

The Lint & kubeval charts include:

  • Version checking
  • YAML schema validation on Chart.yaml
  • YAML linting on Chart.yaml and values.yaml
  • Maintainer validation on changed charts
  • Validate the configuration using Kubeval

And Commits to main branch workflow will deal with releasing your charts using GitHub pages.

# Using helm chart

Now that our helm chart is created we can use it in our kubernetes cluster for deployment.

1
2
helm repo add mycharts https://etowett.github.io/helm-charts/
helm repo update

Now you would be able to search your repo and use it in any kubernetes deployment.

1
2
3
$ helm search repo mycharts
NAME        	CHART VERSION	APP VERSION	DESCRIPTION
mycharts/app	0.1.0        	1.16.0     	A Helm chart for Kubernetes

To install the app chart in the Kubernetes cluster.

1
helm upgrade --install app mycharts/app

# Conclusion

In this blog we have seen how we can use github pages, action and github repo for hosting our helm charts repo.

comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy