5252 check-latest : true
5353 cache : true
5454 -
55- name : Install Tools
56- # TODO: pin version -> fork + update dedicated github action
57- run : |
58- go install gotest.tools/gotestsum@latest
55+ name : Install gotestsum
56+ uses : go-openapi/gh-actions/install/gotestsum@b54cc4ecd2b7e4e255a89c1e8ae71eff84698e1c
5957 -
6058 name : Run unit tests
6159 shell : bash
6967 -timeout=20m
7068 -coverprofile='unit.coverage.${{ matrix.os }}-${{ matrix.go }}.out'
7169 -covermode=atomic
72- -coverpkg=$(go list)/...
70+ -coverpkg=" $(go list)" /...
7371 ./...
7472 -
7573 name : Upload coverage artifacts
8987 name : ' unit.report.${{ matrix.os }}-${{ matrix.go }}'
9088 retention-days : 1
9189
92- fuzz-test :
93- name : fuzz test
94- runs-on : ubuntu-latest
95- env :
96- CORPUS_MAX_SIZE_MB : 100
97- steps :
98- -
99- uses : actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
100- -
101- uses : actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
102- with :
103- go-version : stable
104- check-latest : true
105- cache : true
106- -
107- name : Locate go fuzz cache
108- run : |
109- GOCACHE=$(go env GOCACHE)
110- echo "CORPUS_DIR=${GOCACHE}/fuzz" >> "${GITHUB_ENV}"
111- -
112- name : Retrieve fuzz corpus from cache
113- uses : actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
114- with :
115- key : ${{ runner.os }}-go-fuzz
116- path :
117- ${{ env.CORPUS_DIR }}
118- -
119- name : Manage fuzz corpus cache size
120- run : |
121- mkdir -p "${CORPUS_DIR}"
122- CURRENT_SIZE=$(du -sm "${CORPUS_DIR}"|cut -f1)
123- echo "corpus size: ${CURRENT_SIZE}MB"
124- if [[ "${CURRENT_SIZE}" -gt "${CORPUS_MAX_SIZE}" ]] ; then
125- # remove the 50 oldest corpus files
126- echo "::warning:Large fuzz corpus pruned"
127- find "${CORPUS_DIR}" -type f|ls -t|tail -n +50|xargs rm -f
128- fi
129- -
130- name : Run go fuzz tests
131- run : >
132- go test
133- -fuzz=Fuzz
134- -run=Fuzz
135- -fuzztime=1m30s
136- -fuzzminimizetime=5m
137- ./...
138- -
139- name : Upload failed corpus
140- if : ${{ failure() }}
141- uses : actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
142- with :
143- path : ${{ env.CORPUS_DIR }}
144- name : ' ${{ runner.os }}-fuzz-corpus-failure'
145- retention-days : 60
146- -
147- name : Report fuzz corpus cache size
148- run : |
149- FINAL_SIZE=$(du -m "${CORPUS_DIR}"|cut -f1)
150- echo "::notice title=fuzz corpus size:${FINAL_SIZE}MB"
151-
152-
15390 test-complete :
15491 # description: |
15592 # Be explicit about all tests being passed. This allows for setting up only a few status checks on PRs.
@@ -206,12 +143,6 @@ jobs:
206143 if : ${{ !cancelled() }}
207144 runs-on : ubuntu-latest
208145 steps :
209- -
210- uses : actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
211- with :
212- go-version : stable
213- check-latest : true
214- cache : true
215146 -
216147 name : Download test report artifacts
217148 uses : actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
@@ -220,6 +151,9 @@ jobs:
220151 pattern : " *.report.*"
221152 # artifacts resolve as folders
222153 path : reports/
154+ -
155+ name : Install go-junit-report
156+ uses : go-openapi/gh-actions/install/go-junit-report@b54cc4ecd2b7e4e255a89c1e8ae71eff84698e1c
223157 -
224158 name : Convert test reports to a merged JUnit XML
225159 # NOTE: codecov test reports only support JUnit format at this moment. See https://docs.codecov.com/docs/test-analytics.
@@ -228,14 +162,10 @@ jobs:
228162 # As a contemplated alternative, we could use gotestsum above to produce the JUnit XML directly.
229163 # At this moment, we keep a json format to dispatch test reports to codecov as well as to CTRF reports.
230164 #
231- # TODO(fredbi): sec compliance - pin go-junit-report
232165 # TODO(fredbi): investigate - use mikepenz/action-junit-report@v5, that packages most of the following scripts
233166 # in a single action. Alternative: for that action.
234167 run : |
235- go install github.com/jstemmer/go-junit-report/v2@latest
236- go-junit-report -version
237-
238- find reports/ -name \*.json | xargs cat | go-junit-report -parser gojson -out=reports/junit_report.xml
168+ find reports/ -name \*.json -print0 | xargs -0 cat | go-junit-report -parser gojson -out=reports/junit_report.xml
239169 -
240170 name : Upload test results to Codecov
241171 # This allows for using the test results UI on codecov
@@ -246,14 +176,20 @@ jobs:
246176 fail_ci_if_error : false
247177 handle_no_reports_found : true
248178 verbose : true
179+ -
180+ uses : actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
181+ with :
182+ go-version : stable
183+ check-latest : true
184+ cache : true
185+ -
186+ name : Install go-ctrf-json-reporter
187+ uses : go-openapi/gh-actions/install/go-ctrf-json-reporter@b54cc4ecd2b7e4e255a89c1e8ae71eff84698e1c
249188 -
250189 name : Convert test reports to CTRF JSON
251190 # description: |
252191 # This step publishes CTRF test reports on github UI (actions)
253- # TODO: pin this dependency
254192 run : |
255- go install github.com/ctrf-io/go-ctrf-json-reporter/cmd/go-ctrf-json-reporter@v0.0.10
256-
257193 appName="${{ github.repository }}"
258194 buildNumber="${{ github.run_id }}"
259195 appVersion="${{ github.event.pull_request.head.sha }}"
@@ -263,11 +199,9 @@ jobs:
263199 fi
264200
265201 # reconstruct platform information from the file name
266- # set -x
267- while read report ; do
268- # 'unit.report.${{ matrix.os }}-${{ matrix.go }}.json'
202+ while read -r report ; do
269203 reformated=$(echo "${report##*/}"|sed -E 's/(go)([[:digit:]]+)\.([[:digit:]]+)/\1\2\3/') # e.g. go1.24 becomes go124
270- mapfile -d'.' -t -s 2 -n 2 split < <(echo $reformated) # skip the first 2 parts, stop on 2 more parts
204+ mapfile -d'.' -t -s 2 -n 2 split < <(echo " $reformated" ) # skip the first 2 parts, stop on 2 more parts
271205 envstring="${split[0]}"
272206 osPlatform="${envstring%-*}"
273207 osRelease="${envstring##*-}"
@@ -306,3 +240,109 @@ jobs:
306240 summary-report : true # post a report to the github actions summary
307241 github-report : true
308242 failed-folded-report : true
243+
244+ fuzz-test :
245+ name : fuzz test
246+ runs-on : ubuntu-latest
247+ env :
248+ CORPUS_MAX_SIZE_MB : 250
249+ FUZZ_TIME : 1m30s
250+ FUZZ_MINIMIZE_TIME : 5m
251+ steps :
252+ -
253+ uses : actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
254+ -
255+ uses : actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
256+ with :
257+ go-version : stable
258+ check-latest : true
259+ cache : true
260+ -
261+ name : Locate go fuzz cache
262+ run : |
263+ GOCACHE=$(go env GOCACHE)
264+ echo "CORPUS_DIR=${GOCACHE}/fuzz" >> "${GITHUB_ENV}"
265+ -
266+ name : Retrieve fuzz corpus from cache
267+ uses : actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
268+ with :
269+ key : ${{ runner.os }}-go-fuzz
270+ path :
271+ ${{ env.CORPUS_DIR }}
272+ -
273+ name : Manage fuzz corpus cache size
274+ run : |
275+ mkdir -p "${CORPUS_DIR}"
276+ # This script checks that the size of the corpus cache doesn't exceed ${CORPUS_MAX_SIZE_MB},
277+ # and if it does, it removes all oldest files beyond that size.
278+
279+ function size() {
280+ local location=$1
281+ local unit=$2
282+
283+ du -s"${unit}" "${location}"|cut -f1
284+ }
285+
286+ function purge() {
287+ local location=$1
288+ local max_size_b=$2
289+ declare -i current_size_b=0 file_size_b=0 purged_files=0
290+
291+ while read -r filename ; do
292+ file_size_b="$(size "${filename}" "b")"
293+ ((current_size_b+=file_size_b))
294+
295+ if [[ ${current_size_b} -le ${max_size_b} ]] ; then
296+ continue
297+ fi
298+ if [[ ${file_size_b} -eq 0 ]] ; then
299+ continue
300+ fi
301+
302+ rm -f "${filename}"
303+ ((purged_files+=1))
304+ done < <(find "${location}" -type f -print0 | xargs -0 ls -t)
305+
306+ echo ${purged_files}
307+ }
308+
309+ CURRENT_SIZE_MB="$(size "${CORPUS_DIR}" "m")"
310+ if [[ "${CURRENT_SIZE_MB}" -lt "${MAX_SIZE_MB}" ]] ; then
311+ echo "::notice:cache size remains under the accepted size of ${MAX_SIZE_MB} MB: ${CURRENT_SIZE_MB} MB"
312+
313+ exit 0
314+ fi
315+
316+ declare -i max_size_b=$(("${CORPUS_MAX_SIZE_MB}" * 1024 * 1024))
317+ purged_files=$(purge "${purged_dir}" "${max_size_b}");
318+ echo "::notice:cache size is ${CURRENT_SIZE_MB} MB: purging oldest files to keep it under ${CORPUS_MAX_SIZE_MB} MB"
319+ if [[ ${purged_files} -gt 0 ]] ; then
320+ echo "::notice:removed ${purged_files} files to keep the cache size below ${CORPUS_MAX_SIZE_MB} MB"
321+ fi
322+ FINAL_SIZE_MB="$(size "${CORPUS_DIR}" "m")"
323+ echo "::notice:purged cache size: ${FINAL_SIZE_MB} MB"
324+ -
325+ name : Run go fuzz tests
326+ # TODO(fredbi): ./... is not supported: we should run as a matrix test multiple fuzz tests
327+ run : >
328+ go test
329+ -fuzz=Fuzz
330+ -run=Fuzz
331+ -fuzztime='${{ env.FUZZ_TIME }}'
332+ -fuzzminimizetime='${{ env.FUZZ_MINIMIZE_TIME }}'
333+ ./...
334+ -
335+ name : Upload failed corpus
336+ if : ${{ failure() }}
337+ uses : actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
338+ # TODO(fredbi): ideally, after uploading, we should fire a pull request to add
339+ # this corpus to testdata.
340+ with :
341+ path : ${{ env.CORPUS_DIR }}
342+ name : ' ${{ runner.os }}-fuzz-corpus-failure'
343+ retention-days : 60
344+ -
345+ name : Report fuzz corpus cache size
346+ run : |
347+ FINAL_SIZE=$(du -m "${CORPUS_DIR}"|cut -f1)
348+ echo "::notice title=fuzz corpus size:${FINAL_SIZE}MB"
0 commit comments