From 677220c2fc84b9bc02304d713a88995ba7639567 Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Tue, 7 Jul 2026 21:30:13 +0200 Subject: [PATCH 1/3] docs(adr): Adopt Codecov for coverage reporting Add ADR-0012 (publish test coverage to Codecov): a live README badge and PR coverage feedback are not achievable with workflow artifacts alone, and the CI-committed badge alternative was rejected because CI must not push commits. Codecov statuses are configured informational so coverage never blocks a merge. ADR-0012 supersedes ADR-0011 and restates its surviving half (Checkstyle stays advisory). Update ADR-0011's status and the ADR index accordingly. --- ...t-ci-quality-checks-as-advisory-reports.md | 2 +- .../0012-publish-test-coverage-to-codecov.md | 72 +++++++++++++++++++ docs/adr/README.md | 3 +- 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 docs/adr/0012-publish-test-coverage-to-codecov.md diff --git a/docs/adr/0011-start-ci-quality-checks-as-advisory-reports.md b/docs/adr/0011-start-ci-quality-checks-as-advisory-reports.md index 8f73c69..5563d17 100644 --- a/docs/adr/0011-start-ci-quality-checks-as-advisory-reports.md +++ b/docs/adr/0011-start-ci-quality-checks-as-advisory-reports.md @@ -1,6 +1,6 @@ # Start CI quality checks as advisory reports -- Status: accepted +- Status: superseded by [ADR-0012](0012-publish-test-coverage-to-codecov.md) - Date: 2026-07-06 - Deciders: Eric Bouchut diff --git a/docs/adr/0012-publish-test-coverage-to-codecov.md b/docs/adr/0012-publish-test-coverage-to-codecov.md new file mode 100644 index 0000000..2ccf87a --- /dev/null +++ b/docs/adr/0012-publish-test-coverage-to-codecov.md @@ -0,0 +1,72 @@ +# Publish test coverage to Codecov + +- Status: accepted +- Date: 2026-07-07 +- Deciders: Eric Bouchut + +## Context and Problem Statement + +[ADR-0011](0011-start-ci-quality-checks-as-advisory-reports.md) kept +coverage local: a JaCoCo report uploaded as a workflow artifact, no +external service. Living with it showed the limits: there is no +stable link to the latest coverage (artifact URLs are per-run), no coverage +percentage badge is possible without CI committing a generated SVG back to +dev (tried and reverted: CI must not add commits), and PRs get no coverage +feedback. How do we get a live badge and PR-level coverage insight without +CI commits? + +## Decision Drivers + +- A live coverage badge in the README, without CI pushing commits +- Coverage feedback on every PR (project and patch coverage) +- Keep quality checks advisory: coverage must not block merges + (the spirit of [ADR-0011](0011-start-ci-quality-checks-as-advisory-reports.md)) +- Minimal setup and cost (free for public repositories) + +## Considered Options + +- Keep artifacts only (the status quo of + [ADR-0011](0011-start-ci-quality-checks-as-advisory-reports.md)) +- A badge SVG generated and committed by CI (rejected: CI commits on dev) +- Codecov (external coverage service) + +## Decision Outcome + +Chosen: "Codecov", because it provides the badge and PR feedback from the +JaCoCo XML that CI already produces, with one upload step and zero commits. +The advisory stance is preserved: `codecov.yml` sets the project and patch +statuses to informational, so Codecov never fails a check. + +This ADR supersedes [ADR-0011](0011-start-ci-quality-checks-as-advisory-reports.md). +The other half of ADR-0011 is unchanged and restated here: **Checkstyle +stays advisory** (report-only goal, `continue-on-error`, report artifact), +until the remaining warnings are fixed and the gate is switched on. + +### Consequences + +- Good: Live coverage badge in the README and a browsable dashboard + (https://app.codecov.io/gh/ebouchut/learn-dev). +- Good: Every PR gets a coverage comment (project delta and patch coverage). +- Trade-off: An external service and an account; uploads use a + `CODECOV_TOKEN` repository secret (public-repo uploads can run tokenless + but are rate-limited). +- Trade-off: The Tests workflow gains a third-party action + (codecov/codecov-action, pinned to a commit SHA). +- The JaCoCo artifact upload is kept as an offline fallback. + +## Pros and Cons of the Options + +### Keep artifacts only + +- 👍 No external dependency +- 👎 No badge, no stable latest-coverage link, no PR feedback + +### CI-committed badge SVG + +- 👍 No external service +- 👎 CI pushes commits to dev (rejected by the maintainer) + +### Codecov + +- 👍 Badge, dashboard, PR comments; free for public repos; one workflow step +- 👎 External service, account, and upload token to manage diff --git a/docs/adr/README.md b/docs/adr/README.md index ca5a3fb..d55bf09 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -41,4 +41,5 @@ NNNN-short-title-in-kebab-case.md | [0008](0008-share-singleton-testcontainers-postgres.md) | Share one Testcontainers PostgreSQL as a static singleton, not @Container | accepted | | [0009](0009-run-tests-under-surefire-not-failsafe.md) | Run all tests under Surefire with the *Test suffix, not Failsafe/*IT | accepted | | [0010](0010-structure-ci-as-focused-workflows-per-concern.md) | Structure CI as focused workflows per concern, not a monolithic ci.yml | accepted | -| [0011](0011-start-ci-quality-checks-as-advisory-reports.md) | Start CI quality checks as advisory reports, gates come later | accepted | \ No newline at end of file +| [0011](0011-start-ci-quality-checks-as-advisory-reports.md) | Start CI quality checks as advisory reports, gates come later | superseded by ADR-0012 | +| [0012](0012-publish-test-coverage-to-codecov.md) | Publish test coverage to Codecov | accepted | \ No newline at end of file From ea41a5a6adfea29c51c4dff70cbba77df57520ce Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Tue, 7 Jul 2026 21:31:35 +0200 Subject: [PATCH 2/3] ci(coverage): Upload the JaCoCo report to Codecov Add a Codecov upload step to the Tests workflow (codecov-action pinned to the commit SHA of v7.0.0) sending target/site/jacoco/jacoco.xml, and a root codecov.yml marking the project and patch statuses informational so coverage reports never block a merge (ADR-0012). Upload failures do not fail CI. The workflow-artifact upload stays as an offline fallback. The upload uses the CODECOV_TOKEN repository secret; until it is set, uploads from this public repository run tokenless (rate-limited). --- .github/workflows/test.yml | 9 +++++++++ codecov.yml | 12 ++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 codecov.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4273ccf..ff57bc5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,3 +32,12 @@ jobs: with: name: jacoco-coverage-report path: target/site/jacoco/ + # Publish coverage to Codecov (ADR-0012). Advisory: codecov.yml sets + # informational statuses, and an upload failure does not fail CI. + - name: Upload coverage to Codecov + # Third-party action, pinned to the commit SHA of v7.0.0 + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: target/site/jacoco/jacoco.xml + fail_ci_if_error: false diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..bfc7c2c --- /dev/null +++ b/codecov.yml @@ -0,0 +1,12 @@ +# Codecov configuration (see docs/adr/0012-publish-test-coverage-to-codecov.md). +# Coverage is advisory: both statuses are informational, so Codecov reports +# but never fails a check. Tighten later by removing "informational" and +# setting coverage targets. +coverage: + status: + project: + default: + informational: true + patch: + default: + informational: true From 8cd6a002381cbeb08b5e25183dc2853c10aca592 Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Tue, 7 Jul 2026 21:33:25 +0200 Subject: [PATCH 3/3] docs(coverage): Add the Codecov badge and links Add the Codecov coverage badge to the README badge block, linking to the dashboard, and rework the documentation entry to lead with Codecov while keeping the workflow-artifact and local-report paths. Document the Codecov flow in CONTRIBUTING (dashboard, PR comments, informational statuses), add Codecov entries to GLOSSARY.md and GLOSSAIRE.md (kept in sync), add a CI and code quality table to docs/tech-stacks.md (GitHub Actions, Checkstyle, JaCoCo, Codecov), and record the executed plan in docs/plans/2026-07-07-codecov-coverage.md. --- CONTRIBUTING.md | 6 ++++ GLOSSAIRE.md | 9 +++-- GLOSSARY.md | 7 +++- README.md | 12 +++++-- docs/plans/2026-07-07-codecov-coverage.md | 44 +++++++++++++++++++++++ docs/tech-stacks.md | 9 +++++ 6 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 docs/plans/2026-07-07-codecov-coverage.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 95e1512..ea5073a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -914,6 +914,12 @@ coverage is reported, not yet enforced as a threshold). uploads the report as the **`jacoco-coverage-report`** artifact. Open a run, scroll to its **Artifacts** section, download the archive, and open `index.html` inside it. +- **On Codecov**: CI also uploads the report to the + [Codecov dashboard](https://app.codecov.io/gh/ebouchut/learn-dev) + (see [ADR-0012](docs/adr/0012-publish-test-coverage-to-codecov.md)), + which powers the README coverage badge and comments on every PR with the + project and patch coverage. The Codecov statuses are **informational** + (configured in `codecov.yml`): they report, they never block a merge. ### Generating the Documentation diff --git a/GLOSSAIRE.md b/GLOSSAIRE.md index 00d7073..77745d2 100644 --- a/GLOSSAIRE.md +++ b/GLOSSAIRE.md @@ -107,8 +107,13 @@ pour la justification des décisions de conception, voir les [ADR](docs/adr/READ fourni (`google_checks.xml`) en mode rapport seul (voir [ADR-0011](docs/adr/0011-start-ci-quality-checks-as-advisory-reports.md)). - **Code coverage (couverture de code)** — Le pourcentage de code exercé par - la suite de tests. Mesuré ici par JaCoCo ; rapporté, sans seuil imposé pour - l'instant. + la suite de tests. Mesuré ici par JaCoCo et publié sur Codecov ; rapporté, + sans seuil imposé pour l'instant. +- **Codecov** — Un service hébergé qui reçoit les rapports de couverture + depuis la CI, fournit un tableau de bord et un badge pour le README, et + commente chaque PR avec la couverture du projet et du patch. Les statuts + sont informatifs ici (voir + [ADR-0012](docs/adr/0012-publish-test-coverage-to-codecov.md)). - **DTO (Data Transfer Object)** — Un objet qui transporte des données à travers une frontière, volontairement distinct des entités. Un DTO `...Form` porte un formulaire HTML. diff --git a/GLOSSARY.md b/GLOSSARY.md index 96d7fe2..10cb237 100644 --- a/GLOSSARY.md +++ b/GLOSSARY.md @@ -89,7 +89,12 @@ rationale behind design decisions, see the [ADRs](docs/adr/README.md). style ruleset. Runs here with the bundled Google ruleset (`google_checks.xml`) in report-only mode (see [ADR-0011](docs/adr/0011-start-ci-quality-checks-as-advisory-reports.md)). - **Code coverage** — The percentage of code exercised by the test suite. - Measured here by JaCoCo; reported, not yet enforced as a threshold. + Measured here by JaCoCo and published to Codecov; reported, not yet + enforced as a threshold. +- **Codecov** — A hosted service that ingests coverage reports from CI, + renders a dashboard and a README badge, and comments on PRs with the + project and patch coverage. Statuses are informational here (see + [ADR-0012](docs/adr/0012-publish-test-coverage-to-codecov.md)). - **DTO (Data Transfer Object)** — An object carrying data across a boundary, deliberately separate from entities. A `...Form` DTO backs an HTML form. - **Failsafe** — The Maven plugin that runs `*IT` integration tests in the `verify` diff --git a/README.md b/README.md index c90d64e..9fc9c1c 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![build status][build-image]][build-url] [![test status][test-image]][test-url] +[![code coverage][coverage-image]][coverage-url] [![lint status][lint-image]][lint-url] [![schema drift status][schema-drift-image]][schema-drift-url] [![github issues][github-issues-image]][github-issues-url] @@ -378,9 +379,12 @@ visit [this link](https://github.com/users/ebouchut/projects/7/views/3). - [GLOSSARY.md](GLOSSARY.md) — definitions of the domain and technical terms used across the project (🇫🇷 French version: [GLOSSAIRE.md](GLOSSAIRE.md)). - [Architecture Decision Records](docs/adr/README.md) — A list of design decisions and their trade-offs. -- [Test coverage reports (JaCoCo)](https://github.com/ebouchut/learn-dev/actions/workflows/test.yml) — - published as the `jacoco-coverage-report` artifact of each Tests workflow run; - locally, `make test` writes the same report to `target/site/jacoco/index.html` +- [Test coverage (Codecov)](https://app.codecov.io/gh/ebouchut/learn-dev) — + live coverage dashboard fed by CI + (see [ADR-0012](docs/adr/0012-publish-test-coverage-to-codecov.md)); + the raw JaCoCo report is also published as the `jacoco-coverage-report` + artifact of each [Tests workflow run](https://github.com/ebouchut/learn-dev/actions/workflows/test.yml), + and locally `make test` writes it to `target/site/jacoco/index.html` (see [CONTRIBUTING](CONTRIBUTING.md#test-coverage-report-jacoco) for details). @@ -450,6 +454,8 @@ See [LICENSE](LICENSE) for details. [build-url]: https://github.com/ebouchut/learn-dev/actions/workflows/build.yml [test-image]: https://github.com/ebouchut/learn-dev/actions/workflows/test.yml/badge.svg?branch=dev&event=push [test-url]: https://github.com/ebouchut/learn-dev/actions/workflows/test.yml +[coverage-image]: https://codecov.io/gh/ebouchut/learn-dev/branch/dev/graph/badge.svg +[coverage-url]: https://app.codecov.io/gh/ebouchut/learn-dev [lint-image]: https://github.com/ebouchut/learn-dev/actions/workflows/lint.yml/badge.svg?branch=dev&event=push [lint-url]: https://github.com/ebouchut/learn-dev/actions/workflows/lint.yml [schema-drift-image]: https://github.com/ebouchut/learn-dev/actions/workflows/schema-drift.yml/badge.svg?branch=dev&event=push diff --git a/docs/plans/2026-07-07-codecov-coverage.md b/docs/plans/2026-07-07-codecov-coverage.md new file mode 100644 index 0000000..da0c590 --- /dev/null +++ b/docs/plans/2026-07-07-codecov-coverage.md @@ -0,0 +1,44 @@ +# Codecov Coverage Reporting Implementation Plan + +> **Status: executed** on 2026-07-07, branch `docs-link-coverage-reports`. +> Retrospective record; the CI-side checks at the bottom complete after the +> PR runs and the Codecov account is wired. + +**Goal:** A live code coverage badge in the README and coverage feedback on +every PR, without CI pushing commits. A CI-committed badge SVG was tried and +reverted for that exact reason; Codecov replaces it (see +[ADR-0012](../adr/0012-publish-test-coverage-to-codecov.md), which +supersedes [ADR-0011](../adr/0011-start-ci-quality-checks-as-advisory-reports.md) +while keeping Checkstyle advisory). + +## Tasks + +- [x] [ADR-0012](../adr/0012-publish-test-coverage-to-codecov.md): decision + record; mark ADR-0011 superseded; update the ADR index + => commit `docs(adr): Adopt Codecov for coverage reporting` +- [x] Tests workflow: upload `target/site/jacoco/jacoco.xml` with + codecov-action (pinned to the commit SHA of v7.0.0), + `fail_ci_if_error: false`; add root `codecov.yml` with informational + project and patch statuses (coverage never blocks a merge) + => commit `ci(coverage): Upload the JaCoCo report to Codecov` +- [x] Docs: README badge (`codecov.io/gh/ebouchut/learn-dev/branch/dev`) + linking to the dashboard; README documentation entry; CONTRIBUTING + "On Codecov" bullet; Codecov entries in GLOSSARY.md and GLOSSAIRE.md + (kept in sync); CI and quality table in docs/tech-stacks.md + => commit `docs(coverage): Add the Codecov badge and links` + +## User prerequisites (manual) + +- [ ] Sign in at https://about.codecov.io/ with GitHub and activate the + `ebouchut/learn-dev` repository +- [ ] Store the repository upload token as the `CODECOV_TOKEN` Actions + secret (`gh secret set CODECOV_TOKEN`); until then, uploads from this + public repository run tokenless (rate-limited) + +## Verification + +- [x] `test.yml` and `codecov.yml` parse as valid YAML +- [x] README badge reference labels each appear exactly twice (use + definition) +- [ ] The PR's Tests run shows the "Upload coverage to Codecov" step green +- [ ] The PR receives a Codecov comment (project delta and patch coverage) +- [ ] The README badge renders a percentage once dev has its first upload diff --git a/docs/tech-stacks.md b/docs/tech-stacks.md index 207a993..3a93e82 100644 --- a/docs/tech-stacks.md +++ b/docs/tech-stacks.md @@ -75,6 +75,15 @@ definitions see [GLOSSARY.md](../GLOSSARY.md). All tests run under the Maven Surefire plugin (no Failsafe); see [ADR-0009](adr/0009-run-tests-under-surefire-not-failsafe.md). +## Continuous integration and code quality + +| Technology | Version | Why here | +|------------|---------|----------| +| GitHub Actions | — | CI: one focused workflow per concern (build, test, lint, schema drift). See [ADR-0010](adr/0010-structure-ci-as-focused-workflows-per-concern.md). | +| Checkstyle (maven-checkstyle-plugin) | 3.6.0 | Advisory linting against the project ruleset (`config/checkstyle/checkstyle.xml`). See [ADR-0011](adr/0011-start-ci-quality-checks-as-advisory-reports.md). | +| JaCoCo | 0.8.15 | Test coverage measurement; report produced by every `mvn test`. | +| Codecov | — | Hosts the coverage reports: README badge, dashboard, PR comments (informational statuses). See [ADR-0012](adr/0012-publish-test-coverage-to-codecov.md). | + ## Containers and local infrastructure | Technology | Version | Why here |