66 pull_request :
77 branches : [ main ]
88
9+ env :
10+ HELM_VERSION : v3.16.3
11+ KUBECONFORM_VERSION : v0.6.4
12+
913jobs :
10- # STAGE 1: Unit Tests & Validation
11- unit-tests :
14+ # STAGE 1a: Lint + unit tests + yamllint (template-level, no cluster)
15+ lint-unit :
1216 runs-on : ubuntu-latest
1317 steps :
1418 - uses : actions/checkout@v4
15-
19+
1620 - uses : azure/setup-helm@v4
1721 with :
18- version : v3.16.3
19-
22+ version : ${{ env.HELM_VERSION }}
23+
2024 - name : Lint
2125 run : make lint
2226
@@ -26,61 +30,194 @@ jobs:
2630 - name : Unit Tests
2731 run : make unit-test
2832
33+ - name : Install yamllint
34+ run : pipx install yamllint
35+
36+ - name : Yamllint
37+ run : make yamllint
38+
39+ # STAGE 1b: kubeconform validation across multiple Kubernetes API versions
40+ validate :
41+ runs-on : ubuntu-latest
42+ strategy :
43+ fail-fast : false
44+ matrix :
45+ kube_version : [ "1.27.0", "1.29.0", "1.31.0" ]
46+ name : Validate (k8s ${{ matrix.kube_version }})
47+ steps :
48+ - uses : actions/checkout@v4
49+
50+ - uses : azure/setup-helm@v4
51+ with :
52+ version : ${{ env.HELM_VERSION }}
53+
2954 - name : Install Kubeconform
3055 run : |
31- VERSION=v0.6.4
32- curl -L https://github.com/yannh/kubeconform/releases/download/$VERSION/kubeconform-linux-amd64.tar.gz | tar xz
56+ curl -L https://github.com/yannh/kubeconform/releases/download/${KUBECONFORM_VERSION}/kubeconform-linux-amd64.tar.gz | tar xz
3357 sudo mv kubeconform /usr/local/bin/
3458
3559 - name : Kubeconform Validation
36- run : make validate
60+ run : make validate KUBE_VERSION=${{ matrix.kube_version }}
3761
38- # STAGE 2: Examples (Pre-requisite: Unit Tests MUST pass)
62+ # STAGE 2: chart-testing — enforces Chart.yaml version bump + installs ci values
63+ chart-testing :
64+ needs : [ lint-unit, validate ]
65+ runs-on : ubuntu-latest
66+ steps :
67+ - uses : actions/checkout@v4
68+ with :
69+ fetch-depth : 0
70+
71+ - uses : azure/setup-helm@v4
72+ with :
73+ version : ${{ env.HELM_VERSION }}
74+
75+ - uses : actions/setup-python@v5
76+ with :
77+ python-version : " 3.x"
78+
79+ - name : Set up chart-testing
80+ uses : helm/chart-testing-action@v2.6.1
81+
82+ - name : Run chart-testing (lint)
83+ run : ct lint --config .github/ct.yaml
84+
85+ - name : Create kind cluster
86+ uses : helm/kind-action@v1.10.0
87+
88+ - name : Run chart-testing (install)
89+ run : ct install --config .github/ct.yaml
90+
91+ # STAGE 3: Build the matrix of example values files
3992 list-examples :
40- needs : unit-tests
93+ needs : [ lint-unit, validate ]
4194 runs-on : ubuntu-latest
4295 outputs :
4396 matrix : ${{ steps.set-matrix.outputs.matrix }}
4497 steps :
4598 - uses : actions/checkout@v4
4699 - id : set-matrix
47100 run : |
48- # List all yaml files in examples, get basename, and format as JSON array
49101 EXAMPLES=$(ls examples/*.yaml | xargs -n 1 basename | jq -R -s -c 'split("\n")[:-1]')
50102 echo "matrix=$EXAMPLES" >> $GITHUB_OUTPUT
51103
104+ # STAGE 3 (cont.): install every example on kind and assert it becomes ready.
105+ # NOTE: gating is now real — a failed install or unready workload fails the job.
52106 install-examples :
53- needs : list-examples
107+ needs : [ list-examples ]
54108 runs-on : ubuntu-latest
55109 strategy :
56110 fail-fast : false
57111 matrix :
58112 example : ${{ fromJson(needs.list-examples.outputs.matrix) }}
59- name : Test ${{ matrix.example }}
113+ name : Install ${{ matrix.example }}
60114 steps :
61115 - uses : actions/checkout@v4
62-
116+
63117 - uses : azure/setup-helm@v4
64118 with :
65- version : v3.16.3
66-
119+ version : ${{ env.HELM_VERSION }}
120+
67121 - name : Create kind cluster
68- uses : helm/kind-action@v1.9.0
69-
70- - name : Test Example
71- continue-on-error : true
122+ uses : helm/kind-action@v1.10.0
123+
124+ - name : Install and verify example
72125 run : |
126+ set -euo pipefail
73127 file="examples/${{ matrix.example }}"
74- echo "Testing installation with $file..."
75-
76128 RELEASE_NAME="test-$(echo ${{ matrix.example }} | sed 's/\.yaml//' | tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:]-')"
77129 NS="$RELEASE_NAME-ns"
78-
79- if helm install "$RELEASE_NAME" ./charts/frankenphp -f "$file" --create-namespace --namespace "$NS" --wait --timeout 3m; then
80- echo "✅ Installation successful for $file"
81- else
82- echo "❌ Installation failed for $file"
83- kubectl describe pods -n "$NS"
84- kubectl logs -l app.kubernetes.io/name=frankenphp -n "$NS" --all-containers --tail=20
85- exit 1
130+ echo "Installing $file as $RELEASE_NAME in $NS"
131+
132+ if ! helm install "$RELEASE_NAME" ./charts/frankenphp -f " $file" \
133+ --create-namespace --namespace "$NS" --wait --timeout 3m; then
134+ echo "::error::helm install failed for $file"
135+ kubectl describe pods -n "$NS" || true
136+ kubectl logs -l app.kubernetes.io/instance="$RELEASE_NAME" -n "$NS" --all-containers --tail=50 || true
137+ exit 1
86138 fi
139+
140+ echo "Asserting main Deployment is Available"
141+ if ! kubectl wait --for=condition=Available deployment \
142+ -l app.kubernetes.io/instance="$RELEASE_NAME" -n "$NS" --timeout=120s; then
143+ echo "::error::deployment not Available for $file"
144+ kubectl describe pods -n "$NS" || true
145+ kubectl logs -l app.kubernetes.io/instance="$RELEASE_NAME" -n "$NS" --all-containers --tail=50 || true
146+ exit 1
147+ fi
148+ echo "✅ $file installed and ready"
149+
150+ # STAGE 4: live HTTP smoke via `helm test`, across multiple Kubernetes versions
151+ smoke :
152+ needs : [ lint-unit, validate ]
153+ runs-on : ubuntu-latest
154+ strategy :
155+ fail-fast : false
156+ matrix :
157+ node_image :
158+ - kindest/node:v1.27.13
159+ - kindest/node:v1.29.8
160+ - kindest/node:v1.31.0
161+ name : Smoke (${{ matrix.node_image }})
162+ steps :
163+ - uses : actions/checkout@v4
164+
165+ - uses : azure/setup-helm@v4
166+ with :
167+ version : ${{ env.HELM_VERSION }}
168+
169+ - name : Create kind cluster
170+ uses : helm/kind-action@v1.10.0
171+ with :
172+ node_image : ${{ matrix.node_image }}
173+
174+ - name : Install smoke release
175+ run : |
176+ helm install smoke ./charts/frankenphp -f charts/frankenphp/ci/smoke-values.yaml \
177+ --create-namespace --namespace smoke --wait --timeout 3m
178+
179+ - name : helm test (HTTP smoke)
180+ run : helm test smoke --namespace smoke --logs
181+
182+ - name : Diagnostics on failure
183+ if : failure()
184+ run : |
185+ kubectl describe pods -n smoke || true
186+ kubectl logs -l app.kubernetes.io/instance=smoke -n smoke --all-containers --tail=50 || true
187+
188+ # STAGE 5: upgrade regression — install the latest released chart, then upgrade to this PR
189+ upgrade :
190+ needs : [ lint-unit, validate ]
191+ runs-on : ubuntu-latest
192+ steps :
193+ - uses : actions/checkout@v4
194+
195+ - uses : azure/setup-helm@v4
196+ with :
197+ version : ${{ env.HELM_VERSION }}
198+
199+ - name : Create kind cluster
200+ uses : helm/kind-action@v1.10.0
201+
202+ - name : Install latest released chart
203+ id : install-old
204+ continue-on-error : true
205+ run : |
206+ helm repo add frankenphp https://fabienpapet.github.io/helm-frankenphp/
207+ helm repo update
208+ helm install upg frankenphp/frankenphp \
209+ --set image.repository=dunglas/frankenphp --set image.tag=1-php8.3 \
210+ --create-namespace --namespace upg --wait --timeout 3m
211+
212+ - name : Upgrade to PR chart
213+ if : steps.install-old.outcome == 'success'
214+ run : |
215+ helm upgrade upg ./charts/frankenphp \
216+ --set image.repository=dunglas/frankenphp --set image.tag=1-php8.3 \
217+ --namespace upg --wait --timeout 3m
218+ kubectl wait --for=condition=Available deployment \
219+ -l app.kubernetes.io/instance=upg -n upg --timeout=120s
220+
221+ - name : Skip note
222+ if : steps.install-old.outcome != 'success'
223+ run : echo "No released chart available yet — skipping upgrade regression."
0 commit comments