This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git
The following commit(s) were added to refs/heads/main by this push:
new 3149eb5ce5 revert: route all Codecov flags through the deferred
workflow_run upload (#6840)
3149eb5ce5 is described below
commit 3149eb5ce55de0db029bdba2c3106684e6c65a74
Author: Xinyuan Lin <[email protected]>
AuthorDate: Thu Jul 23 14:33:49 2026 -0700
revert: route all Codecov flags through the deferred workflow_run upload
(#6840)
### What changes were proposed in this PR?
Reverts #6730 ("ci: route all Codecov flags through the deferred
workflow_run upload").
Together with the already-merged #6837 (revert of #6824), this fully
backs out the deferred `workflow_run` Codecov upload: the inline
`codecov/codecov-action` steps are restored in `build.yml` for every
flag, and both `codecov-upload.yml` and
`.github/scripts/stage-codecov.sh` are removed.
The deferred approach regressed coverage — because the upload moved out
of the Required Checks run, Codecov built each PR's comment from
carryforward before the deferred upload landed, so every PR showed its
own flag as `Carriedforward` instead of a fresh delta (full analysis in
#6839). Restoring inline uploads brings back fresh per-PR coverage.
### Any related issues, documentation, discussions?
Closes #6839
### How was this PR tested?
Revert of CI-only workflow changes; no product code is affected.
Verified on the branch that `build.yml` restores the inline
`codecov-action` upload steps for all flags (frontend, amber,
amber-integration, the six platform services, pyamber, agent-service)
and that `codecov-upload.yml` and `stage-codecov.sh` are gone. Fresh
(non-carryforward) coverage is confirmed once this merges and the next
PR's Codecov comment again shows its own flag with a delta.
### Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Opus 4.8 [1M context])
---
.github/scripts/stage-codecov.sh | 72 ----------
.github/workflows/build.yml | 260 +++++++++++++++++------------------
.github/workflows/codecov-upload.yml | 213 ----------------------------
3 files changed, 125 insertions(+), 420 deletions(-)
diff --git a/.github/scripts/stage-codecov.sh b/.github/scripts/stage-codecov.sh
deleted file mode 100644
index 431993aad1..0000000000
--- a/.github/scripts/stage-codecov.sh
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env bash
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Stage coverage + test-result reports for the deferred Codecov upload
-# (.github/workflows/codecov-upload.yml). Fork PRs get no CODECOV_TOKEN on the
-# pull_request event, so the build stages its reports as a `codecov-<flag>`
-# artifact instead of uploading inline; the workflow_run job re-uploads them
with
-# a token (see codecov-upload.yml / #6685).
-#
-# Produces ./cc/coverage/ (coverage reports), ./cc/results/ (JUnit XMLs), and
the
-# pr/sha/branch identifier files. Directory structure is preserved so
same-basename
-# reports (e.g. amber's per-module jacoco.xml across ~8 modules) do not
collide;
-# the deferred job points `directory:` at cc/coverage and cc/results so
Codecov's
-# recursive search finds every file under each.
-#
-# Inputs (env):
-# CC_COVERAGE space-separated list of coverage sources — each a literal
file or
-# a `find -path` glob (use * which matches across /), e.g.
-# "*/target/scala-2.13/jacoco/report/jacoco.xml". May be empty
for a
-# test-results-only flag.
-# CC_RESULTS same, for JUnit test-result XMLs.
-# CC_PR PR number (empty on push builds)
-# CC_SHA head commit sha
-# CC_BRANCH head branch
-set -uo pipefail
-
-mkdir -p cc/coverage cc/results
-
-copy_into() {
- dest="$1"; shift
- for src in "$@"; do
- if [ -e "$src" ]; then
- # literal existing path
- cp --parents "$src" "$dest/" 2>/dev/null || cp "$src" "$dest/"
2>/dev/null || true
- else
- # treat as a find -path glob (matches across / since find's * does)
- find . -path "./$src" -o -path "$src" 2>/dev/null \
- | while IFS= read -r f; do
- [ -f "$f" ] && cp --parents "$f" "$dest/" 2>/dev/null || true
- done
- fi
- done
-}
-
-# shellcheck disable=SC2086 # intentional word-splitting into separate globs
-copy_into cc/coverage ${CC_COVERAGE:-}
-# shellcheck disable=SC2086
-copy_into cc/results ${CC_RESULTS:-}
-
-printf '%s' "${CC_PR:-}" > cc/pr-number.txt
-printf '%s' "${CC_SHA:-}" > cc/commit-sha.txt
-printf '%s' "${CC_BRANCH:-}" > cc/branch.txt
-
-echo "Staged coverage files:"
-find cc/coverage -type f 2>/dev/null | sed 's/^/ /' || true
-echo "Staged result files:"
-find cc/results -type f 2>/dev/null | sed 's/^/ /' || true
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 34eeff6ae3..1355a4dbbc 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -137,36 +137,44 @@ jobs:
run: ./bin/licensing/check_binary_deps.py ${{ inputs.mode == 'PR' &&
'--ignore-transitive-version' || '' }} npm frontend/dist/3rdpartylicenses.json
- name: Run frontend unit tests
run: yarn --cwd frontend run test:ci
+ - name: Upload frontend coverage to Codecov
+ if: matrix.os == 'ubuntu-latest' && always()
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./frontend/coverage/**/lcov.info
+ flags: frontend
+ fail_ci_if_error: false
+ - name: Upload frontend unit test results to Codecov
+ # vitest.config.ts adds a `junit` reporter that writes to junit.xml
+ # in the working dir; the @angular/build:unit-test runner forwards
+ # vitest config through unchanged.
+ if: matrix.os == 'ubuntu-latest' && !cancelled()
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./frontend/junit.xml
+ flags: frontend
+ report_type: test_results
+ disable_search: true
+ fail_ci_if_error: false
- name: Install Playwright Chromium
run: yarn --cwd frontend playwright install ${{ matrix.os ==
'ubuntu-latest' && '--with-deps' || '' }} chromium
- name: Run frontend browser-mode tests
run: yarn --cwd frontend ng run gui:test-browser
- # Codecov upload is deferred to codecov-upload.yml (workflow_run) so
fork PRs
- # get authenticated uploads and a reliable PR comment — see that file and
- # #6685. Stage this flag's reports as the `codecov-frontend` artifact
instead
- # of uploading inline. The `!cancelled()` guard is a status-check
function, so
- # it overrides the implicit success() and staging still runs when the
unit or
- # browser tests fail (matching the old always()/!cancelled() steps); it
only
- # skips a cancelled run. Skipped on backport builds (different ref +
would
- # collide on the artifact name across the target matrix).
- - name: Stage frontend coverage for deferred Codecov upload
- if: matrix.os == 'ubuntu-latest' && inputs.backport_target_branch ==
'' && !cancelled()
- shell: bash
- env:
- CC_COVERAGE: frontend/coverage/gui/lcov.info
- CC_RESULTS: frontend/junit.xml frontend/junit-browser.xml
- CC_PR: ${{ github.event.pull_request.number }}
- CC_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
- CC_BRANCH: ${{ github.event.pull_request.head.ref || github.ref_name
}}
- run: bash .github/scripts/stage-codecov.sh
- - name: Upload frontend Codecov artifact
- if: matrix.os == 'ubuntu-latest' && inputs.backport_target_branch ==
'' && !cancelled()
- uses: actions/upload-artifact@v4
+ - name: Upload frontend browser-mode test results to Codecov
+ # vitest.browser.config.ts emits junit-browser.xml (distinct from
+ # the unit-test report). Same `frontend` flag — Codecov merges
+ # multi-file uploads under one flag.
+ if: matrix.os == 'ubuntu-latest' && !cancelled()
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
with:
- name: codecov-frontend
- path: cc/
- retention-days: 1
- if-no-files-found: warn
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./frontend/junit-browser.xml
+ flags: frontend
+ report_type: test_results
+ disable_search: true
+ fail_ci_if_error: false
amber:
# The amber job runs the cross-cutting Scala lints (scalafmtCheckAll,
@@ -292,29 +300,28 @@ jobs:
"WorkflowCore/jacoco" \
"WorkflowOperator/jacoco" \
"WorkflowExecutionService/jacoco"
- - name: Stage amber and common coverage for deferred Codecov upload
- # Deferred to codecov-upload.yml (workflow_run) so fork PRs get an
- # authenticated upload — see #6685. Multi-module globs: the staging
script
- # preserves the directory tree so the ~8 same-basename jacoco.xml (and
the
- # per-spec test-reports) don't collide when flattened. `!cancelled()`
keeps
- # staging on test failure; skipped on backport builds (artifact-name
clash).
- if: inputs.backport_target_branch == '' && !cancelled()
- shell: bash
- env:
- CC_COVERAGE: "*/target/scala-2.13/jacoco/report/jacoco.xml"
- CC_RESULTS: "*/target/test-reports/*.xml"
- CC_PR: ${{ github.event.pull_request.number }}
- CC_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
- CC_BRANCH: ${{ github.event.pull_request.head.ref || github.ref_name
}}
- run: bash .github/scripts/stage-codecov.sh
- - name: Upload amber Codecov artifact
- if: inputs.backport_target_branch == '' && !cancelled()
- uses: actions/upload-artifact@v4
+ - name: Upload amber and common coverage to Codecov
+ if: always()
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
with:
- name: codecov-amber
- path: cc/
- retention-days: 1
- if-no-files-found: warn
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./**/target/scala-2.13/jacoco/report/jacoco.xml
+ flags: amber
+ fail_ci_if_error: false
+ - name: Upload amber and common test results to Codecov
+ # ScalaTest writes one JUnit-XML per spec under each module's
+ # target/test-reports/ (configured ThisBuild in build.sbt). Glob
+ # picks them up from every module that ran in the jacoco invocation
+ # above. `!cancelled()` so test failures still upload (the point
+ # of Test Analytics).
+ if: ${{ !cancelled() }}
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./**/target/test-reports/*.xml
+ flags: amber
+ report_type: test_results
+ fail_ci_if_error: false
amber-integration:
# Runs Scala tests tagged @org.apache.texera.amber.tags.IntegrationTest —
@@ -649,30 +656,18 @@ jobs:
# --junit-xml feeds the Test Analytics upload below.
run: |
cd amber && pytest -m integration --junit-xml=junit-integration.xml
-sv
- - name: Stage amber-integration test results for deferred Codecov upload
- # Deferred to codecov-upload.yml (workflow_run) so fork PRs get an
- # authenticated upload — see #6685. Results-only flag (no jacoco).
Staged
- # on the ubuntu leg only: the integration specs run on both ubuntu and
- # macOS, so staging both would clash on the `codecov-amber-integration`
- # artifact name (upload-artifact@v4 rejects duplicates); the ubuntu
run is
- # representative for Test Analytics. Skipped on backport builds.
- if: matrix.os == 'ubuntu-latest' && inputs.backport_target_branch ==
'' && !cancelled()
- shell: bash
- env:
- CC_COVERAGE: ""
- CC_RESULTS: "*/target/test-reports/*.xml amber/junit-integration.xml"
- CC_PR: ${{ github.event.pull_request.number }}
- CC_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
- CC_BRANCH: ${{ github.event.pull_request.head.ref || github.ref_name
}}
- run: bash .github/scripts/stage-codecov.sh
- - name: Upload amber-integration Codecov artifact
- if: matrix.os == 'ubuntu-latest' && inputs.backport_target_branch ==
'' && !cancelled()
- uses: actions/upload-artifact@v4
+ - name: Upload amber integration test results to Codecov
+ # Two separate uploads because the ScalaTest and pytest runs each
+ # produce their own JUnit-XMLs and Codecov keys uploads by flag.
+ # `!cancelled()` so test failures still upload.
+ if: ${{ !cancelled() }}
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
with:
- name: codecov-amber-integration
- path: cc/
- retention-days: 1
- if-no-files-found: warn
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./**/target/test-reports/*.xml,./amber/junit-integration.xml
+ flags: amber-integration
+ report_type: test_results
+ fail_ci_if_error: false
platform:
# Per-service build, test, and license check for the non-amber Scala
@@ -773,30 +768,27 @@ jobs:
check_exit=1
fi
exit "$check_exit"
- - name: Stage ${{ matrix.service }} coverage for deferred Codecov upload
- # Deferred to codecov-upload.yml (workflow_run) so fork PRs get an
- # authenticated upload — see #6685. Per-service flag. Skipped on
backport
- # builds (artifact-name clash across the target matrix).
- if: inputs.backport_target_branch == '' && !cancelled()
- shell: bash
- env:
- CC_COVERAGE: "${{ matrix.service
}}/target/scala-2.13/jacoco/report/jacoco.xml"
- CC_RESULTS: "${{ matrix.service }}/target/test-reports/*.xml"
- CC_PR: ${{ github.event.pull_request.number }}
- CC_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
- CC_BRANCH: ${{ github.event.pull_request.head.ref || github.ref_name
}}
- run: bash .github/scripts/stage-codecov.sh
- - name: Upload ${{ matrix.service }} Codecov artifact
- # Adding a service to the matrix above also needs a matching
- # { flag: <service>, coverage: true } row in codecov-upload.yml, or
this
- # artifact is downloaded by nothing and the service's coverage is
dropped.
- if: inputs.backport_target_branch == '' && !cancelled()
- uses: actions/upload-artifact@v4
+ - name: Upload ${{ matrix.service }} coverage to Codecov
+ # Per-service flag so each matrix entry has its own Codecov view
+ # rather than being merged into one umbrella `platform` flag.
+ if: always()
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
with:
- name: codecov-${{ matrix.service }}
- path: cc/
- retention-days: 1
- if-no-files-found: warn
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./${{ matrix.service
}}/target/scala-2.13/jacoco/report/jacoco.xml
+ flags: ${{ matrix.service }}
+ fail_ci_if_error: false
+ - name: Upload ${{ matrix.service }} test results to Codecov
+ # Per-service Test Analytics, mirroring the coverage upload flag.
+ if: ${{ !cancelled() }}
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./${{ matrix.service }}/target/test-reports/*.xml
+ flags: ${{ matrix.service }}
+ report_type: test_results
+ disable_search: true
+ fail_ci_if_error: false
platform-integration:
# Boot smoke test for the platform services (mirrors amber-integration: an
@@ -1023,27 +1015,28 @@ jobs:
# test PR comments and flaky-test detection on main.
run: |
cd amber && pytest -m "not integration" --cov=src/main/python
--cov-report=xml --junit-xml=junit.xml -sv
- - name: Stage pyamber coverage for deferred Codecov upload
- # Deferred to codecov-upload.yml (workflow_run) so fork PRs get an
- # authenticated upload — see #6685. 3.12 leg only (the leg that
produced
- # coverage.xml / the pip-licenses snapshot). Skipped on backport
builds.
- if: matrix.python-version == '3.12' && inputs.backport_target_branch
== '' && !cancelled()
- shell: bash
- env:
- CC_COVERAGE: amber/coverage.xml
- CC_RESULTS: amber/junit.xml
- CC_PR: ${{ github.event.pull_request.number }}
- CC_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
- CC_BRANCH: ${{ github.event.pull_request.head.ref || github.ref_name
}}
- run: bash .github/scripts/stage-codecov.sh
- - name: Upload pyamber Codecov artifact
- if: matrix.python-version == '3.12' && inputs.backport_target_branch
== '' && !cancelled()
- uses: actions/upload-artifact@v4
+ - name: Upload pyamber coverage to Codecov
+ if: matrix.python-version == '3.12' && always()
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./amber/coverage.xml
+ flags: pyamber
+ fail_ci_if_error: false
+ - name: Upload pyamber test results to Codecov
+ # Test Analytics ingestion. Runs on the same 3.12 leg that uploads
+ # coverage to keep one canonical source per flag. `!cancelled()`
+ # rather than `always()` so we still upload on test failure (the
+ # whole point of Test Analytics) but skip cancelled runs.
+ if: matrix.python-version == '3.12' && !cancelled()
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
with:
- name: codecov-pyamber
- path: cc/
- retention-days: 1
- if-no-files-found: warn
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./amber/junit.xml
+ flags: pyamber
+ report_type: test_results
+ disable_search: true
+ fail_ci_if_error: false
agent-service:
if: ${{ inputs.run_agent_service }}
@@ -1092,29 +1085,26 @@ jobs:
# Test Analytics upload below can feed Codecov's failing-test PR
# comments and flaky-test detection on main.
run: bun test --coverage --coverage-reporter=lcov --reporter=junit
--reporter-outfile=junit.xml
- - name: Stage agent-service coverage for deferred Codecov upload
- # Deferred to codecov-upload.yml (workflow_run) so fork PRs get an
- # authenticated upload — see #6685. ubuntu leg only. working-directory
is
- # pinned to the workspace root (this job otherwise defaults to
- # agent-service/) so the staged cc/ lands where the artifact upload
expects.
- if: matrix.os == 'ubuntu-latest' && inputs.backport_target_branch ==
'' && !cancelled()
- shell: bash
- working-directory: ${{ github.workspace }}
- env:
- CC_COVERAGE: agent-service/coverage/lcov.info
- CC_RESULTS: agent-service/junit.xml
- CC_PR: ${{ github.event.pull_request.number }}
- CC_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
- CC_BRANCH: ${{ github.event.pull_request.head.ref || github.ref_name
}}
- run: bash .github/scripts/stage-codecov.sh
- - name: Upload agent-service Codecov artifact
- if: matrix.os == 'ubuntu-latest' && inputs.backport_target_branch ==
'' && !cancelled()
- uses: actions/upload-artifact@v4
+ - name: Upload agent-service coverage to Codecov
+ if: matrix.os == 'ubuntu-latest' && always()
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./agent-service/coverage/lcov.info
+ flags: agent-service
+ fail_ci_if_error: false
+ - name: Upload agent-service test results to Codecov
+ # Test Analytics ingestion. Runs on the same ubuntu leg that
+ # uploads coverage. `!cancelled()` so test failures still upload.
+ if: matrix.os == 'ubuntu-latest' && !cancelled()
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
with:
- name: codecov-agent-service
- path: cc/
- retention-days: 1
- if-no-files-found: warn
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./agent-service/junit.xml
+ flags: agent-service
+ report_type: test_results
+ disable_search: true
+ fail_ci_if_error: false
infra:
# Generic project-tooling job — runs the lightweight (no docker, no
diff --git a/.github/workflows/codecov-upload.yml
b/.github/workflows/codecov-upload.yml
deleted file mode 100644
index b43e22906e..0000000000
--- a/.github/workflows/codecov-upload.yml
+++ /dev/null
@@ -1,213 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Deferred, authenticated Codecov upload for coverage produced by "Required
Checks".
-#
-# Why this exists (reported on #6685): a PR from a fork never receives
-# secrets.CODECOV_TOKEN — the build runs on the `pull_request` event and GitHub
-# withholds secrets from fork runs. An inline upload from the build therefore
uses
-# Codecov's tokenless path, which is rate-limited; under a burst of fork-PR
uploads
-# Codecov processes the report but silently drops the PR comment. This
workflow runs
-# on `workflow_run`, in the base-repo context where the token IS available, and
-# re-uploads the staged coverage/test-results artifacts with authentication so
the
-# comment posts reliably even in bursts.
-#
-# Each build job stages its reports as a `codecov-<flag>` artifact with a
uniform
-# layout — coverage/ (coverage reports) and results/ (JUnit XMLs) plus
pr-number /
-# commit-sha / branch identifier files. The matrix below re-uploads each flag
with
-# `directory:` scoping so Codecov's search is confined to that flag's files
(this is
-# what lets the amber flag's ~8 same-basename module jacoco.xml reports upload
without
-# a fragile explicit file list). Codecov requires one upload per flag (flags
in a
-# single upload apply to all its files, and carryforward needs the flag at
upload
-# time), so the flags cannot be collapsed into fewer calls — the win here is
the
-# token, not fewer uploads.
-#
-# NOTE: `workflow_run` only fires from the copy of this file on the default
branch, so
-# this has NO effect until merged to main. After merge, exercise it manually
via the
-# workflow_dispatch entry below, passing a finished "Required Checks" run id.
-
-name: Codecov Upload
-
-on:
- workflow_run:
- workflows: ["Required Checks"]
- types:
- - completed
- workflow_dispatch:
- inputs:
- run_id:
- description: "Finished 'Required Checks' run id to pull the codecov-*
artifacts from"
- required: true
- type: string
-
-permissions:
- contents: read
- actions: read # download-artifact needs this to read artifacts from another
run
-
-jobs:
- upload:
- # Skip only a cancelled/skipped upstream; still run on failure so partial
- # coverage is reported (mirrors the build's always()/!cancelled() staging).
- if: >-
- github.event_name == 'workflow_dispatch' ||
- (github.event.workflow_run.conclusion != 'cancelled' &&
- github.event.workflow_run.conclusion != 'skipped')
- runs-on: ubuntu-latest
- # Job-level so the group can key on matrix.flag: one upload pass per source
- # run + flag, and a re-run of the source supersedes the previous attempt.
- concurrency:
- group: codecov-upload-${{ github.event.workflow_run.id || inputs.run_id
}}-${{ matrix.flag }}
- cancel-in-progress: false
- strategy:
- fail-fast: false
- matrix:
- # flag = artifact suffix (codecov-<flag>); coverage=false for the
- # test-results-only flag (amber-integration has no coverage report).
- #
- # KEEP IN SYNC with the coverage-producing jobs in build.yml: one row
per
- # codecov-<flag> artifact staged there — frontend, amber,
amber-integration,
- # pyamber, agent-service, and every service in build.yml's `platform`
matrix.
- # A flag staged in build.yml but missing here is downloaded by nothing
and
- # its coverage is silently dropped (the reverse — a row here with no
artifact
- # — is safe: the download continue-on-errors and the leg skips).
- include:
- - { flag: frontend, coverage: true }
- - { flag: amber, coverage: true }
- - { flag: amber-integration, coverage: false }
- - { flag: pyamber, coverage: true }
- - { flag: agent-service, coverage: true }
- - { flag: config-service, coverage: true }
- - { flag: access-control-service, coverage: true }
- - { flag: file-service, coverage: true }
- - { flag: computing-unit-managing-service, coverage: true }
- - { flag: workflow-compiling-service, coverage: true }
- - { flag: notebook-migration-service, coverage: true }
- steps:
- - name: Resolve source run id
- id: src
- shell: bash
- run: echo "run_id=${{ github.event.workflow_run.id || inputs.run_id
}}" >> "$GITHUB_OUTPUT"
- - name: Download staged coverage
- id: dl
- continue-on-error: true # absent when this flag's job was label-gated
out
- # Layout: stage-codecov.sh roots the artifact at cc/ (coverage/,
results/,
- # and the pr-number/commit-sha/branch txt files), so downloading to
path: cc
- # restores cc/coverage/**, cc/results/**, and cc/pr-number.txt — the
paths
- # the steps below reference. Keep that rooting if the staging script
changes.
- uses: actions/download-artifact@v4
- with:
- name: codecov-${{ matrix.flag }}
- path: cc
- run-id: ${{ steps.src.outputs.run_id }}
- github-token: ${{ github.token }}
- - name: Read coverage metadata
- if: steps.dl.outcome == 'success'
- id: meta
- shell: bash
- # Artifact content comes from a (possibly fork) PR build, so sanitize
each
- # value to its expected charset before handing it to the Codecov CLI.
- run: |
- echo "pr=$(cat cc/pr-number.txt 2>/dev/null | tr -cd '0-9')" >>
"$GITHUB_OUTPUT"
- echo "sha=$(cat cc/commit-sha.txt 2>/dev/null | tr -cd '0-9a-fA-F')"
>> "$GITHUB_OUTPUT"
- echo "branch=$(cat cc/branch.txt 2>/dev/null | tr -cd
'[:alnum:]._/:-')" >> "$GITHUB_OUTPUT"
- - name: Upload ${{ matrix.flag }} coverage to Codecov
- # fail_ci_if_error: true so a genuine upload failure fails this leg and
- # trips the notify-failure job below (Codecov posts its own comment
only on
- # success, so a failed coverage upload would otherwise leave the PR
with no
- # report and no signal). A label-gated-absent flag is not a failure —
the
- # download continue-on-errors and this step is skipped via the guards
above.
- if: steps.dl.outcome == 'success' && matrix.coverage &&
hashFiles('cc/coverage/**') != ''
- uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
- with:
- token: ${{ secrets.CODECOV_TOKEN }}
- directory: cc/coverage
- flags: ${{ matrix.flag }}
- fail_ci_if_error: true
- override_commit: ${{ steps.meta.outputs.sha }}
- override_branch: ${{ steps.meta.outputs.branch }}
- override_pr: ${{ steps.meta.outputs.pr }}
- - name: Upload ${{ matrix.flag }} test results to Codecov
- # fail_ci_if_error: true here too (per review) so a test-results
upload error
- # also trips notify-failure instead of being silently dropped. Still
guarded
- # on hashFiles, so an absent / label-gated flag simply skips.
- if: steps.dl.outcome == 'success' && hashFiles('cc/results/**') != ''
- uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
# v7.0.0
- with:
- token: ${{ secrets.CODECOV_TOKEN }}
- directory: cc/results
- flags: ${{ matrix.flag }}
- report_type: test_results
- fail_ci_if_error: true
- override_commit: ${{ steps.meta.outputs.sha }}
- override_branch: ${{ steps.meta.outputs.branch }}
- override_pr: ${{ steps.meta.outputs.pr }}
-
- notify-failure:
- # If any upload above failed (coverage or test-results), leave a comment
on the
- # PR so a human can re-dispatch it. Codecov posts its own comment on
SUCCESS, so
- # we only cover the failure case (per #6730 review). A delayed / queued
upload
- # posts nothing — the absence of a Codecov comment then signals a stuck
run.
- needs: upload
- if: ${{ failure() && github.event_name == 'workflow_run' }}
- runs-on: ubuntu-latest
- permissions:
- contents: read
- actions: read # download-artifact from the source run
- pull-requests: write # comment on the PR
- steps:
- - name: Download coverage metadata
- id: dl
- continue-on-error: true
- uses: actions/download-artifact@v4
- with:
- pattern: codecov-*
- path: cc-all
- merge-multiple: true # every flag's artifact carries the same
pr-number.txt
- run-id: ${{ github.event.workflow_run.id }}
- github-token: ${{ github.token }}
- - name: Resolve PR number
- id: meta
- shell: bash
- run: echo "pr=$(cat cc-all/pr-number.txt 2>/dev/null | tr -cd '0-9')"
>> "$GITHUB_OUTPUT"
- - name: Comment upload failure on the PR
- if: steps.meta.outputs.pr != ''
- uses: actions/github-script@v9
- with:
- github-token: ${{ github.token }}
- script: |
- const MARKER = '<!-- codecov-upload-failure -->';
- const pr = Number('${{ steps.meta.outputs.pr }}');
- const srcRunId = '${{ github.event.workflow_run.id }}';
- const runUrl =
`${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
- const body = [
- MARKER,
- '⚠️ **Codecov upload failed.**',
- '',
- `The deferred \`Codecov Upload\` workflow ([run](${runUrl}))
failed, so the coverage report for this PR may be missing. This does **not**
block merge.`,
- '',
- 'To recover: re-run the failed jobs in the run above, or
manually dispatch the **Codecov Upload** workflow with',
- `\`run_id\`: \`${srcRunId}\`.`,
- ].join('\n');
- const { owner, repo } = context.repo;
- const comments = await
github.paginate(github.rest.issues.listComments, {
- owner, repo, issue_number: pr, per_page: 100,
- });
- const prior = comments.find(c => c.body &&
c.body.includes(MARKER));
- if (prior) {
- await github.rest.issues.updateComment({ owner, repo,
comment_id: prior.id, body });
- } else {
- await github.rest.issues.createComment({ owner, repo,
issue_number: pr, body });
- }