From 49a741f141f7826bf6ebe13a465f0fe8de77bb0d Mon Sep 17 00:00:00 2001 From: Johnathan Falk Date: Mon, 5 Oct 2026 00:50:08 -0400 Subject: [PATCH] fix(ci): skip the dead Go coverage rerun without .testcoverage.yml; go-ci cap 40m The Generate step re-ran the full suite for a checker that exits at once when .testcoverage.yml is missing, pushing go-ci past its 30m cap. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017MtQ5LP2n3t3bs7AhptkKJ --- .github/workflows/reusable-ci.yml | 15 +++++++++++---- .../20261005_go_ci_skip_dead_coverage_rerun.md | 6 ++++++ 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 changelog.d/20261005_go_ci_skip_dead_coverage_rerun.md diff --git a/.github/workflows/reusable-ci.yml b/.github/workflows/reusable-ci.yml index 9d050616..2254a442 100644 --- a/.github/workflows/reusable-ci.yml +++ b/.github/workflows/reusable-ci.yml @@ -1,5 +1,5 @@ # file: .github/workflows/reusable-ci.yml -# version: 1.14.0 +# version: 1.15.0 # guid: reusable-ci-2025-09-24-core-workflow name: Reusable CI Workflow @@ -409,7 +409,12 @@ jobs: fail-fast: false matrix: ${{ fromJSON(needs.load-config.outputs.go-matrix) }} runs-on: ${{ matrix.os }} - timeout-minutes: 30 + # 40, not 30: the go-test helper runs `go test -race` with no -timeout, so + # a hung test binary is killed by Go's default 10m. The cap must exceed + # setup (~4.5m) + the slowest measured suite (~20.5m) + that 10m, or the + # runner cancels the job before Go prints the goroutine dump naming the + # stuck test. + timeout-minutes: 40 permissions: contents: read env: @@ -481,13 +486,15 @@ jobs: command: go-test coverage-threshold: ${{ inputs.coverage-threshold || needs.load-config.outputs.coverage-threshold }} + # Only feeds go-test-coverage, which exits at once without .testcoverage.yml; + # without the file this step was a dead full-suite rerun (6-8 min). - name: Generate Go coverage profile - if: ${{ !inputs.skip-tests }} + if: ${{ !inputs.skip-tests && hashFiles('.testcoverage.yml') != '' }} continue-on-error: true run: go test ./... -coverprofile=./cover.out -covermode=atomic -coverpkg=./... - name: Check Go test coverage - if: ${{ !inputs.skip-tests }} + if: ${{ !inputs.skip-tests && hashFiles('.testcoverage.yml') != '' }} continue-on-error: true uses: vladopajic/go-test-coverage@f94bcf0d6b9fa5fb8b783830b22648f6c17475e2 # v2.19.0 with: diff --git a/changelog.d/20261005_go_ci_skip_dead_coverage_rerun.md b/changelog.d/20261005_go_ci_skip_dead_coverage_rerun.md new file mode 100644 index 00000000..ea75c92f --- /dev/null +++ b/changelog.d/20261005_go_ci_skip_dead_coverage_rerun.md @@ -0,0 +1,6 @@ +### Fixed + +#### reusable-ci: no dead coverage rerun, 40-minute Go CI cap + +- "Generate Go coverage profile" and "Check Go test coverage" now run only when the repo has `.testcoverage.yml`. Without it the first step re-ran the whole suite (6–8 min) for a checker that exits immediately, which pushed audiobook-organizer's go-ci over its 30-minute cap. +- `go-ci` `timeout-minutes` is now 40, so a hung test is killed by Go's 10-minute test timeout (with a goroutine dump naming it) before the runner cancels the job.