PAUL'S BLOG

Learn. Build. Share. Repeat.

Publishing Helm Charts to GitHub Container Registry

2024-07-22 5 min read Tutorial

So you have a local Helm chart that you want to share with others?

In this quick tutorial, I’ll walk you through the process of publishing Helm charts to your very own Helm repository using GitHub Container Registry and GitHub Pages using GitHub Actions.

Before you begin, make sure you have the following prerequisites:

  • A GitHub account
  • A GitHub repository with your Helm chart
  • GitHub CLI installed on your local machine
  • Bash shell

GitHub Pages Setup

We will use GitHub Pages to host the Helm repository. So you will need to create a new branch called gh-pages. This branch will contain the Helm chart binaries and a README.md file with instructions on how to use the helm repo and install its charts.

Start by navigating to your repository in the terminal and run the following commands to create the gh-pages branch.

git checkout -b gh-pages

The gh-pages branch should be empty. Remove all the files in the branch using the following command:

rm -rf *

Create a new file named README.md in the root of your repository and add the following content:

## Usage

[Helm](https://helm.sh) must be installed to use the charts.  Please refer to
Helm's [documentation](https://helm.sh/docs) to get started.

Once Helm has been set up correctly, add the repo as follows:

    helm repo add YOUR_REPO_NAME YOUR_REPO_URL

If you had already added this repo earlier, run `helm repo update` to retrieve
the latest versions of the packages.  You can then run `helm search repo
{alias}` to see the charts.

To install the YOUR_REPO_NAME chart:

    helm install demo YOUR_REPO_NAME/YOUR_CHART_NAME

To uninstall the chart:

    helm delete demo

There are some placeholder values in the README.md file that need to be replaced with the actual values. We need to replace YOUR_REPO_NAME with the name of your repository and YOUR_REPO_URL with the URL of your repository.

Run the following GitHub CLI commands to get the repository name, repository URL, and chart name:

# Execute gh commands and store output in variables
repo_name=$(gh repo view --json name | jq .name -r)
repo_url="http://$(gh api user --jq .login).github.io/$repo_name"
chart_name="sample-app" # Replace this with the name of your Helm chart

Next, run the following sed commands to replace the placeholder values in the README.md file:

# Replace the placeholder values in the README.md file
sed -i "s/YOUR_REPO_NAME/$repo_name/g" README.md
sed -i "s,YOUR_REPO_URL,$repo_url,g" README.md
sed -i "s/YOUR_CHART_NAME/$chart_name/g" README.md

Add the README.md file to the staging area and commit the changes:

git add README.md
git commit -m "docs: add chart usage instructions"

Push the changes to the gh-pages branch:

git push --set-upstream origin gh-pages

GitHub Actions Workflow

Now, switch back to the main branch and we’ll create a new GitHub Actions workflow file to publish the Helm charts to GitHub Container Registry.

git checkout main

Create a new file named chart.yml in the .github/workflows directory and add the following code to it:

name: package-helm-chart

on:
  push:
    branches:
      - main
    paths:
      - 'charts/**'
  
  workflow_dispatch:

jobs:
  package-helm-chart:
    permissions:
      contents: read
      packages: write

    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

      - name: Set environment variables
        id: set-variables
        run: |
          echo "REPOSITORY=ghcr.io/$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT"
          echo "VERSION=$(yq -r .version ./charts/sample-app/Chart.yaml)" >> "$GITHUB_OUTPUT"          

      - name: Env variable output
        id: test-variables
        run: |
          echo ${{ steps.set-variables.outputs.REPOSITORY }}
          echo ${{ steps.set-variables.outputs.VERSION }}          

      - name: Login to GitHub Container Registry
        uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ github.token }}

      - name: Package and push helm chart
        run: |
          helm package ./charts/sample-app --version ${{ steps.set-variables.outputs.VERSION }}
          helm push ./sample-app-chart-${{ steps.set-variables.outputs.VERSION }}.tgz oci://${{ steps.set-variables.outputs.REPOSITORY }}/charts          
  
  publish-helm-chart:
    permissions:
      id-token: write
      packages: write
      contents: write
      actions: read
      deployments: read
      pull-requests: read
      
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

      - name: Publish Helm chart to GitHub Pages
        uses: stefanprodan/helm-gh-pages@0ad2bb377311d61ac04ad9eb6f252fb68e207260 # v1.7.0
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          linting: off

In this workflow file, we have defined two jobs, package-helm-chart and publish-helm-chart:

  1. The package-helm-chart job is responsible for packaging the Helm chart and pushing it to GitHub Container Registry using the Helm CLI commands helm package and helm push. Note that the Helm chart version is extracted from the Chart.yaml file and used to version the chart in the Helm repository.
  2. The publish-helm-chart job is responsible for publishing the Helm chart to GitHub Pages. It uses the Helm Publisher action by @stefanprodan to publish the Helm chart to the gh-pages branch.

Commit the changes to your repository:

git add .github/workflows/chart.yml
git commit -m 'ci: helm chart publish to gh-pages'
git push

Last thing to do is confirm GitHub Pages is enabled in your repository. Go to your repository on GitHub, click on the “Settings” tab, and then click on “Pages” in the sidebar. Select the gh-pages branch as the source and click “Save”. GitHub Pages should now be enabled for your repository.

Trigger the Workflow

Now you need to trigger the workflow manually. You can go to the “Actions” tab in your repository, select the “package-helm-chart” workflow, and click on the “Run workflow” button. This will package and push the Helm chart to GitHub Container Registry. If you have the GitHub CLI installed, you can also trigger the workflow using the following command:

gh workflow run chart.yml
gh run view

That’s it! You have successfully published your Helm charts to GitHub Container Registry and GitHub Pages. You can now share the Helm charts with others by providing them with the repository URL and usage instructions.

Conclusion

In this tutorial, you learned how to publish Helm charts to GitHub Container Registry using GitHub Actions. You also set up GitHub Pages to host the Helm repository and provide usage instructions to users. This process makes it easy for others to discover and install your Helm charts.

Happy Helming!