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 9b850e2ed8 ci: enable Codecov Test Analytics across all test jobs
(#5207)
9b850e2ed8 is described below
commit 9b850e2ed8927a28cf4842d8534d4cb3f0ab01b7
Author: Yicong Huang <[email protected]>
AuthorDate: Mon May 25 15:49:33 2026 -0700
ci: enable Codecov Test Analytics across all test jobs (#5207)
### What changes were proposed in this PR?
Enable Codecov Test Analytics for every stack we already upload coverage
from. Each stack now emits JUnit-XML alongside its existing coverage
report, and a second `codecov/codecov-action` step per job uploads it
with `report_type: test_results`.
- ScalaTest: `ThisBuild / Test / testOptions += -u target/test-reports`
in the root `build.sbt`.
- Vitest unit + browser configs: `reporters: ["default", ["junit", {
outputFile: ... }]]`.
- pytest (`python` job + `amber-integration` Python step):
`--junit-xml=...`.
- `bun test` (`agent-service`): `--reporter=junit
--reporter-outfile=junit.xml`.
Test Analytics ingestion is independent of coverage and shares the same
`CODECOV_TOKEN`. Once landed, Codecov will start posting failing-test
stack traces on PRs, flagging tests that have gone flaky on `main`, and
tracking per-test runtime / failure-rate over time.
### Any related issues, documentation, discussions?
Closes #5206.
### How was this PR tested?
Ran `sbt scalafmtCheckAll` and `prettier --check` on the two modified
`vitest.*.config.ts` files locally; both pass.
### Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Opus 4.7
---
.github/workflows/build.yml | 102 ++++++++++++++++++++++++++++++++++++--
build.sbt | 7 +++
frontend/vitest.browser.config.ts | 5 ++
frontend/vitest.config.ts | 5 ++
4 files changed, 116 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 8b0a5ea522..4fd056c7a7 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -133,10 +133,36 @@ jobs:
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@75cd11691c0faa626561e295848008c8a7dddffe
# v5.5.4
+ 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
+ - 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@75cd11691c0faa626561e295848008c8a7dddffe
# v5.5.4
+ with:
+ 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,
@@ -255,6 +281,20 @@ jobs:
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@75cd11691c0faa626561e295848008c8a7dddffe
# v5.5.4
+ 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 —
@@ -448,8 +488,21 @@ jobs:
"scalafixAll --check" \
"WorkflowExecutionService/test"
- name: Run Python integration tests
+ # --junit-xml feeds the Test Analytics upload below.
run: |
- cd amber && pytest -m integration -sv
+ cd amber && pytest -m integration --junit-xml=junit-integration.xml
-sv
+ - 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@75cd11691c0faa626561e295848008c8a7dddffe
# v5.5.4
+ with:
+ 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
@@ -545,6 +598,17 @@ jobs:
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@75cd11691c0faa626561e295848008c8a7dddffe
# v5.5.4
+ 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
python:
if: ${{ inputs.run_python }}
@@ -622,8 +686,11 @@ jobs:
python -m pip install uv
if [ -f amber/dev-requirements.txt ]; then uv pip install --system
-r amber/dev-requirements.txt; fi
- name: Test with pytest
+ # --junit-xml emits a JUnit-XML report alongside the coverage XML
+ # so the Test Analytics upload below can feed Codecov's failing-
+ # test PR comments and flaky-test detection on main.
run: |
- cd amber && pytest -m "not integration" --cov=src/main/python
--cov-report=xml -sv
+ cd amber && pytest -m "not integration" --cov=src/main/python
--cov-report=xml --junit-xml=junit.xml -sv
- name: Upload python coverage to Codecov
if: matrix.python-version == '3.12' && always()
uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe
# v5.5.4
@@ -632,6 +699,20 @@ jobs:
files: ./amber/coverage.xml
flags: python
fail_ci_if_error: false
+ - name: Upload python 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@75cd11691c0faa626561e295848008c8a7dddffe
# v5.5.4
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./amber/junit.xml
+ flags: python
+ report_type: test_results
+ disable_search: true
+ fail_ci_if_error: false
python-state-materialization-mac:
# Diagnostic leg: cross-region state materialization is reported to
@@ -713,7 +794,10 @@ jobs:
- name: Typecheck
run: bun run typecheck
- name: Run unit tests
- run: bun test --coverage --coverage-reporter=lcov
+ # --reporter=junit emits a JUnit-XML alongside coverage so the
+ # 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: Upload agent-service coverage to Codecov
if: matrix.os == 'ubuntu-latest' && always()
uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe
# v5.5.4
@@ -722,3 +806,15 @@ jobs:
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@75cd11691c0faa626561e295848008c8a7dddffe
# v5.5.4
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ files: ./agent-service/junit.xml
+ flags: agent-service
+ report_type: test_results
+ disable_search: true
+ fail_ci_if_error: false
diff --git a/build.sbt b/build.sbt
index b7b6b3cfb2..8268fc7a11 100644
--- a/build.sbt
+++ b/build.sbt
@@ -24,6 +24,13 @@ import
com.typesafe.sbt.packager.universal.UniversalPlugin.autoImport.Universal
ThisBuild / Test / javaOptions ++=
JdkOptions.jvmFlags((ThisBuild / baseDirectory).value)
+// Emit one JUnit-XML file per spec under each module's target/test-reports/.
+// Codecov Test Analytics ingests these via `report_type: test_results` to
+// surface failing-test stack traces in PR comments and flag tests that have
+// gone flaky on main. ScalaTest's `-u` argument is additive — module-level
+// testOptions (e.g. amber/build.sbt's filter args) continue to apply.
+ThisBuild / Test / testOptions += Tests.Argument(TestFrameworks.ScalaTest,
"-u", "target/test-reports")
+
// sbt-jacoco emits only HTML by default; add XML so Codecov can consume
// per-module jacoco.xml at target/scala-2.13/jacoco/report/jacoco.xml.
// JacocoPlugin defines a project-scoped default that overrides ThisBuild,
diff --git a/frontend/vitest.browser.config.ts
b/frontend/vitest.browser.config.ts
index b24f875a4f..eee0624ff1 100644
--- a/frontend/vitest.browser.config.ts
+++ b/frontend/vitest.browser.config.ts
@@ -42,6 +42,11 @@ export default defineConfig({
],
},
test: {
+ // Emit a JUnit-XML report alongside the default console reporter so
+ // Codecov Test Analytics can ingest browser-mode failures and detect
+ // flakies on main. Written to a distinct filename so the upload step
+ // can disambiguate it from the unit-test report.
+ reporters: ["default", ["junit", { outputFile: "junit-browser.xml" }]],
globals: true,
setupFiles: ["src/test-zone-setup.ts"],
browser: {
diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts
index 5462d42cf4..82a35b7afe 100644
--- a/frontend/vitest.config.ts
+++ b/frontend/vitest.config.ts
@@ -21,6 +21,11 @@ import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
+ // Emit a JUnit-XML report alongside the default console reporter so
+ // Codecov Test Analytics can ingest failing-test stack traces and
+ // detect flakies on main. `default` stays first so CI logs read the
+ // same as before.
+ reporters: ["default", ["junit", { outputFile: "junit.xml" }]],
// Make describe/it/expect/vi/beforeEach/etc available as globals so
// existing Jasmine-style specs don't need a per-file import sweep.
// Paired with `vitest/globals` triple-slash in src/vitest-globals.d.ts.