Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
62 changes: 62 additions & 0 deletions .github/scripts/test-summary.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
# test-summary.sh
#
# Post-run command for gotestsum (--post-run-command).
# Called automatically after all test runs and reruns complete.
#
# Responsibilities:
# 1. Detect flaky tests: tests that failed at least once but ultimately passed
# on rerun. These are identified by having both "fail" and "pass" actions
# for the same test name in the JSON output.
# 2. Expose outputs to subsequent GitHub Actions steps via $GITHUB_OUTPUT:
# - has_flaky: "true" if any flaky tests were detected, "false" otherwise
# - flaky_count: number of flaky tests
# 3. Append a summary to the GitHub Actions job summary ($GITHUB_STEP_SUMMARY).
#
# Environment variables provided by gotestsum:
# GOTESTSUM_JSONFILE path to the JSON file with all test events (test2json format)
# TESTS_FAILED number of tests that ultimately failed
# TESTS_TOTAL total number of tests run
# GOTESTSUM_ELAPSED total elapsed time (e.g. "12.34s")

set -eo pipefail

# Extract names of flaky tests: those that appear with both a "fail" and a "pass"
# action. These passed only after being rerun, making them flaky.
FLAKY_NAMES=$(jq -rs '[
[.[] | select(.Test != null)] |
group_by(.Test)[] |
select(any(.[]; .Action == "fail") and any(.[]; .Action == "pass")) |
"- `\(.[0].Package)/\(.[0].Test)`"
] | join("\n")' "$GOTESTSUM_JSONFILE")

FLAKY=$(echo "$FLAKY_NAMES" | grep -c "^-" || true)

# Determine the overall status line based on final failure count.
if [ "$TESTS_FAILED" -gt 0 ]; then
STATUS="❌ $TESTS_FAILED test(s) failed"
else
STATUS="✅ All tests passed!"
fi

# Expose flaky test info to subsequent steps in the same job.
# flaky_names uses the multiline delimiter syntax required by GitHub Actions.
echo "has_flaky=$([ "$FLAKY" -gt 0 ] && echo true || echo false)" >> "$GITHUB_OUTPUT"
echo "flaky_count=$FLAKY" >> "$GITHUB_OUTPUT"
echo "tests_total=$TESTS_TOTAL" >> "$GITHUB_OUTPUT"
echo "elapsed=$GOTESTSUM_ELAPSED" >> "$GITHUB_OUTPUT"
{
echo "flaky_names<<EOF"
echo "$FLAKY_NAMES"
echo "EOF"
} >> "$GITHUB_OUTPUT"

# Write a summary to the GitHub Actions job summary page.
{
echo "## Test Results"
echo "$STATUS | $TESTS_TOTAL tests in $GOTESTSUM_ELAPSED"
if [ "$FLAKY" -gt 0 ]; then
printf '\n> ⚠️ %s test(s) were flaky (failed then passed on rerun)\n\n' "$FLAKY"
echo "$FLAKY_NAMES"
fi
} >> "$GITHUB_STEP_SUMMARY"
71 changes: 47 additions & 24 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ on:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:

build:
name: Build
permissions:
contents: read
id-token: write # OIDC with Codecov
issues: write
pull-requests: write
runs-on: ubuntu-latest
steps:
Expand All @@ -39,37 +38,61 @@ jobs:
run: sudo sysctl -w kernel.unprivileged_userns_clone=1

- name: Test
run: go test -tags="nomsgpack,remote,exclude_graphdriver_btrfs,containers_image_openpgp" -v -json -race -covermode atomic -coverprofile coverage.txt ./... 2>&1 | go tool -modfile=tools.mod go-junit-report -parser gojson -set-exit-code > junit.xml
id: test
run: |
go tool -modfile=tools.mod gotestsum \
--jsonfile test-report.json \
--format testname \
--rerun-fails=3 \
--rerun-fails-max-failures=10 \
--packages="./..." \
--post-run-command .github/scripts/test-summary.sh \
-- -tags="nomsgpack,remote,exclude_graphdriver_btrfs,containers_image_openpgp" -race -covermode atomic -coverprofile=coverage.out ./...

- name: Display JUnit report
- name: Generate HTML test report
if: ${{ !cancelled() }}
run: cat junit.xml
run: cat test-report.json | go tool -modfile=tools.mod go-test-report

- name: Upload junit report
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@59db25f34e16620e48ab4bb9e4a5dce155cb5432 # v8.0.0
if: ${{ !cancelled() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
with:
name: junit-report
path: junit.xml
args: >
-Dsonar.go.tests.reportPaths=test-report.json
-Dsonar.go.coverage.reportPaths=coverage.out

- name: Upload coverage to Codecov
- name: Upload HTML Test report
if: ${{ !cancelled() }}
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
id: upload
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
use_oidc: true
fail_ci_if_error: true
name: html-test-report
path: test_report.html
compression-level: 0
archive: false
retention-days: 2

- name: Upload test results to Codecov
if: ${{ !cancelled() }}
uses: codecov/test-results-action@0fa95f0e1eeaafde2c782583b36b28ad0d8c77d3 # v1.2.1
- name: Find existing test results comment
if: github.event_name == 'pull_request' && !cancelled()
uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0
id: fc
with:
use_oidc: true
fail_ci_if_error: true
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: Test Results

- name: Run Basic Test Results Action
if: ${{ !cancelled() && github.event_name == 'pull_request' }}
uses: codecov/basic-test-results@c46ff461955b5cd6eb57cbe9ff22f3b77fc15824 # v1
- name: Create or update test results comment
if: github.event_name == 'pull_request' && !cancelled()
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
file: junit.xml
disable-search: true
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body: |
## Test Results
${{ steps.test.outcome == 'success' && '✅ All tests passed!' || '❌ Some tests failed' }} | ${{ steps.test.outputs.tests_total }} tests in ${{ steps.test.outputs.elapsed }}
${{ steps.test.outputs.has_flaky == 'true' && format('> ⚠️ {0} test(s) were flaky (failed then passed on rerun)', steps.test.outputs.flaky_count) || '' }}
${{ steps.test.outputs.flaky_names }}
[View HTML Test Report](${{ steps.upload.outputs.artifact-url }})
edit-mode: replace
2 changes: 1 addition & 1 deletion .github/workflows/goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ jobs:
exit 1
fi

go tool -modfile=tools.mod gsa -o diff.txt "${{ steps.latest-release.outputs.artifact_path }}" "$built_path"
GOEXPERIMENT=jsonv2 go tool -modfile=tools.mod gsa -o diff.txt "${{ steps.latest-release.outputs.artifact_path }}" "$built_path"
echo "diff<<EOF" >> $GITHUB_OUTPUT
echo "$(cat diff.txt)" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
.PHONY: run gen build test lint fmt docker docs

.DEFAULT_GOAL := build

export GOFLAGS=-tags=nomsgpack,remote,exclude_graphdriver_btrfs,containers_image_openpgp

run:
Expand All @@ -8,6 +10,7 @@ run:
gen:
go generate -v ./...

.PHONY: build
build:
goreleaser build --single-target --snapshot --clean --output .

Expand Down
22 changes: 12 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@ go 1.26.0

require (
github.com/containers/podman/v5 v5.8.2
github.com/docker/docker v28.5.2+incompatible
github.com/gin-gonic/gin v1.12.0
github.com/google/go-cmp v0.7.0
github.com/lmittmann/tint v1.1.3
github.com/moby/moby/api v1.54.2
github.com/moby/moby/client v0.4.1
github.com/neilotoole/slogt v1.1.0
github.com/pkg/errors v0.9.1
github.com/samber/slog-gin v1.21.1
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
github.com/spf13/viper v1.21.0
github.com/stretchr/testify v1.11.1
github.com/testcontainers/testcontainers-go v0.41.0
github.com/testcontainers/testcontainers-go/modules/dind v0.41.0
github.com/testcontainers/testcontainers-go/modules/k3s v0.41.0
github.com/testcontainers/testcontainers-go/modules/valkey v0.41.0
github.com/testcontainers/testcontainers-go v0.42.0
github.com/testcontainers/testcontainers-go/modules/dind v0.42.0
github.com/testcontainers/testcontainers-go/modules/k3s v0.42.0
github.com/testcontainers/testcontainers-go/modules/valkey v0.42.0
github.com/tniswong/go.rfcx v0.0.0-20181019234604-07783c52761f
github.com/valkey-io/valkey-go v1.0.74
go.podman.io/image/v5 v5.39.2
Expand Down Expand Up @@ -62,8 +63,9 @@ require (
github.com/disiqueira/gotree/v3 v3.0.2 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker v28.5.2+incompatible // indirect
github.com/docker/docker-credential-helpers v0.9.4 // indirect
github.com/docker/go-connections v0.6.0 // indirect
github.com/docker/go-connections v0.7.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/ebitengine/purego v0.10.0 // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
Expand Down Expand Up @@ -100,7 +102,7 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kevinburke/ssh_config v1.4.0 // indirect
github.com/klauspost/compress v1.18.2 // indirect
github.com/klauspost/compress v1.18.5 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/kr/fs v0.1.0 // indirect
Expand All @@ -118,7 +120,7 @@ require (
github.com/mistifyio/go-zfs/v3 v3.1.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/go-archive v0.2.0 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
github.com/moby/patternmatcher v0.6.1 // indirect
github.com/moby/sys/capability v0.4.0 // indirect
github.com/moby/sys/mountinfo v0.7.2 // indirect
github.com/moby/sys/sequential v0.6.0 // indirect
Expand Down Expand Up @@ -148,7 +150,7 @@ require (
github.com/rivo/uniseg v0.4.7 // indirect
github.com/sagikazarmark/locafero v0.11.0 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.9.1 // indirect
github.com/shirou/gopsutil/v4 v4.26.2 // indirect
github.com/shirou/gopsutil/v4 v4.26.3 // indirect
github.com/sigstore/fulcio v1.7.1 // indirect
github.com/sigstore/protobuf-specs v0.4.1 // indirect
github.com/sigstore/sigstore v1.9.5 // indirect
Expand Down Expand Up @@ -186,7 +188,7 @@ require (
golang.org/x/crypto v0.48.0 // indirect
golang.org/x/net v0.51.0 // indirect
golang.org/x/oauth2 v0.34.0 // indirect
golang.org/x/sys v0.41.0 // indirect
golang.org/x/sys v0.42.0 // indirect
golang.org/x/term v0.40.0 // indirect
golang.org/x/text v0.34.0 // indirect
golang.org/x/time v0.12.0 // indirect
Expand Down
Loading
Loading