Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
c41ecad
fix(chart): add trailing newline to Chart.yaml
etgraylog May 31, 2026
4e2e4f8
fix(values): add trailing newline to values.yaml
etgraylog May 31, 2026
ad6d495
style(values): remove inner spaces in RBAC role-rules brackets
etgraylog May 31, 2026
60cbefe
ci(gha): add chart-testing config (.github/ct.yaml)
etgraylog May 31, 2026
55d7c11
ci(gha): replace bare helm lint with chart-testing-action
etgraylog May 31, 2026
aeacced
ci(gha): refine workflow per first-run annotations (drop redundant se…
etgraylog May 31, 2026
4fd5db8
feat(ci): add minimal-resource overlay for ct install
etgraylog Jun 1, 2026
648bcff
ci(gha): add install job with kind cluster and MongoDB Operator
etgraylog Jun 1, 2026
ac9c008
ci(gha): rename jobs to helm-ct-lint and helm-ct-install
etgraylog Jun 1, 2026
ee10b16
ci(gha): generate ephemeral rootPassword and mask in workflow logs
etgraylog Jun 1, 2026
313cc34
ci(gha): make ct.yaml validation knobs explicit and enable upgrade te…
etgraylog Jun 1, 2026
895b67c
ci(gha): add Kubernetes version matrix (v1.32.11, v1.33.7, v1.34.3) t…
etgraylog Jun 1, 2026
04d58f5
ci(gha): disable ct upgrade testing
etgraylog Jun 1, 2026
be86e37
ci(gha): add Helm version matrix (v3.16.4 + v4.2.0) to helm-ct-lint
etgraylog Jun 1, 2026
cf78cd5
ci(gha): expand helm-ct-install to asymmetric K8s × Helm matrix (3 He…
etgraylog Jun 1, 2026
4284d7d
ci(gha): reorder helm-ct-install matrix keys to display helm-version …
etgraylog Jun 1, 2026
9a99f8b
ci(gha): add helm-unittest job to lint-and-test workflow
etgraylog Jun 1, 2026
efe3586
test(unit): add starter helm-unittest suites (service, statefulset, i…
etgraylog Jun 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/ct.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Configuration for chart-testing (ct), used by .github/workflows/lint-and-test.yaml
# Full reference: https://github.com/helm/chart-testing

chart-dirs:
- charts

target-branch: main

# Chart.yaml does not declare a maintainers list today; enabling this would
# block linting. Revisit if a maintainers list is added.
validate-maintainers: false

# Defaults below are made explicit to document the chart's CI policy
# rather than relying on ct's built-in defaults.
check-version-increment: true
validate-chart-schema: true
validate-yaml: true

# In-place upgrade testing (disabled). ct's `--upgrade` doesn't exercise
# `helm upgrade` against an existing deployed release the way users would
# expect; it installs the previous revision into an ephemeral namespace,
# upgrades to current, then tears down. Combined with the ~2x CI runtime
# cost, not worth enabling right now. Revisit if ct's upgrade semantics
# change or maintainers want to opt in.
upgrade: false

# Passed through to `helm install` during `ct install`. 15-minute timeout
# accommodates Graylog's startup time on minimal-resource CI runners.
helm-extra-args: --timeout=900s
120 changes: 117 additions & 3 deletions .github/workflows/lint-and-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,122 @@ on:
branches: ["main"]

jobs:
lint:
helm-ct-lint:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
helm-version:
- v3.16.4
- v4.2.0
steps:
- uses: actions/checkout@v3
- run: helm lint charts/graylog
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Set up Helm
uses: azure/setup-helm@v5
with:
version: ${{ matrix.helm-version }}

- name: Set up chart-testing
uses: helm/chart-testing-action@v2.8.0

- name: Run ct lint
run: ct lint --config .github/ct.yaml --all

helm-unittest:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
helm-version:
- v3.16.4
- v4.2.0
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Set up Helm
uses: azure/setup-helm@v5
with:
version: ${{ matrix.helm-version }}

- name: Install helm-unittest plugin
# `helm plugin install --version` does NOT pin to a git tag — it
# clones the default branch. Clone the v1.0.3 tag explicitly and
# install from local path. v1.0.3 is the latest helm-unittest
# release whose plugin.yaml does NOT use the `platformHooks` field;
# v1.1.0+ adds that field, which Helm 3.16.4 rejects during
# plugin.yaml parsing. Pinning to v1.0.3 keeps both matrix variants
# (Helm 3 and Helm 4) compatible.
# Local-path install also sidesteps Helm 4's signature verification.
run: |
git clone --depth 1 --branch v1.0.3 https://github.com/helm-unittest/helm-unittest /tmp/helm-unittest
helm plugin install /tmp/helm-unittest

- name: Run helm unittest
run: helm unittest charts/graylog

helm-ct-install:
runs-on: ubuntu-latest
needs: [helm-ct-lint, helm-unittest]
strategy:
fail-fast: false
# Asymmetric K8s × Helm matrix: full K8s coverage on Helm 3 (the chart's
# stated minimum per docs/TESTING.md), with Helm 4 added as bonus coverage
# on the most recent K8s version. Expand by adding more `include:` entries.
matrix:
include:
- helm-version: v3.16.4
k8s-version: v1.32.11
- helm-version: v3.16.4
k8s-version: v1.33.7
- helm-version: v3.16.4
k8s-version: v1.34.3
- helm-version: v4.2.0
k8s-version: v1.34.3
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Set up Helm
uses: azure/setup-helm@v5
with:
version: ${{ matrix.helm-version }}

- name: Set up chart-testing
uses: helm/chart-testing-action@v2.8.0

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

- name: Install MongoDB Kubernetes Operator
run: |
helm upgrade --install mongodb-kubernetes-operator mongodb-kubernetes \
--repo https://mongodb.github.io/helm-charts \
--version "1.6.1" \
--set operator.watchNamespace="*" \
--namespace operators \
--create-namespace \
--wait \
--timeout 5m

- name: Generate ephemeral CI rootPassword and mask in workflow logs
id: ci-root-password
run: |
password=$(openssl rand -hex 16)
echo "::add-mask::${password}"
echo "value=${password}" >> "$GITHUB_OUTPUT"

- name: Run ct install
run: |
ct install --config .github/ct.yaml --all \
--helm-extra-set-args "--set graylog.config.rootPassword=${{ steps.ci-root-password.outputs.value }}"
2 changes: 1 addition & 1 deletion charts/graylog/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,4 @@ annotations:
# This is the chart version.
version: 1.0.0
# This is the version number of the Graylog application bundled with this chart.
appVersion: "7.0"
appVersion: "7.0"
33 changes: 33 additions & 0 deletions charts/graylog/ci/ci-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# CI overlay used by `ct install` (auto-discovered via charts/graylog/ci/*-values.yaml).
# Minimal-resource configuration tuned to fit a default GitHub-hosted runner
# (~7 GB RAM, 4 vCPU). Not intended for production-like validation.

graylog:
replicas: 1
config:
serverJavaOpts: "-Xms512m -Xmx768m"
resources:
requests:
cpu: "250m"
memory: "768Mi"
limits:
cpu: "1"
memory: "1500Mi"

datanode:
replicas: 1
config:
opensearchHeap: "1g"
javaOpts: "-Xms512m -Xmx512m"
resources:
requests:
cpu: "250m"
memory: "1Gi"
limits:
cpu: "1"
memory: "2Gi"

mongodb:
replicas: 1
arbiters: 0
version: "8.0.23"
79 changes: 79 additions & 0 deletions charts/graylog/tests/graylog_statefulset_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
suite: graylog StatefulSet
templates:
# The StatefulSet's pod-spec annotations reference two checksum helpers that
# `include` other templates by path. helm-unittest's `templates:` filter must
# list those dependencies so the includes resolve. Assertions below use the
# `template:` field to scope each assert to the StatefulSet specifically.
- workload/statefulsets/graylog.yaml
- config/graylog.yaml # checksum/config dependency
- config/secret/secrets.yaml # checksum/secret dependency
release:
name: graylog
namespace: graylog
tests:
- it: respects graylog.replicas value
set:
graylog.replicas: 3
asserts:
- equal:
path: spec.replicas
value: 3
template: workload/statefulsets/graylog.yaml

- it: mounts tls-creds volume when graylog.config.tls.enabled is true
set:
graylog.config.tls.enabled: true
graylog.config.tls.secretName: my-tls-secret
asserts:
- contains:
path: spec.template.spec.volumes
content:
name: tls-creds
secret:
secretName: "my-tls-secret"
template: workload/statefulsets/graylog.yaml

- it: mounts tls-creds at /usr/share/graylog/tls when TLS enabled
set:
graylog.config.tls.enabled: true
graylog.config.tls.secretName: my-tls-secret
asserts:
- contains:
path: spec.template.spec.containers[0].volumeMounts
content:
name: tls-creds
mountPath: /usr/share/graylog/tls
template: workload/statefulsets/graylog.yaml

- it: does NOT mount tls-creds when graylog.config.tls.enabled is false
set:
graylog.config.tls.enabled: false
asserts:
- notContains:
path: spec.template.spec.containers[0].volumeMounts
content:
name: tls-creds
mountPath: /usr/share/graylog/tls
template: workload/statefulsets/graylog.yaml

- it: adds init-plugins emptyDir volume when graylog.config.plugins.enabled is true
set:
graylog.config.plugins.enabled: true
asserts:
- contains:
path: spec.template.spec.volumes
content:
name: init-plugins
emptyDir: {}
template: workload/statefulsets/graylog.yaml

- it: does NOT add init-plugins volume when graylog.config.plugins.enabled is false
set:
graylog.config.plugins.enabled: false
asserts:
- notContains:
path: spec.template.spec.volumes
content:
name: init-plugins
emptyDir: {}
template: workload/statefulsets/graylog.yaml
112 changes: 112 additions & 0 deletions charts/graylog/tests/ingress_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
suite: graylog web Ingress
templates:
- service/ingress/graylog.yaml
release:
name: graylog
namespace: graylog
tests:
- it: does not render when ingress.enabled is false
set:
ingress.enabled: false
asserts:
- hasDocuments:
count: 0

- it: does not render when ingress.web.enabled is false
set:
ingress.enabled: true
ingress.web.enabled: false
asserts:
- hasDocuments:
count: 0

- it: renders when ingress.enabled and ingress.web.enabled are both true
set:
ingress.enabled: true
ingress.web.enabled: true
asserts:
- hasDocuments:
count: 1
- equal:
path: kind
value: Ingress
- equal:
path: apiVersion
value: networking.k8s.io/v1

- it: sets ingressClassName from values
set:
ingress.enabled: true
ingress.web.enabled: true
ingress.web.className: nginx
asserts:
- equal:
path: spec.ingressClassName
value: nginx

- it: renders TLS section when ingress.web.tls is provided
set:
ingress.enabled: true
ingress.web.enabled: true
ingress.web.tls:
- secretName: graylog-tls
hosts:
- graylog.example.com
asserts:
- equal:
path: spec.tls[0].secretName
value: graylog-tls
- equal:
path: spec.tls[0].hosts[0]
value: graylog.example.com

- it: omits TLS section when ingress.web.tls is empty
set:
ingress.enabled: true
ingress.web.enabled: true
ingress.web.tls: []
asserts:
- notExists:
path: spec.tls

- it: adds cert-manager cluster-issuer annotation when configured
set:
ingress.enabled: true
ingress.web.enabled: true
ingress.web.tls:
- secretName: graylog-tls
hosts:
- graylog.example.com
ingress.config.tls.clusterIssuer.existingName: letsencrypt-prod
asserts:
- equal:
path: metadata.annotations["cert-manager.io/cluster-issuer"]
value: letsencrypt-prod

- it: adds cert-manager issuer annotation when existingName is configured
set:
ingress.enabled: true
ingress.web.enabled: true
ingress.web.tls:
- secretName: graylog-tls
hosts:
- graylog.example.com
ingress.config.tls.issuer.existingName: my-issuer
asserts:
- equal:
path: metadata.annotations["cert-manager.io/issuer"]
value: my-issuer

- it: does NOT add cert-manager annotation when no issuer is configured
set:
ingress.enabled: true
ingress.web.enabled: true
ingress.web.tls:
- secretName: graylog-tls
hosts:
- graylog.example.com
asserts:
- notExists:
path: metadata.annotations["cert-manager.io/cluster-issuer"]
- notExists:
path: metadata.annotations["cert-manager.io/issuer"]
Loading
Loading