Skip to content

Commit 0ec358a

Browse files
authored
Add support for reading Helm API versions from files (#8)
* Add support for reading API versions from foot comments * Add Argo Workflows test manifests * Not the purpose of the `argo-workflows` test files * Readme: Add TOC, document how to specify API versions * Readme: Add remainder of sentence
1 parent d14dcc0 commit 0ec358a

File tree

4 files changed

+243
-10
lines changed

4 files changed

+243
-10
lines changed

README.md

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<!-- omit in toc -->
12
# Flux Helm chart diff action
23

34
A composite GitHub Action for use with PR workflows in repos with [Flux Helm manifests](https://fluxcd.io/flux/use-cases/helm/).
@@ -14,6 +15,17 @@ Combine with these awesome projects for maximum workflow smoothness:
1415
- [mshick/add-pr-comment](https://github.com/mshick/add-pr-comment): Add diff report as comment to PR
1516
- [Renovate](https://github.com/renovatebot/renovate): Automatically create PRs when new charts versions are available)
1617

18+
<!-- omit in toc -->
19+
## Table of Contents
20+
21+
- [Dependencies](#dependencies)
22+
- [Inputs](#inputs)
23+
- [Outputs](#outputs)
24+
- [Usage](#usage)
25+
- [Dry-running/Emulating API Capabilities](#dry-runningemulating-api-capabilities)
26+
- [Example Output/PR comment](#example-outputpr-comment)
27+
- [Testing](#testing)
28+
1729
## Dependencies
1830

1931
Requires [Helm](https://helm.sh/) and [yq](https://mikefarah.gitbook.io/yq). Both can be installed using [Arkade](https://github.com/alexellis/arkade-get) if needed.
@@ -35,6 +47,7 @@ In `diff_markdown` the output for each file will either be:
3547

3648
## Usage
3749

50+
<!-- omit in toc -->
3851
### TL;DR
3952

4053
```yaml
@@ -45,6 +58,7 @@ In `diff_markdown` the output for each file will either be:
4558
helm_files: ${{ steps.changed_files_helm.outputs.all_changed_files }}
4659
```
4760
61+
<!-- omit in toc -->
4862
### Full Example
4963
5064
Run on pull requests:
@@ -174,13 +188,40 @@ Optionally, cause check to fail, if any Helm file failed to render:
174188

175189
See [example-workflow.yaml](example-workflow.yaml) for coherent example.
176190

191+
192+
## Dry-running/Emulating API Capabilities
193+
194+
When installing, Helm can access the available Kubernetes APIs and versions, through "[Built-in Objects](https://helm.sh/docs/chart_template_guide/builtin_objects/)".
195+
196+
This enable charts to deploy custom resources, or tweak properties as needed, based on the APIs offered in the cluster. For example, starting with `argo-workflows` chart 0.41.0, the `ServiceMonitor` resource doesn't even get deployed, if [`.Capabilities.APIVersions.Has`](https://github.com/argoproj/argo-helm/blob/argo-workflows-0.41.0/charts/argo-workflows/templates/controller/workflow-controller-servicemonitor.yaml#L2) doesn't contain [`monitoring.coreos.com/v1`](https://github.com/argoproj/argo-helm/blob/argo-workflows-0.41.0/charts/argo-workflows/templates/_helpers.tpl#L200).
197+
198+
This does however also make it difficult to dry-run (using the `helm template` command), with no cluster access. As a workaround, it's possible to specify API version to be used when running the `template` command as commented YAML. The comments has to be the last in the file and must have the document start `---` above. Example:
199+
200+
```yaml
201+
---
202+
# helm-api-versions:
203+
# - myapi/v0
204+
# - monitoring.coreos.com/v1
205+
```
206+
207+
You can verify that the APIs are read correctly from the log output of the "Helm diff" step of the action:
208+
209+
```
210+
Processing file "infrastructure/base/argo-workflows/helm.yaml"
211+
(...)
212+
head API versions: myapi/v0,monitoring.coreos.com/v1
213+
(...)
214+
```
215+
177216
## Example Output/PR comment
178217

218+
<!-- omit in toc -->
179219
### infrastructure/base/dcgm-exporter/helm.yaml
180220
```diff
181221
No changes
182222
```
183223

224+
<!-- omit in toc -->
184225
### infrastructure/base/nvidia-device-plugin/helm.yaml
185226
```diff
186227
(abbreviated)
@@ -258,13 +299,15 @@ helm_files=($(find ./test/head -type f -name 'helm.yaml' | sed "s|^./test/head/|
258299
GITHUB_OUTPUT=debug.out HELM_FILES="${helm_files[@]}" TEST=1 ./flux-helm-diff.sh; cat debug.out
259300
```
260301

302+
<!-- omit in toc -->
261303
### Testing files
262304

263-
| Name | Scenario tested | Expected output |
264-
| ----------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------- |
265-
| `dcgm-exporter` | Chart added in `head` that doesn't exist in `base` | Diff shows entire rendered template as added |
266-
| `metaflow` | Very non-standard way of publishing charts (not sure if should be supported) | TBD |
267-
| `nvidia-device-plugin` | HelmRepository (using `https`), minor chart version bump | Diff (with potentially breaking `nodeAffinity`) |
268-
| `weave-gitops-helm2oci` | Repository type changed from HelmRepository (type `oci`) to OCIRepository | No changes |
269-
| `weave-gitops-helmrepo` | HelmRepository with type `oci` | Diff |
270-
| `weave-gitops-ocirepo` | OCIRepository | Diff |
305+
| Name | Scenario tested | Expected output |
306+
| ----------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
307+
| `argo-workflows` | Read API from comment in helm file (otherwise `ServiceMonitor` resource is not rendered) | Diff shows change to `ServiceMonitor`, instead of being removed |
308+
| `dcgm-exporter` | Chart added in `head` that doesn't exist in `base` | Diff shows entire rendered template as added |
309+
| `metaflow` | Very non-standard way of publishing charts (not sure if should be supported) | TBD |
310+
| `nvidia-device-plugin` | HelmRepository (using `https`), minor chart version bump | Diff (with potentially breaking `nodeAffinity`) |
311+
| `weave-gitops-helm2oci` | Repository type changed from HelmRepository (type `oci`) to OCIRepository | No changes |
312+
| `weave-gitops-helmrepo` | HelmRepository with type `oci` | Diff |
313+
| `weave-gitops-ocirepo` | OCIRepository | Diff |

flux-helm-diff.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22
set -eu -o pipefail
33

44
helm_files=(${HELM_FILES[@]})
@@ -61,6 +61,9 @@ helm_template() {
6161
namespace=$(yq '. | select(.kind == "HelmRelease").metadata.namespace' "${helm_file}")
6262
values=$(yq '. | select(.kind == "HelmRelease").spec.values' "${helm_file}")
6363

64+
# Use Capabilities.APIVersions
65+
mapfile -t api_versions < <(yq '. | foot_comment' "${helm_file}" | yq '.helm-api-versions[]')
66+
6467
# Let's see what information we got out about the chart...
6568
echo "${ref} repo type: ${repo_type}" >&2
6669
echo "${ref} repo name: ${repo_name}" >&2
@@ -69,6 +72,7 @@ helm_template() {
6972
echo "${ref} chart version: ${version}" >&2
7073
echo "${ref} release name: ${name}" >&2
7174
echo "${ref} release namespace: ${namespace}" >&2
75+
echo "${ref} API versions: $(IFS=,; echo "${api_versions[*]}")" >&2
7276

7377
# Syntax for chart repos is different from OCI repos (as HelmRepo kind)
7478
if [[ "${url}" = "oci://"* ]]; then
@@ -78,7 +82,7 @@ helm_template() {
7882
fi
7983

8084
# Render template
81-
template_out=$(helm template "${name}" ${chart_args[@]} --version "${version}" -n "${namespace}" -f <(echo "${values}") 2>&1) || {
85+
template_out=$(helm template "${name}" ${chart_args[@]} --version "${version}" -n "${namespace}" -f <(echo "${values}") --api-versions "$(IFS=,; echo "${api_versions[*]}")" 2>&1) || {
8286
echo "$template_out"
8387
echo "$template_out" >&2
8488
return 2
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
apiVersion: source.toolkit.fluxcd.io/v1
3+
kind: HelmRepository
4+
metadata:
5+
name: argo
6+
namespace: argo
7+
spec:
8+
interval: 15m
9+
url: https://argoproj.github.io/argo-helm
10+
11+
---
12+
apiVersion: helm.toolkit.fluxcd.io/v2
13+
kind: HelmRelease
14+
metadata:
15+
name: argo-workflows
16+
namespace: argo
17+
spec:
18+
interval: 5m
19+
targetNamespace: argo
20+
chart:
21+
spec:
22+
chart: argo-workflows
23+
version: "0.40.14"
24+
sourceRef:
25+
kind: HelmRepository
26+
name: argo
27+
interval: 15m
28+
install:
29+
skipCRDs: true
30+
values:
31+
crds:
32+
install: false
33+
useStaticCredentials: false
34+
controller:
35+
parallelism: 1500 # this affects apps/processing/base/synchronization.yaml
36+
metricsConfig:
37+
enabled: true
38+
workflowDefaults:
39+
spec:
40+
podGC: # https://argoproj.github.io/argo-workflows/fields/#podgc
41+
strategy: OnPodCompletion
42+
ttlStrategy: # https://argoproj.github.io/argo-workflows/fields/#ttlstrategy
43+
secondsAfterSuccess: 300 # 5 minutes
44+
secondsAfterFailure: 86400 # 24 hours
45+
secondsAfterCompletion: 86400 # 24 hours
46+
priorityClassName: high-priority
47+
resources:
48+
requests:
49+
cpu: 100m
50+
memory: 10Gi
51+
limits:
52+
memory: 10Gi
53+
extraArgs:
54+
- --qps=200
55+
- --burst=300
56+
workflowWorkers: 64
57+
workflowTTLWorkers: 16
58+
podCleanupWorkers: 16
59+
serviceMonitor:
60+
enabled: true
61+
additionalLabels:
62+
instance: primary
63+
server:
64+
extraArgs:
65+
- --auth-mode=server
66+
- --kube-api-qps=120.0
67+
- --kube-api-burst=180
68+
priorityClassName: high-priority
69+
resources:
70+
requests:
71+
cpu: 500m
72+
memory: 1Gi
73+
limits:
74+
memory: 1Gi
75+
ingress:
76+
enabled: true
77+
annotations:
78+
cert-manager.io/cluster-issuer: letsencrypt
79+
ingressClassName: nginx
80+
hosts:
81+
- ${flux_argo_instance}wf.${flux_base_domain_name}
82+
pathType: Prefix
83+
paths:
84+
- /
85+
tls:
86+
- secretName: argo-tls
87+
hosts:
88+
- ${flux_argo_instance}wf.${flux_base_domain_name}
89+
serviceAccount:
90+
name: argo-workflows
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
---
2+
apiVersion: source.toolkit.fluxcd.io/v1
3+
kind: HelmRepository
4+
metadata:
5+
name: argo
6+
namespace: argo
7+
spec:
8+
interval: 15m
9+
url: https://argoproj.github.io/argo-helm
10+
11+
---
12+
apiVersion: helm.toolkit.fluxcd.io/v2
13+
kind: HelmRelease
14+
metadata:
15+
name: argo-workflows
16+
namespace: argo
17+
spec:
18+
interval: 5m
19+
targetNamespace: argo
20+
chart:
21+
spec:
22+
chart: argo-workflows
23+
version: "0.42.5"
24+
sourceRef:
25+
kind: HelmRepository
26+
name: argo
27+
interval: 15m
28+
install:
29+
skipCRDs: true
30+
values:
31+
crds:
32+
install: false
33+
useStaticCredentials: false
34+
controller:
35+
parallelism: 1500 # this affects apps/processing/base/synchronization.yaml
36+
metricsConfig:
37+
enabled: true
38+
honorLabels: true
39+
workflowDefaults:
40+
spec:
41+
podGC: # https://argoproj.github.io/argo-workflows/fields/#podgc
42+
strategy: OnPodCompletion
43+
ttlStrategy: # https://argoproj.github.io/argo-workflows/fields/#ttlstrategy
44+
secondsAfterSuccess: 300 # 5 minutes
45+
secondsAfterFailure: 86400 # 24 hours
46+
secondsAfterCompletion: 86400 # 24 hours
47+
priorityClassName: high-priority
48+
resources:
49+
requests:
50+
cpu: 100m
51+
memory: 10Gi
52+
limits:
53+
memory: 10Gi
54+
extraArgs:
55+
- --qps=200
56+
- --burst=300
57+
workflowWorkers: 64
58+
workflowTTLWorkers: 16
59+
podCleanupWorkers: 16
60+
serviceMonitor:
61+
enabled: true
62+
additionalLabels:
63+
instance: primary
64+
server:
65+
extraArgs:
66+
- --auth-mode=server
67+
- --kube-api-qps=120.0
68+
- --kube-api-burst=180
69+
priorityClassName: high-priority
70+
resources:
71+
requests:
72+
cpu: 500m
73+
memory: 1Gi
74+
limits:
75+
memory: 1Gi
76+
ingress:
77+
enabled: true
78+
annotations:
79+
cert-manager.io/cluster-issuer: letsencrypt
80+
ingressClassName: nginx
81+
hosts:
82+
- ${flux_argo_instance}wf.${flux_base_domain_name}
83+
pathType: Prefix
84+
paths:
85+
- /
86+
tls:
87+
- secretName: argo-tls
88+
hosts:
89+
- ${flux_argo_instance}wf.${flux_base_domain_name}
90+
serviceAccount:
91+
name: argo-workflows
92+
93+
---
94+
# helm-api-versions:
95+
# - myapi/v0
96+
# - monitoring.coreos.com/v1

0 commit comments

Comments
 (0)