From f534b7c3650637e6eb453f20e9533158c6f75a46 Mon Sep 17 00:00:00 2001 From: Armel Soro Date: Tue, 12 May 2026 22:50:30 +0200 Subject: [PATCH 01/10] ci: upload unit test coverage to Codecov Add codecov.yml configuration and upload steps to the PR and nightly workflows. Coverage checks are informational only and will not block merges. Uploads happen after `make test` using codecov-action v6. The PR workflow uses override_commit/override_pr to handle the pull_request_target trigger correctly. The nightly workflow uses override_branch for the branch matrix. RHIDP-13388 Assisted-by: Claude --- .github/workflows/nightly.yaml | 11 +++++++++++ .github/workflows/pr.yaml | 12 ++++++++++++ codecov.yml | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 codecov.yml diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 0ea2cdd84..1e6153d7e 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -70,6 +70,17 @@ jobs: # run this stage only if there are changes that match the includes and not the excludes run: make test + - name: Upload coverage to Codecov + if: ${{ steps.operator-image-existence-checker.outputs.OPERATOR_IMAGE_EXISTS == 'true' }} + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6 + with: + files: cover.out + flags: unittests,nightly + fail_ci_if_error: false + override_branch: ${{ matrix.branch }} + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + - name: Create Kind cluster (integration tests) if: ${{ steps.operator-image-existence-checker.outputs.OPERATOR_IMAGE_EXISTS == 'true' }} uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 5cc234f86..c4c0232a6 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -80,6 +80,18 @@ jobs: if: steps.changed-files.outputs.any_changed == 'true' run: make test + - name: Upload coverage to Codecov + if: steps.changed-files.outputs.any_changed == 'true' + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6 + with: + files: cover.out + flags: unittests + fail_ci_if_error: false + override_commit: ${{ github.event.pull_request.head.sha }} + override_pr: ${{ github.event.number }} + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + - name: Create Kind cluster if: steps.changed-files.outputs.any_changed == 'true' uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0 diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..60f1f012c --- /dev/null +++ b/codecov.yml @@ -0,0 +1,34 @@ +codecov: + require_ci_to_pass: true + +coverage: + status: + project: + default: + target: auto + threshold: 1% + if_ci_failed: error + informational: true + patch: + default: + target: 80% + threshold: 5% + if_ci_failed: error + informational: true + +comment: + layout: "reach,diff,flags,files" + behavior: default + require_changes: true + require_base: false + require_head: true + +ignore: + - "api/**" + - "**/zz_generated*.go" + - "bundle/**" + - "config/**" + - "tests/**" + - "integration_tests/**" + - "hack/**" + - "cmd/main.go" From 6e76e6d01e069a24854af7554a07536fdb2e6fdc Mon Sep 17 00:00:00 2001 From: Armel Soro Date: Wed, 13 May 2026 09:44:44 +0200 Subject: [PATCH 02/10] ci: run lint, test and coverage upload unconditionally in nightly The operator image existence check is only needed for integration and E2E tests which deploy the operator. Lint, unit tests, and coverage upload do not depend on the image and should always run. Assisted-by: Claude --- .github/workflows/nightly.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 1e6153d7e..ebf82483d 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -55,23 +55,18 @@ jobs: rm_cmd: "rmz" - name: Setup Go - if: ${{ steps.operator-image-existence-checker.outputs.OPERATOR_IMAGE_EXISTS == 'true' }} uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: 'go.mod' # gosec needs a "build" stage so connect it to the lint step which we always do - name: Build - if: ${{ steps.operator-image-existence-checker.outputs.OPERATOR_IMAGE_EXISTS == 'true' }} run: make lint - name: Test - if: ${{ steps.operator-image-existence-checker.outputs.OPERATOR_IMAGE_EXISTS == 'true' }} - # run this stage only if there are changes that match the includes and not the excludes run: make test - name: Upload coverage to Codecov - if: ${{ steps.operator-image-existence-checker.outputs.OPERATOR_IMAGE_EXISTS == 'true' }} uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6 with: files: cover.out From 4c8f8f1a48a36eaeebe895068e31224be82d3fa4 Mon Sep 17 00:00:00 2001 From: Armel Soro Date: Wed, 13 May 2026 10:09:28 +0200 Subject: [PATCH 03/10] ci: add workflow to validate codecov.yml Validates the Codecov configuration against the Codecov API on changes to codecov.yml or the workflow itself. Assisted-by: Claude --- .github/workflows/codecov-checks.yaml | 34 +++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/codecov-checks.yaml diff --git a/.github/workflows/codecov-checks.yaml b/.github/workflows/codecov-checks.yaml new file mode 100644 index 000000000..2b820f266 --- /dev/null +++ b/.github/workflows/codecov-checks.yaml @@ -0,0 +1,34 @@ +name: Codecov config validator + +on: + push: + paths: + - 'codecov.yml' + - '.github/workflows/codecov-checks.yaml' + pull_request: + paths: + - 'codecov.yml' + - '.github/workflows/codecov-checks.yaml' + +jobs: + codecov_validate: + runs-on: ubuntu-latest + env: + CODECOV_CONFIG_FILE: codecov.yml + CODECOV_VALIDATE_URL: https://codecov.io/validate + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Validate codecov.yml + run: | + response=$(curl -s -o /dev/null -w "%{http_code}" --data-binary @"${CODECOV_CONFIG_FILE}" "${CODECOV_VALIDATE_URL}") + if [ "$response" -eq 200 ]; then + echo "${CODECOV_CONFIG_FILE} is valid" + exit 0 + fi + if [ "$response" -eq 400 ]; then + echo "${CODECOV_CONFIG_FILE} is invalid (HTTP $response)" + curl --data-binary @"${CODECOV_CONFIG_FILE}" "${CODECOV_VALIDATE_URL}" + exit 1 + fi + echo "::warning ::Codecov validation endpoint returned HTTP $response. This may be a transient issue — please retry." + exit 1 From e4009c44f9dba566f44694d867431e324270e527 Mon Sep 17 00:00:00 2001 From: Armel Soro Date: Wed, 13 May 2026 11:04:29 +0200 Subject: [PATCH 04/10] ci: fail CI on Codecov upload errors Ensure coverage upload failures are surfaced as CI failures rather than silently ignored, so missing coverage data is caught early. Assisted-by: Claude --- .github/workflows/nightly.yaml | 2 +- .github/workflows/pr.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index ebf82483d..78bdb70be 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -71,7 +71,7 @@ jobs: with: files: cover.out flags: unittests,nightly - fail_ci_if_error: false + fail_ci_if_error: true override_branch: ${{ matrix.branch }} env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index c4c0232a6..7f6aa697c 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -86,7 +86,7 @@ jobs: with: files: cover.out flags: unittests - fail_ci_if_error: false + fail_ci_if_error: true override_commit: ${{ github.event.pull_request.head.sha }} override_pr: ${{ github.event.number }} env: From 663cefdec3980a77f5ca1ec755cfdfc189e402fb Mon Sep 17 00:00:00 2001 From: Armel Soro Date: Wed, 13 May 2026 11:05:49 +0200 Subject: [PATCH 05/10] ci: pin nightly Codecov upload to checked-out commit SHA Capture the exact HEAD after checkout and pass it as override_commit to the Codecov action, ensuring the coverage report is associated with the correct commit regardless of scheduling timing. Assisted-by: Claude --- .github/workflows/nightly.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 78bdb70be..5be73cbcf 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -30,6 +30,7 @@ jobs: - name: Set env vars run: | + echo "CODECOV_COMMIT_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV OPERATOR_MANIFEST="${{ github.workspace }}/dist/rhdh/install.yaml" echo "OPERATOR_MANIFEST=${OPERATOR_MANIFEST}" >> $GITHUB_ENV OPERATOR_IMAGE=$(curl -s "file://${OPERATOR_MANIFEST}" | yq 'select(.kind == "Deployment" and .metadata.labels.app == "rhdh-operator") | .spec.template.spec.containers[0].image') @@ -72,6 +73,7 @@ jobs: files: cover.out flags: unittests,nightly fail_ci_if_error: true + override_commit: ${{ env.CODECOV_COMMIT_SHA }} override_branch: ${{ matrix.branch }} env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From c7257362e2886b7ec7e85ab9e279696125d2da8b Mon Sep 17 00:00:00 2001 From: Armel Soro Date: Wed, 13 May 2026 11:06:46 +0200 Subject: [PATCH 06/10] ci: add curl timeouts and retries to Codecov validator Add --connect-timeout, --max-time, --retry and --retry-all-errors to prevent hangs and reduce transient failures. Non-200/400 responses after retries now emit a warning instead of failing the job. Assisted-by: Claude --- .github/workflows/codecov-checks.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codecov-checks.yaml b/.github/workflows/codecov-checks.yaml index 2b820f266..802198fae 100644 --- a/.github/workflows/codecov-checks.yaml +++ b/.github/workflows/codecov-checks.yaml @@ -19,16 +19,17 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Validate codecov.yml + env: + CURL_OPTS: "--connect-timeout 10 --max-time 30 --retry 3 --retry-all-errors" run: | - response=$(curl -s -o /dev/null -w "%{http_code}" --data-binary @"${CODECOV_CONFIG_FILE}" "${CODECOV_VALIDATE_URL}") + response=$(curl -s -o /dev/null -w "%{http_code}" ${CURL_OPTS} --data-binary @"${CODECOV_CONFIG_FILE}" "${CODECOV_VALIDATE_URL}") if [ "$response" -eq 200 ]; then echo "${CODECOV_CONFIG_FILE} is valid" exit 0 fi if [ "$response" -eq 400 ]; then echo "${CODECOV_CONFIG_FILE} is invalid (HTTP $response)" - curl --data-binary @"${CODECOV_CONFIG_FILE}" "${CODECOV_VALIDATE_URL}" + curl ${CURL_OPTS} --data-binary @"${CODECOV_CONFIG_FILE}" "${CODECOV_VALIDATE_URL}" exit 1 fi - echo "::warning ::Codecov validation endpoint returned HTTP $response. This may be a transient issue — please retry." - exit 1 + echo "::warning ::Codecov validation endpoint returned HTTP $response after retries. This may be a transient issue — please re-run the job." From 76d20ad9001442948bb5784e8cfb0b58d54eca94 Mon Sep 17 00:00:00 2001 From: Armel Soro Date: Wed, 13 May 2026 16:59:14 +0200 Subject: [PATCH 07/10] Apply suggestions from code review Co-authored-by: Gustavo Lira e Silva --- .github/workflows/nightly.yaml | 5 ++--- .github/workflows/pr.yaml | 5 ++--- codecov.yml | 5 +++++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 5be73cbcf..af76be9b5 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -70,13 +70,12 @@ jobs: - name: Upload coverage to Codecov uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6 with: + token: ${{ secrets.CODECOV_TOKEN }} files: cover.out flags: unittests,nightly - fail_ci_if_error: true + fail_ci_if_error: false override_commit: ${{ env.CODECOV_COMMIT_SHA }} override_branch: ${{ matrix.branch }} - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: Create Kind cluster (integration tests) if: ${{ steps.operator-image-existence-checker.outputs.OPERATOR_IMAGE_EXISTS == 'true' }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 7f6aa697c..8a69a43bf 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -84,13 +84,12 @@ jobs: if: steps.changed-files.outputs.any_changed == 'true' uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6 with: + token: ${{ secrets.CODECOV_TOKEN }} files: cover.out flags: unittests - fail_ci_if_error: true + fail_ci_if_error: false override_commit: ${{ github.event.pull_request.head.sha }} override_pr: ${{ github.event.number }} - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: Create Kind cluster if: steps.changed-files.outputs.any_changed == 'true' diff --git a/codecov.yml b/codecov.yml index 60f1f012c..dc578644f 100644 --- a/codecov.yml +++ b/codecov.yml @@ -23,6 +23,11 @@ comment: require_base: false require_head: true +flag_management: + individual_flags: + - name: unittests + carryforward: true + ignore: - "api/**" - "**/zz_generated*.go" From 76a3176aea1577d86ee4da03a663ba83c75033bb Mon Sep 17 00:00:00 2001 From: Armel Soro Date: Wed, 13 May 2026 17:01:44 +0200 Subject: [PATCH 08/10] ci: rename CODECOV_COMMIT_SHA to COMMIT_SHA in nightly workflow The env var is a generic checked-out HEAD reference, not specific to Codecov. Assisted-by: Claude --- .github/workflows/nightly.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index af76be9b5..2004c0708 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -30,7 +30,7 @@ jobs: - name: Set env vars run: | - echo "CODECOV_COMMIT_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV + echo "COMMIT_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV OPERATOR_MANIFEST="${{ github.workspace }}/dist/rhdh/install.yaml" echo "OPERATOR_MANIFEST=${OPERATOR_MANIFEST}" >> $GITHUB_ENV OPERATOR_IMAGE=$(curl -s "file://${OPERATOR_MANIFEST}" | yq 'select(.kind == "Deployment" and .metadata.labels.app == "rhdh-operator") | .spec.template.spec.containers[0].image') @@ -74,7 +74,7 @@ jobs: files: cover.out flags: unittests,nightly fail_ci_if_error: false - override_commit: ${{ env.CODECOV_COMMIT_SHA }} + override_commit: ${{ env.COMMIT_SHA }} override_branch: ${{ matrix.branch }} - name: Create Kind cluster (integration tests) From 5a89c08da586a7556bab444770a3f0cf9aec34ab Mon Sep 17 00:00:00 2001 From: Armel Soro Date: Thu, 14 May 2026 21:17:17 +0200 Subject: [PATCH 09/10] Apply suggestions from code review Co-authored-by: Gustavo Lira e Silva --- .github/workflows/codecov-checks.yaml | 16 ++++++++++------ codecov.yml | 4 +++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/codecov-checks.yaml b/.github/workflows/codecov-checks.yaml index 802198fae..082483641 100644 --- a/.github/workflows/codecov-checks.yaml +++ b/.github/workflows/codecov-checks.yaml @@ -22,14 +22,18 @@ jobs: env: CURL_OPTS: "--connect-timeout 10 --max-time 30 --retry 3 --retry-all-errors" run: | - response=$(curl -s -o /dev/null -w "%{http_code}" ${CURL_OPTS} --data-binary @"${CODECOV_CONFIG_FILE}" "${CODECOV_VALIDATE_URL}") - if [ "$response" -eq 200 ]; then + output=$(curl -s -w "\n%{http_code}" ${CURL_OPTS} --data-binary @"${CODECOV_CONFIG_FILE}" "${CODECOV_VALIDATE_URL}") + http_code=$(echo "$output" | tail -1) + body=$(echo "$output" | sed '$d') + echo "$body" + if [ "$http_code" -eq 200 ]; then echo "${CODECOV_CONFIG_FILE} is valid" exit 0 fi - if [ "$response" -eq 400 ]; then - echo "${CODECOV_CONFIG_FILE} is invalid (HTTP $response)" - curl ${CURL_OPTS} --data-binary @"${CODECOV_CONFIG_FILE}" "${CODECOV_VALIDATE_URL}" + if [ "$http_code" -eq 400 ]; then + echo "${CODECOV_CONFIG_FILE} is invalid (HTTP $http_code)" exit 1 fi - echo "::warning ::Codecov validation endpoint returned HTTP $response after retries. This may be a transient issue — please re-run the job." + echo "::warning ::Codecov validation endpoint returned HTTP $http_code after retries. This may be a transient issue — please re-run the job." + # Don't fail the job on transient Codecov API issues + exit 0 diff --git a/codecov.yml b/codecov.yml index dc578644f..3bcf8ea2d 100644 --- a/codecov.yml +++ b/codecov.yml @@ -11,7 +11,7 @@ coverage: informational: true patch: default: - target: 80% + target: auto threshold: 5% if_ci_failed: error informational: true @@ -27,6 +27,8 @@ flag_management: individual_flags: - name: unittests carryforward: true + - name: nightly + carryforward: true ignore: - "api/**" From bf5d8868512b9de155098ee0d218f79696760629 Mon Sep 17 00:00:00 2001 From: Armel Soro Date: Thu, 14 May 2026 21:39:23 +0200 Subject: [PATCH 10/10] Apply suggestion from @rm3l --- .github/workflows/codecov-checks.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codecov-checks.yaml b/.github/workflows/codecov-checks.yaml index 082483641..2f12bce62 100644 --- a/.github/workflows/codecov-checks.yaml +++ b/.github/workflows/codecov-checks.yaml @@ -35,5 +35,5 @@ jobs: exit 1 fi echo "::warning ::Codecov validation endpoint returned HTTP $http_code after retries. This may be a transient issue — please re-run the job." - # Don't fail the job on transient Codecov API issues - exit 0 + # Fail earlier on transient Codecov API issues, so we can catch the issue and eventually retry + exit 1