-
Notifications
You must be signed in to change notification settings - Fork 118
283 lines (246 loc) · 11.6 KB
/
build-test.yml
File metadata and controls
283 lines (246 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# Copyright 2024-2025 New Vector Ltd
#
# SPDX-License-Identifier: AGPL-3.0-only
name: Helm Chart Building tests
on:
pull_request:
push:
branches:
- main
workflow_dispatch:
jobs:
# We build from source and commit all generated file changes so that we can see the impact in PRs
# We want to ensure that the commit of built changes does happen, so fail if building creates changes
# If this gets problematic we change to not committing the built schemas/values to git
no-changes-after-building:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2
with:
python-version: "3.x"
poetry-version: "1.8.5"
- name: Load poetry path
run: |
echo "$(poetry env info -p)/bin" >> "${GITHUB_PATH}"
- name: Build and check for changes
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
# Ensure all JSON files are consistently formatted
for file in $(git ls-files | grep -E "json$"); do yq -iP --indent 2 -o json '.' "$file"; done
# Rebuild the charts & test values files with from the current source
scripts/assemble_ci_values_files_from_fragments.sh
version=$(yq '.version' charts/matrix-stack/Chart.yaml)
scripts/assemble_helm_charts_from_fragments.sh
scripts/set_chart_version.sh "$version"
git diff --exit-code
helm-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Set up chart-testing
uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b # v2.7.0
- name: Run chart-testing (lint)
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
scripts/ct-lint.sh --config ct.yaml
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2
with:
poetry-version: "1.8.5"
python-version: "3.x"
- name: Load poetry path
run: |
echo "$(poetry env info -p)/bin" >> "${GITHUB_PATH}"
- name: Set up Kubeconform
uses: bmuschko/setup-kubeconform@5ccaecbbf012bcb1eeeab66e649db64a477ade8f # v1
- name: Run kubeconform
run: |
for values in charts/matrix-stack/ci/*values.yaml; do
echo "Testing matrix-stack with $values";
helm template \
-n ess-ci \
-a monitoring.coreos.com/v1/ServiceMonitor \
-f "$values" charts/matrix-stack \
| kubeconform \
-schema-location default \
-schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
-strict \
-summary
done
- name: Run checkov
run: |
checkov --version
for checkov_values in charts/matrix-stack/ci/*checkov*values.yaml; do
scripts/checkov.sh "$checkov_values"
done
template-dyff:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write # required to post a comment to a pull request
steps:
- name: Checkout PR
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
fetch-depth: 0
# helm template doesn't reliably order manifests within the same kind, so use yq to do it for us
- name: Generate manifests for PR
id: generate-manifests
run: |
mkdir -p "$RUNNER_TEMP/new"
for values in charts/matrix-stack/ci/*values.yaml; do
echo "Generating new templates with $values";
mkdir -p "$RUNNER_TEMP/new/$(basename "$values" ".yaml")"
helm template \
-n ess-ci \
-a monitoring.coreos.com/v1/ServiceMonitor \
-f "$values" charts/matrix-stack | \
yq ea '[.] | .[] | splitDoc' | \
yq -s "\"$RUNNER_TEMP/new/$(basename "$values" ".yaml")/\""' + ([.kind, .metadata.name] | join("-") | downcase) + ".yaml"'
done
echo "output_dir=$RUNNER_TEMP/new" | tee -a "$GITHUB_OUTPUT"
# We want the most recent common ancestor between the target & PR branches rather than the target branch itself
# There could have been more commits to the target branch since the PR branch was created and we don't want to see
# those changes in the dyff, only what this branch is doing.
- name: Determine most recent common ancestor of target and PR branches
id: merge-base
run: |
echo "merge-base=$(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }})" | tee -a "$GITHUB_OUTPUT"
- name: Checkout target
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
ref: ${{ steps.merge-base.outputs.merge-base }}
- name: Generate manifests for base
run: |
mkdir -p "$RUNNER_TEMP/old"
for values in charts/matrix-stack/ci/*values.yaml; do
echo "Generating old templates with $values";
mkdir -p "$RUNNER_TEMP/old/$(basename "$values" ".yaml")"
helm template \
-n ess-ci \
-a monitoring.coreos.com/v1/ServiceMonitor \
-f "$values" charts/matrix-stack | \
yq ea '[.] | .[] | splitDoc' | \
yq -s "\"$RUNNER_TEMP/old/$(basename "$values" ".yaml")/\""' + ([.kind, .metadata.name] | join("-") | downcase) + ".yaml"'
done
- name: Install dyff with asdf
uses: asdf-vm/actions/install@1902764435ca0dd2f3388eea723a4f92a4eb8302 # v4
with:
tool_versions: |
dyff 1.10.1
- name: Upload new manifests
id: upload-new
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: new-manifests
path: ${{ steps.generate-manifests.outputs.output_dir }}
retention-days: 1
- name: dyff old and new manifests
id: dyff
shell: bash
env:
ARTIFACT_URL: ${{ steps.upload-new.outputs.artifact-url }}
run: |
echo "output_dir=$RUNNER_TEMP" | tee -a "$GITHUB_OUTPUT"
values_directories=$(find "$RUNNER_TEMP/old" "$RUNNER_TEMP/new" -maxdepth 1 -type d | sed -E 's|'"$RUNNER_TEMP"'/(old\|new)||' | sed -E 's|^/||' | sort | uniq)
header="# dyff of changes in rendered templates of CI manifests\n\n"
comment_body=""
while read -r values_dir; do
if [ -z "$values_dir" ]; then
continue
fi
templates_files=$(find "$RUNNER_TEMP/old" "$RUNNER_TEMP/new" -maxdepth 2 -name '*.yaml' | grep "$values_dir" | sed -E 's|'"$RUNNER_TEMP"'/(old\|new)/||' | sort | uniq)
comment_templates_body=""
while read -r templates_file; do
current_file="$(basename "$templates_file")"
if [[ "$current_file" == ".yaml" ]] && [ ! -s "$template_file" ]; then
continue
fi
if [ ! -f "$RUNNER_TEMP/old/$templates_file" ]; then
api_version=$(yq '.apiVersion' "$RUNNER_TEMP/new/$templates_file")
kind=$(yq '.kind' "$RUNNER_TEMP/new/$templates_file")
name=$(yq '.metadata.name' "$RUNNER_TEMP/new/$templates_file")
namespace=$(yq '.metadata.namespace' "$RUNNER_TEMP/new/$templates_file")
metadata=$(yq '.metadata' "$RUNNER_TEMP/new/$templates_file")
comment_templates_body+="@@ $current_file @@\n"
comment_templates_body+="# $api_version/$kind/$namespace/$name\n"
comment_templates_body+="! + one file added - the full content of the file is available in ${ARTIFACT_URL}\n"
comment_templates_body+="+ apiVersion: $api_version\n"
comment_templates_body+="+ kind: $kind\n"
comment_templates_body+="+ metadata:\n"
while IFS= read -r line; do
comment_templates_body+="+ $line\n"
done <<< "$metadata"
comment_templates_body+="\n\n"
continue
fi
if [ ! -f "$RUNNER_TEMP/new/$templates_file" ]; then
api_version=$(yq '.apiVersion' "$RUNNER_TEMP/old/$templates_file" )
kind=$(yq '.kind' "$RUNNER_TEMP/old/$templates_file")
name=$(yq '.metadata.name' "$RUNNER_TEMP/old/$templates_file")
namespace=$(yq '.metadata.namespace' "$RUNNER_TEMP/old/$templates_file")
metadata=$(yq '.metadata' "$RUNNER_TEMP/old/$templates_file")
comment_templates_body+="@@ $current_file @@\n"
comment_templates_body+="# $api_version/$kind/$namespace/$name\n"
comment_templates_body+="! - one file removed\n"
comment_templates_body+="- apiVersion: $api_version\n"
comment_templates_body+="- kind: $kind\n"
comment_templates_body+="- metadata:\n"
while IFS= read -r line; do
comment_templates_body+="- $line\n"
done <<< "$metadata"
comment_templates_body+="\n\n"
continue
fi
exit_code=0
dyff_detail=$(dyff between --set-exit-code --omit-header --output=github "$RUNNER_TEMP/old/$templates_file" "$RUNNER_TEMP/new/$templates_file" 2>&1) || exit_code=$?
if [ $exit_code -ne 0 ]; then
if [[ "$dyff_detail" == *"failed to compare input files"* ]]; then
echo "failed with file $templates_file"
exit 1
fi
api_version=$(yq '.apiVersion' "$RUNNER_TEMP/new/$templates_file")
kind=$(yq '.kind' "$RUNNER_TEMP/new/$templates_file")
name=$(yq '.metadata.name' "$RUNNER_TEMP/new/$templates_file")
namespace=$(yq '.metadata.namespace' "$RUNNER_TEMP/new/$templates_file")
resource_metadata="# $api_version/$kind/$namespace/$name"
comment_templates_body+=$(sed -e "1d" -e "/^@@/a$resource_metadata" <<< "$dyff_detail")
comment_templates_body+="\n\n\n"
fi
done <<< "$templates_files"
if [[ -n "$comment_templates_body" ]]; then
comment_body+="<details><summary><b>$values_dir.yaml</b></summary>\n"
comment_body+='\n```diff\n'
comment_body+="$comment_templates_body"
comment_body+='```\n'
comment_body+="\n</details>\n"
fi
done <<< "$values_directories"
if [ -z "$comment_body" ]; then
comment_body="No changes in rendered templates"
fi
echo -e "$header$comment_body" | tee "$RUNNER_TEMP/dyff-output.md"
- name: Upload generated manifests
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: dyff-templates
path: ${{ steps.dyff.outputs.output_dir }}
retention-days: 1
- name: Find dyff comment
if: github.event.pull_request.number != ''
uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3
id: find-dyff-comment
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: 'dyff of changes in rendered templates'
- name: Create or update comment
if: github.event.pull_request.number != ''
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4
with:
comment-id: ${{ steps.find-dyff-comment.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body-path: ${{ runner.temp }}/dyff-output.md
edit-mode: replace