Skip to content

Commit 923b9de

Browse files
committed
feat: Add publish-helm-chart action
1 parent 2f1efd2 commit 923b9de

File tree

3 files changed

+160
-0
lines changed

3 files changed

+160
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ particular step in a workflow.
2323
- [build-container-image](./build-container-image/README.md)
2424
- [build-product-image](./build-product-image/README.md)
2525
- [free-disk-space](./free-disk-space/README.md)
26+
- [publish-helm-chart](./publish-helm-chart/README.md)
2627
- [publish-image](./publish-image/README.md)
2728
- [publish-image-index-manifest](./publish-image-index-manifest/README.md)
2829
- [run-integration-test](./run-integration-test/README.md)

publish-helm-chart/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# `publish-helm-chart`
2+
3+
> Manifest: [publish-helm-chart/action.yml][publish-helm-chart]
4+
5+
This action packages, publishes, and signs a Helm chart.
6+
7+
## Inputs and Outputs
8+
9+
> [!TIP]
10+
> For descriptions of the inputs and outputs, see the complete [publish-helm-chart] action.
11+
12+
### Inputs
13+
14+
| Input | Required | Description |
15+
| ------------------------- | -------- | --------------------------------------------------------------- |
16+
| `chart-registry-uri` | Yes | The URI of the Helm Chart registry |
17+
| `chart-registry-username` | Yes | The username used to login to the Helm Chart registry |
18+
| `chart-registry-password` | Yes | The password used to login to the Helm Chart registry |
19+
| `chart-repository` | Yes | Path to the Helm chart, for example `sdp-charts/kafka-operator` |
20+
| `chart-directory` | Yes | The directory where the Chart.yaml file is located |
21+
| `chart-version` | Yes | The Helm Chart version |
22+
| `app-version` | Yes | The app version to set in the Helm Chart |
23+
| `helm-version` | No | The version of helm |
24+
25+
### Outputs
26+
27+
None.
28+
29+
[publish-helm-chart]: ./action.yaml

publish-helm-chart/action.yaml

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
---
2+
name: Publish Helm Chart
3+
description: This action creates, publishes, and signs a Helm Chart
4+
inputs:
5+
chart-registry-uri:
6+
description: The URI of the Helm Chart registry
7+
required: true
8+
chart-registry-username:
9+
description: The username used to login to the Helm Chart registry
10+
required: true
11+
chart-registry-password:
12+
description: The password used to login to the Helm Chart registry
13+
required: true
14+
chart-repository:
15+
description: Path to the Helm chart, for example `sdp-charts/kafka-operator`
16+
required: true
17+
helm-version:
18+
description: Version of helm
19+
# See https://github.com/helm/helm/releases for latest version
20+
default: v3.18.6
21+
chart-version:
22+
description: The Helm Chart version
23+
required: true
24+
chart-directory:
25+
description: The directory where the Chart.yaml file is located
26+
required: true
27+
app-version:
28+
description: The app version to set in the Helm Chart
29+
required: true
30+
runs:
31+
using: composite
32+
steps:
33+
- name: Set up Cosign
34+
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3.9.1
35+
36+
- name: Set up Helm
37+
uses: stackabletech/actions/setup-k8s-tools # TODO: Pin this to the latest tag
38+
with:
39+
helm-version: ${{ inputs.helm-version }}
40+
41+
- name: Log into Container Registry (${{ inputs.chart-registry-uri }}) using Helm
42+
env:
43+
CHART_REGISTRY_USERNAME: ${{ inputs.chart-registry-username }}
44+
CHART_REGISTRY_PASSWORD: ${{ inputs.chart-registry-password }}
45+
CHART_REGISTRY_URI: ${{ inputs.chart-registry-uri }}
46+
GITHUB_DEBUG: ${{ runner.debug }}
47+
shell: bash
48+
run: |
49+
set -euo pipefail
50+
[ -n "$GITHUB_DEBUG" ] && set -x
51+
52+
helm registry login --username "$CHART_REGISTRY_USERNAME" --password "$CHART_REGISTRY_PASSWORD" "$CHART_REGISTRY_URI"
53+
54+
- name: Log into Container Registry (${{ inputs.chart-registry-uri }}) using Docker
55+
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
56+
with:
57+
registry: ${{ inputs.chart-registry-uri }}
58+
username: ${{ inputs.chart-registry-username }}
59+
password: ${{ inputs.chart-registry-password }}
60+
61+
- name: Package Helm Chart
62+
env:
63+
CHART_DIRECTORY: ${{ inputs.chart-directory }}
64+
CHART_VERSION: ${{ inputs.chart-version }}
65+
APP_VERSION: ${{ inputs.app-version }}
66+
GITHUB_DEBUG: ${{ runner.debug }}
67+
shell: bash
68+
run: |
69+
set -euo pipefail
70+
[ -n "$GITHUB_DEBUG" ] && set -x
71+
72+
# Set the Helm Chart version
73+
# yq ".version = \"$CHART_VERSION\"" < "$CHART_DIRECTORY/Chart.yaml" > "$CHART_DIRECTORY/Chart.new.yaml"
74+
# mv "$CHART_DIRECTORY/Chart.new.yaml" "$CHART_DIRECTORY/Chart.yaml"
75+
76+
# Create temporary directory to store the Helm Chart
77+
TEMP_CHART_DIR=$(mktemp -d)
78+
echo "TEMP_CHART_DIR=$TEMP_CHART_DIR" | tee -a "$GITHUB_ENV"
79+
80+
# Package the Helm Chart
81+
helm package \
82+
--destination "$TEMP_CHART_DIR" \
83+
--version "$CHART_VERSION" \
84+
--app-version "$APP_VERSION" \
85+
"$CHART_DIRECTORY"
86+
87+
- name: Publish Helm Chart
88+
env:
89+
CHART_REGISTRY_URI: ${{ inputs.chart-registry-uri }}
90+
CHART_REPOSITORY: ${{ inputs.chart-repository }}
91+
CHART_DIRECTORY: ${{ inputs.chart-directory }}
92+
CHART_VERSION: ${{ inputs.chart-version }}
93+
GITHUB_DEBUG: ${{ runner.debug }}
94+
shell: bash
95+
run: |
96+
set -euo pipefail
97+
[ -n "$GITHUB_DEBUG" ] && set -x
98+
99+
CHART_NAME=$(echo "$CHART_REPOSITORY" | awk -F/ '{print $NF}')
100+
CHART_ARTIFACT="${TEMP_CHART_DIR}/${CHART_NAME}-${CHART_VERSION}.tgz"
101+
echo "CHART_NAME=$CHART_NAME" | tee -a "$GITHUB_ENV"
102+
103+
# Capture the stdout output to extract the digest. It is sad that Helm doesn't provide
104+
# structured output, eg. in JSON. There is a 2-year old open issue about it:
105+
# https://github.com/helm/helm/issues/11735
106+
HELM_OUTPUT=$(helm push "$CHART_ARTIFACT" "oci://${CHART_REGISTRY_URI}/${CHART_REPOSITORY}" 2>&1)
107+
108+
# Yuck
109+
CHART_DIGEST=$(echo "$HELM_OUTPUT" | awk '/^Digest: sha256:[0-9a-f]{64}$/ { print $2 }')
110+
111+
if [ -z "$CHART_DIGEST" ]; then
112+
echo "Could not find digest of Helm Chart"
113+
exit 1
114+
fi
115+
116+
echo "CHART_DIGEST=$CHART_DIGEST" | tee -a "$GITHUB_ENV"
117+
118+
- name: Sign Helm Chart
119+
env:
120+
CHART_REGISTRY_URI: ${{ inputs.chart-registry-uri }}
121+
CHART_REPOSITORY: ${{ inputs.chart-repository }}
122+
GITHUB_DEBUG: ${{ runner.debug }}
123+
shell: bash
124+
run: |
125+
set -euo pipefail
126+
[ -n "$GITHUB_DEBUG" ] && set -x
127+
128+
# This generates a signature and publishes it to the registry, next to the chart artifact
129+
# Uses the keyless signing flow with Github Actions as identity provider
130+
cosign sign -y "${CHART_REGISTRY_URI}/${CHART_REPOSITORY}/${CHART_NAME}@${CHART_DIGEST}"

0 commit comments

Comments
 (0)