From 9430e674080bcc4c1631691313ff992c7242ef8a Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Tue, 7 Jul 2026 14:24:17 +0200 Subject: [PATCH 1/8] ci(build): Verify the Maven build on every PR and push Add a Build workflow that compiles the project with the Maven wrapper on pull requests targeting dev and on pushes to dev and main. Use actions/setup-java with Temurin 21 and the built-in Maven cache. Keep one focused workflow per CI concern instead of a monolithic ci.yml, as decided in issue #49 (wontfix). Fixes #45 --- .github/workflows/build.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f479f49 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,25 @@ +name: Build + +# Verify that the project compiles on every PR and push. +# One focused workflow per CI concern (build, test, lint) instead of a +# monolithic ci.yml (see issue #49, closed as wontfix). Test compilation +# and execution live in test.yml. + +on: + pull_request: + branches: [dev] + push: + branches: [dev, main] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "21" + cache: maven + - name: Compile the project + run: ./mvnw -B -ntp compile From 3650ab89bdcfb978053afa110a8e184f5b85633b Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Tue, 7 Jul 2026 14:24:47 +0200 Subject: [PATCH 2/8] ci(test): Run the test suite on every PR and push Add a Tests workflow that runs ./mvnw test on pull requests targeting dev and on pushes to dev and main. All test classes end in *Test and run under Surefire, per ADR-0009. Testcontainers starts a real PostgreSQL using the Docker daemon that ubuntu-latest runners provide, so no extra container setup is needed. No .env file is required either: @ServiceConnection wires the datasource to the container and the tests exclude the MongoDB autoconfiguration. Fixes #46 --- .github/workflows/test.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..4e98adb --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,26 @@ +name: Tests + +# Run the test suite (Surefire, all *Test classes) on every PR and push. +# Integration-style tests provision a real PostgreSQL via Testcontainers, +# which uses the Docker daemon built into ubuntu-latest runners. +# No .env file is needed: @ServiceConnection wires the datasource to the +# container and the tests exclude the MongoDB autoconfiguration. + +on: + pull_request: + branches: [dev] + push: + branches: [dev, main] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "21" + cache: maven + - name: Run the test suite + run: ./mvnw -B -ntp test From bde8cc5956e342a63c3f1ddaf63bf7ff2584a973 Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Tue, 7 Jul 2026 14:27:35 +0200 Subject: [PATCH 3/8] ci(lint): Add a non-blocking Checkstyle report Add Checkstyle (maven-checkstyle-plugin 3.6.0, bundled Google ruleset) as a report-only quality check: checkstyle:checkstyle prints violations on the console and writes target/checkstyle-result.xml, and failOnViolation/failsOnError are off, so the build never fails on violations. Add a Lint workflow that generates the report on pull requests targeting dev and on pushes to dev and main, and uploads it as a workflow artifact. The job uses continue-on-error so it never gates merges on day one for an existing codebase. Tighten later by switching to checkstyle:check with failOnViolation, or a project ruleset. Fixes #47 --- .github/workflows/lint.yml | 35 +++++++++++++++++++++++++++++++++++ pom.xml | 22 ++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 .github/workflows/lint.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..6805d49 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,35 @@ +name: Lint + +# Code quality check (Checkstyle, Google ruleset) on every PR and push. +# Deliberately non-blocking on day one for an existing codebase: +# - checkstyle:checkstyle only generates a report, it never fails on violations +# - continue-on-error keeps even setup errors from gating merges +# The report is uploaded as a workflow artifact for review. +# Tighten later: switch the goal to checkstyle:check and set +# failOnViolation to true in pom.xml, then drop continue-on-error. + +on: + pull_request: + branches: [dev] + push: + branches: [dev, main] + +jobs: + checkstyle: + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "21" + cache: maven + - name: Generate the Checkstyle report + run: ./mvnw -B -ntp checkstyle:checkstyle + - name: Upload the Checkstyle report + if: always() + uses: actions/upload-artifact@v4 + with: + name: checkstyle-report + path: target/checkstyle-result.xml diff --git a/pom.xml b/pom.xml index 74210db..8c45c55 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,7 @@ 21 5.1.0 + 3.6.0 @@ -198,6 +199,27 @@ + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven-checkstyle-plugin.version} + + google_checks.xml + true + false + false + + From 50f61d6f559ef2a479363e18690cf75862ae6d16 Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Tue, 7 Jul 2026 14:29:47 +0200 Subject: [PATCH 4/8] ci(coverage): Add JaCoCo and upload the coverage report Add jacoco-maven-plugin 0.8.15 with prepare-agent to instrument the Surefire forks and a report execution bound to the test phase, so every `mvn test` run writes the HTML and XML report to target/site/jacoco/. Upload that report as a workflow artifact in the Tests workflow. No external coverage service is used. Fixes #48 --- .github/workflows/test.yml | 8 ++++++++ pom.xml | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4e98adb..4f26764 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,3 +24,11 @@ jobs: cache: maven - name: Run the test suite run: ./mvnw -B -ntp test + # JaCoCo is bound to the test phase, so the run above already + # produced the coverage report (HTML and XML). + - name: Upload the coverage report + if: always() + uses: actions/upload-artifact@v4 + with: + name: jacoco-coverage-report + path: target/site/jacoco/ diff --git a/pom.xml b/pom.xml index 8c45c55..bc26698 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,7 @@ 21 5.1.0 3.6.0 + 0.8.15 @@ -220,6 +221,32 @@ false + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + prepare-agent + + prepare-agent + + + + report + test + + report + + + + From 8fa5fc93255cd533507e344ac73ed5b0ec1e65ec Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Tue, 7 Jul 2026 14:36:16 +0200 Subject: [PATCH 5/8] docs(ci): Record the CI decisions as ADRs and the executed plan Add ADR-0010 (structure CI as focused workflows per concern, recording why the monolithic ci.yml of issue #49 was rejected) and ADR-0011 (start CI quality checks as advisory reports: report-only Checkstyle and JaCoCo artifacts, gates come later), index both in docs/adr/README.md, and add the retrospective implementation plan docs/plans/2026-07-06-ci-test-pipeline.md covering issues #45 to #48 with the verification results. --- ...ure-ci-as-focused-workflows-per-concern.md | 57 +++++++++ ...t-ci-quality-checks-as-advisory-reports.md | 61 ++++++++++ docs/adr/README.md | 4 +- docs/plans/2026-07-06-ci-test-pipeline.md | 108 ++++++++++++++++++ 4 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 docs/adr/0010-structure-ci-as-focused-workflows-per-concern.md create mode 100644 docs/adr/0011-start-ci-quality-checks-as-advisory-reports.md create mode 100644 docs/plans/2026-07-06-ci-test-pipeline.md diff --git a/docs/adr/0010-structure-ci-as-focused-workflows-per-concern.md b/docs/adr/0010-structure-ci-as-focused-workflows-per-concern.md new file mode 100644 index 0000000..f2e6bb1 --- /dev/null +++ b/docs/adr/0010-structure-ci-as-focused-workflows-per-concern.md @@ -0,0 +1,57 @@ +# Structure CI as focused workflows per concern + +- Status: accepted +- Date: 2026-07-06 +- Deciders: Eric Bouchut + +## Context and Problem Statement + +The project needs continuous integration on GitHub Actions (issues #45 to #48): +build verification, test execution, linting, and coverage reporting. +Should all of this live in a single `ci.yml` workflow, or in separate workflow +files? Issue #49 (create a monolithic `ci.yml`) was closed as wontfix; this ADR +records the reasoning so the layout survives the issue tracker. + +## Decision Drivers + +- Readability of CI results on a PR (one status per concern vs one opaque status) +- Independent evolution (tighten linting without touching the test workflow) +- Consistency with the existing `schema-drift.yml` workflow +- Duplication cost (checkout and setup-java repeated per file) + +## Considered Options + +- A single monolithic `ci.yml` with multiple jobs +- One focused workflow file per concern (`build.yml`, `test.yml`, `lint.yml`) + +## Decision Outcome + +Chosen: "One focused workflow file per concern", because each PR check maps to +one small readable file, failures are identifiable at a glance from the check +name, and each workflow can change (or be made blocking) independently. +This matches the precedent set by `schema-drift.yml`. + +### Consequences + +- Good: PR checks read as Build / Tests / Lint / Schema drift; a red check + names its concern directly. +- Good: The advisory lint workflow (ADR-0011) can later become blocking + without touching build or test. +- Trade-off: The checkout + setup-java boilerplate is repeated in each file + (about 10 lines per workflow). +- Trade-off: Shared changes (bumping the Java version) must be applied in + several files. + +## Pros and Cons of the Options + +### Monolithic ci.yml + +- 👍 One file to maintain; shared setup written once +- 👎 One check status hides which concern failed; jobs still rerun setup each +- 👎 Any change risks the whole pipeline; advisory and blocking concerns are + entangled + +### One workflow per concern + +- 👍 Self-describing PR checks; independent lifecycles; matches `schema-drift.yml` +- 👎 Boilerplate repeated per file 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 new file mode 100644 index 0000000..8f73c69 --- /dev/null +++ b/docs/adr/0011-start-ci-quality-checks-as-advisory-reports.md @@ -0,0 +1,61 @@ +# Start CI quality checks as advisory reports + +- Status: accepted +- Date: 2026-07-06 +- Deciders: Eric Bouchut + +## Context and Problem Statement + +CI adds linting (#47) and coverage (#48) to a codebase that has never been +linted and has no coverage baseline. Should these checks block merges from +day one, and should coverage go to an external service? A blocking linter on +an unlinted codebase fails every PR until a large style-only cleanup lands, +which stalls feature work. + +## Decision Drivers + +- Do not block feature PRs on pre-existing style debt +- Zero new config files and no external service accounts (solo project, + certification deadline) +- Keep a clear path to tighten later + +## Considered Options + +- Blocking checks from day one (Checkstyle `check` goal, coverage threshold + via `jacoco:check`, Codecov) +- Advisory reports first: Checkstyle report-only with the bundled + `google_checks.xml`, JaCoCo report bound to the test phase, both published + as workflow artifacts, no external service + +## Decision Outcome + +Chosen: "Advisory reports first", because it makes quality visible immediately +without gating merges on historical debt, adds zero config files (bundled +Google ruleset, plugin versions pinned in `pom.xml`: Checkstyle 3.6.0, +JaCoCo 0.8.15), and keeps secrets and accounts out of scope. The lint job also +sets `continue-on-error: true` so even setup errors stay advisory. + +### Consequences + +- Good: Every PR publishes a Checkstyle XML report and a JaCoCo HTML/XML + report as workflow artifacts. +- Good: `mvn test` locally now produces `target/site/jacoco/` with no extra + flags. +- Trade-off: Nothing enforces quality yet; violations can accumulate until + the gate is switched on. +- Follow-up: To tighten, switch the lint job to `checkstyle:check` with + `failOnViolation=true`, drop `continue-on-error`, and add a `jacoco:check` + minimum threshold. + +## Pros and Cons of the Options + +### Blocking from day one + +- 👍 Debt cannot grow +- 👎 Every PR is red until a big-bang style cleanup; discourages small PRs +- 👎 Codecov adds an account, a token, and an external dependency + +### Advisory reports first + +- 👍 Immediate visibility, zero friction, easy to tighten incrementally +- 👎 Relies on discipline until the gate exists diff --git a/docs/adr/README.md b/docs/adr/README.md index 9346b53..ca5a3fb 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -39,4 +39,6 @@ NNNN-short-title-in-kebab-case.md | [0006](0006-test-against-real-postgres-testcontainers.md) | Test the persistence layer against a real PostgreSQL (Testcontainers), not H2 | accepted | | [0007](0007-use-postgresql-over-mysql.md) | Use PostgreSQL as the relational database, not MySQL | accepted | | [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 | \ No newline at end of file +| [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 diff --git a/docs/plans/2026-07-06-ci-test-pipeline.md b/docs/plans/2026-07-06-ci-test-pipeline.md new file mode 100644 index 0000000..c0a36c9 --- /dev/null +++ b/docs/plans/2026-07-06-ci-test-pipeline.md @@ -0,0 +1,108 @@ +# CI Test Pipeline Implementation Plan + +> **Status: executed** on 2026-07-06, branch `ci-test-pipeline`. +> This is the retrospective record of the plan as it was carried out. + +**Goal:** Give the project a GitHub Actions CI pipeline: verify the Maven +build (#45), run the test suite (#46), report code quality (#47), and publish +test coverage (#48) on every PR targeting `dev` and every push to `dev`/`main`. + +**Architecture:** One focused workflow file per concern instead of a +monolithic `ci.yml` (issue #49 was closed as wontfix; rationale recorded in +[ADR-0010](../adr/0010-structure-ci-as-focused-workflows-per-concern.md)). +Quality checks start as advisory reports, not gates +([ADR-0011](../adr/0011-start-ci-quality-checks-as-advisory-reports.md)). +All jobs run on `ubuntu-latest` with `actions/setup-java@v4` +(Temurin 21, `cache: maven`) and invoke the wrapper as `./mvnw -B -ntp`. + +**Key insight:** the tests need no `.env` on CI. Integration-style tests +extend `AbstractPostgresIT`, which provisions a real PostgreSQL 17 via +Testcontainers and wires the datasource with `@ServiceConnection` +(ADR-0006, ADR-0008); Mongo autoconfiguration is excluded in tests. The +Docker daemon built into GitHub's ubuntu runners is enough; the Podman +environment variables from the `Makefile` are local-only. + +--- + +## Version Control (GitButler) + +Same rules as every plan in this repository: the workspace is on +`gitbutler/workspace`, so all commits go through `but commit` (never +`git add`/`git commit`), and **nothing is pushed** by the agent; the user +reviews, pushes, and opens the PR targeting `dev`. + +--- + +## File Structure + +``` +.github/workflows/ +├── build.yml # Build: ./mvnw -B -ntp compile +├── test.yml # Tests: ./mvnw -B -ntp test + JaCoCo artifact upload +└── lint.yml # Lint: ./mvnw -B -ntp checkstyle:checkstyle (advisory) + +pom.xml # + maven-checkstyle-plugin 3.6.0 (report-only) + # + jacoco-maven-plugin 0.8.15 (prepare-agent, report@test) +``` + +--- + +## Task 1: Maven build verification (#45) + +- [x] Create `.github/workflows/build.yml`: checkout@v4, setup-java + (Temurin 21, Maven cache), `./mvnw -B -ntp compile` +- [x] Triggers: `pull_request: [dev]`, `push: [dev, main]` + (same as `schema-drift.yml`) +- [x] Commit `ci(build): Verify the Maven build on every PR and push` + (Fixes #45) => 9430e67 + +## Task 2: Test automation (#46) + +- [x] Create `.github/workflows/test.yml`: same setup, `./mvnw -B -ntp test` +- [x] Document in the workflow why no `.env` or Podman wiring is needed +- [x] Surefire only, all `*Test` classes; no Failsafe (ADR-0009) +- [x] Commit `ci(test): Run the test suite on every PR and push` + (Fixes #46) => 3650ab8 + +## Task 3: Code quality checks (#47) + +- [x] Add `maven-checkstyle-plugin` (pinned 3.6.0, not managed by the Boot + parent) to `pom.xml`: bundled `google_checks.xml`, `consoleOutput`, + `failOnViolation=false`, `failsOnError=false`, not bound to any phase + so `mvn test`/`mvn install` behavior is unchanged +- [x] Create `.github/workflows/lint.yml`: `checkstyle:checkstyle` + (report goal, never fails on violations), `continue-on-error: true` + on the job, upload `target/checkstyle-result.xml` as an artifact +- [x] Commit `ci(lint): Add a non-blocking Checkstyle report` + (Fixes #47) => bde8cc5 + +## Task 4: Test coverage reports (#48) + +- [x] Add `jacoco-maven-plugin` (pinned 0.8.15) to `pom.xml`: + `prepare-agent` execution plus `report` bound to the `test` phase, so + every `mvn test` produces `target/site/jacoco/` (HTML + XML) +- [x] Add an `actions/upload-artifact@v4` step (`if: always()`) to + `test.yml` publishing `target/site/jacoco/` +- [x] No external coverage service (no Codecov): artifacts only +- [x] Commit `ci(coverage): Add JaCoCo and upload the coverage report` + (Fixes #48) => 50f61d6 + +## Verification (performed) + +- [x] All three workflow files parse as valid YAML + (actionlint unavailable; parsed with a YAML library) +- [x] `make test` after the `pom.xml` changes: + `Tests run: 11, Failures: 0, Errors: 0, Skipped: 0` => BUILD SUCCESS +- [x] `target/site/jacoco/index.html` and `jacoco.xml` produced by the + test phase +- [x] `./mvnw -B -ntp checkstyle:checkstyle` => BUILD SUCCESS, + violations reported as warnings only +- [x] `but status`: exactly 4 commits on `ci-test-pipeline`, no unrelated + changes swept in + +## Deferred (deliberate) + +- Coverage threshold gate (`jacoco:check`): add when a baseline exists +- Blocking Checkstyle (`checkstyle:check`, `failOnViolation=true`, drop + `continue-on-error`): switch on once the existing violations are triaged +- Path filters on the workflows: build and tests should always run for now From e5f50a15a0f1abb84ede1fb2809eb6537b4997eb Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Tue, 7 Jul 2026 14:45:58 +0200 Subject: [PATCH 6/8] docs(glossary): Define the CI pipeline terms Add the terms introduced by the CI work to GLOSSARY.md: Checkstyle, code coverage, JaCoCo, linter, Maven Wrapper, advisory check, CI, GitHub Actions, runner, Temurin, workflow, and workflow artifact, with links to ADR-0010 and ADR-0011. --- GLOSSARY.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/GLOSSARY.md b/GLOSSARY.md index 6ed219e..ce7e41f 100644 --- a/GLOSSARY.md +++ b/GLOSSARY.md @@ -80,6 +80,11 @@ rationale behind design decisions, see the [ADRs](docs/adr/README.md). capturing one design decision and its trade-offs, in MADR format. - **Bean Validation** — The Jakarta standard for declaring constraints (`@NotBlank`, `@Email`, `@Size`) on form/DTO fields, enforced with `@Valid`. +- **Checkstyle** — A static-analysis tool that checks Java source against a + 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. - **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` @@ -89,9 +94,17 @@ rationale behind design decisions, see the [ADRs](docs/adr/README.md). - **HikariCP** — The JDBC connection pool bundled with Spring Boot. - **Integration test** — A test that boots a Spring context and exercises multiple layers together (here `@SpringBootTest` against a real Postgres container). +- **JaCoCo (Java Code Coverage)** — The code-coverage tool for Java. Its Maven + plugin instruments the tests (`prepare-agent`) and writes an HTML/XML report to + `target/site/jacoco/` during the `test` phase; CI uploads it as a workflow artifact. +- **Linter** — A tool that flags style and quality issues in source code without + running it (static analysis). The project's linter is Checkstyle. - **Lombok** — A library that generates boilerplate (getters, constructors) from annotations at compile time. - **MADR (Markdown ADR)** — The lightweight ADR template format used in `docs/adr/`. +- **Maven Wrapper (`mvnw`)** — A committed launcher script that downloads and runs + the project's pinned Maven version, so builds do not depend on a locally + installed Maven (used by CI: `./mvnw -B -ntp ...`). - **Slice test** — A test that loads only one layer of the context (for example `@DataJpaTest` for the persistence layer). - **Smoke test** — A minimal test that the application context starts at all @@ -107,15 +120,33 @@ rationale behind design decisions, see the [ADRs](docs/adr/README.md). ## Infrastructure and process +- **Advisory check** — A CI check that reports problems without blocking the + merge (report-only goal and/or `continue-on-error`). Linting and coverage + start advisory here (see [ADR-0011](docs/adr/0011-start-ci-quality-checks-as-advisory-reports.md)). +- **CI (Continuous Integration)** — Automatically building and testing every + change (each PR and push) to catch regressions early. Implemented with + GitHub Actions (issues #45 to #48). - **Docker Compose** — Declarative multi-container orchestration; here it runs Postgres and Mongo. `docker` on the dev machine is Podman. - **GitButler** — The version-control tool wrapping Git; used via the `but` CLI when the current branch is `gitbutler/workspace`. +- **GitHub Actions** — GitHub's CI service. Each workflow is a YAML file under + `.github/workflows/`; this project uses one focused workflow per concern + (see [ADR-0010](docs/adr/0010-structure-ci-as-focused-workflows-per-concern.md)). - **Podman** — A daemonless container engine, used as the `docker` drop-in. +- **Runner** — The machine that executes a GitHub Actions job (`ubuntu-latest` + here); it ships with a Docker daemon, which Testcontainers uses directly. - **Spring profile** — A named configuration set (for example `dev`) selecting profile-specific properties and Liquibase contexts. +- **Temurin** — The Eclipse Adoptium distribution of the OpenJDK; the Java 21 + build used locally (via SDKMAN) and on CI (via `actions/setup-java`). - **Thymeleaf** — The server-side HTML template engine. Its Spring Security **dialect** (`sec:` namespace) exposes the authenticated user to templates. +- **Workflow (GitHub Actions)** — A YAML file declaring when (triggers) and how + (jobs, steps) CI runs. This project has `build.yml`, `test.yml`, `lint.yml`, + and `schema-drift.yml`. +- **Workflow artifact** — A file or folder uploaded from a workflow run and + downloadable from the run page (here: the Checkstyle XML and JaCoCo reports). ## Certification From f3643de39d333ec33414c6327b51568f3fec2823 Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Tue, 7 Jul 2026 14:46:06 +0200 Subject: [PATCH 7/8] docs(glossary): Add the French translation GLOSSAIRE.md Add GLOSSAIRE.md, the French counterpart of GLOSSARY.md, covering every entry. Cross-link the two files with a note stating they must be kept in sync, and reference the French version from the README documentation list. --- GLOSSAIRE.md | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++ GLOSSARY.md | 5 ++ README.md | 3 +- 3 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 GLOSSAIRE.md diff --git a/GLOSSAIRE.md b/GLOSSAIRE.md new file mode 100644 index 0000000..00d7073 --- /dev/null +++ b/GLOSSAIRE.md @@ -0,0 +1,202 @@ +# Glossaire + +Définitions des termes métier et techniques utilisés dans le projet learn-dev. +Pour les outils concrets et leurs versions, voir [docs/tech-stacks.md](docs/tech-stacks.md) ; +pour l'articulation des composants, voir [ARCHITECTURE.md](ARCHITECTURE.md) ; +pour la justification des décisions de conception, voir les [ADR](docs/adr/README.md). + +> [!NOTE] +> 🇬🇧 English version: [GLOSSARY.md](GLOSSARY.md). +> Les deux fichiers sont la traduction l'un de l'autre : toute entrée ajoutée, +> modifiée ou supprimée dans l'un doit l'être aussi dans l'autre. + +## Termes métier + +- **Archive (archiver)** — Dépublier un cours ou une leçon pour qu'il ne soit + plus accessible aux étudiants, sans le supprimer. +- **Course (cours)** — Une unité de contenu pédagogique appartenant à un + formateur ; contient des leçons. +- **Deactivate (désactiver)** — Neutraliser un compte (formateur ou étudiant, + par exemple) pour qu'il ne puisse plus être utilisé, sans le supprimer. + Voir aussi *compte désactivé*. +- **Drop a course (abandonner un cours)** — Le retrait d'un étudiant d'un cours + avant de l'avoir terminé. +- **Enrollment (inscription)** — La relation qui lie un étudiant à un cours + qu'il a rejoint. +- **Lesson (leçon)** — Un élément de contenu individuel au sein d'un cours. +- **Role (rôle)** — Un ensemble nommé de permissions accordées à un + utilisateur. Les rôles fournis par défaut sont `STUDENT`, `INSTRUCTOR` et + `ADMIN` ; `SUPERADMIN` est prévu (voir l'issue #65). + +## Authentification et sécurité + +- **Authority (autorité)** — Dans Spring Security, une permission unitaire + détenue par un utilisateur authentifié. Les rôles sont représentés comme des + autorités préfixées par `ROLE_` (le rôle `ADMIN` devient l'autorité + `ROLE_ADMIN`). +- **BCrypt** — Une fonction de hachage de mots de passe adaptative. Les mots de + passe sont stockés sous forme de hachés BCrypt, jamais en clair. +- **CSRF (Cross-Site Request Forgery)** — Une attaque qui pousse le navigateur + d'un utilisateur connecté à soumettre une requête à son insu. Contrée par un + jeton par formulaire (injecté par Thymeleaf) et l'attribut de cookie + `SameSite`. +- **Compte désactivé (disabled account)** — Un compte qui existe mais n'est pas + autorisé à s'authentifier (issu du drapeau `is_active = false`). À distinguer + d'un *compte verrouillé*. +- **HttpOnly** — Un attribut de cookie qui masque le cookie au JavaScript côté + client, ce qui limite le vol de session via XSS. +- **IDOR (Insecure Direct Object Reference)** — Une faille de contrôle d'accès + où un identifiant fourni par le client est utilisé sans vérification + d'autorisation. Les clés primaires UUID des utilisateurs limitent + l'énumération (voir [ADR-0003](docs/adr/0003-uuid-pk-for-users-bigint-elsewhere.md)). +- **Compte verrouillé (locked account)** — Un compte temporairement empêché de + s'authentifier (par exemple après trop d'échecs de connexion), issu du + drapeau `is_locked`. À distinguer d'un *compte désactivé*. +- **Principal** — L'entité actuellement authentifiée (en général l'utilisateur) + dans un contexte de sécurité. +- **SameSite** — Un attribut de cookie qui contrôle l'envoi du cookie par le + navigateur sur les requêtes inter-sites. Positionné sur `Lax` ici comme + défense en profondeur contre le CSRF. +- **Secure (cookie)** — Un attribut de cookie qui restreint le cookie au HTTPS. + Activé seulement lorsque l'application sera servie en TLS. +- **Session (côté serveur)** — L'état d'authentification conservé sur le + serveur et référencé par un cookie de session (`JSESSIONID`), plutôt qu'un + jeton autoporteur (voir [ADR-0001](docs/adr/0001-use-server-side-sessions-over-jwt.md)). +- **XSS (Cross-Site Scripting)** — L'injection de scripts malveillants dans des + pages vues par d'autres utilisateurs. Limitée par l'échappement automatique + de Thymeleaf et par `HttpOnly`. + +## Persistance et modélisation des données + +- **Changelog / Changeset (Liquibase)** — Un changelog est la liste ordonnée + des migrations ; un changeset est une migration atomique, identifiée par + `path::id::author`. +- **ERD (Entity-Relationship Diagram)** — Un diagramme des entités et de leurs + relations (produit ici avec Mermaid). +- **Hibernate** — L'implémentation JPA (ORM) utilisée pour faire correspondre + les entités Java aux tables. +- **JPA (Jakarta Persistence API)** — L'API Java standard du mapping + objet-relationnel ; implémentée par Hibernate. +- **JSESSIONID** — Le nom par défaut du cookie de session servlet. +- **Liquibase** — L'outil de migration du schéma de base de données. Les + migrations sont des fichiers SQL formatés écrits à la main et appliqués au + démarrage (voir [ADR-0005](docs/adr/0005-handwrite-liquibase-migrations-over-mcd-ddl.md)). +- **Merise** — Une méthode française de modélisation des données produisant + trois vues : MCD, MLD, MPD. +- **MCD (Modèle Conceptuel de Données)** — Le modèle conceptuel ; les entités + et relations, indépendamment de toute base de données. +- **MLD (Modèle Logique des Données)** — Le modèle logique ; le schéma + relationnel (tables, clés) dérivé du MCD. +- **MPD (Modèle Physique des Données)** — Le modèle physique ; le schéma + concret tel qu'implémenté dans PostgreSQL. +- **ORM (Object-Relational Mapping)** — La correspondance entre objets Java et + tables relationnelles ; assurée par Hibernate/JPA. +- **UUID** — Un identifiant sur 128 bits utilisé comme clé primaire des + utilisateurs pour éviter l'énumération d'identifiants séquentiels. + +## Build, tests et outillage + +- **ADR (Architecture Decision Record)** — Un document court, numéroté et en + ajout seul qui capture une décision de conception et ses compromis, au + format MADR. +- **Bean Validation** — Le standard Jakarta de déclaration de contraintes + (`@NotBlank`, `@Email`, `@Size`) sur les champs de formulaires/DTO, + appliquées avec `@Valid`. +- **Checkstyle** — Un outil d'analyse statique qui vérifie les sources Java + contre un référentiel de style. Exécuté ici avec le référentiel Google + 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. +- **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. +- **Failsafe** — Le plugin Maven qui exécute les tests d'intégration `*IT` + dans la phase `verify`. Ce projet ne l'utilise **pas** (voir + [ADR-0009](docs/adr/0009-run-tests-under-surefire-not-failsafe.md)). +- **FIFO (tube nommé)** — Un fichier spécial qui transmet les données à la + lecture. Le `.env` du projet est une FIFO remplie par 1Password ; le + `source` du shell ne peut pas la lire (taille nulle au `stat`). +- **HikariCP** — Le pool de connexions JDBC fourni avec Spring Boot. +- **Test d'intégration (integration test)** — Un test qui démarre un contexte + Spring et exerce plusieurs couches ensemble (ici `@SpringBootTest` contre un + vrai conteneur Postgres). +- **JaCoCo (Java Code Coverage)** — L'outil de couverture de code pour Java. + Son plugin Maven instrumente les tests (`prepare-agent`) et écrit un rapport + HTML/XML dans `target/site/jacoco/` pendant la phase `test` ; la CI le + publie comme artefact de workflow. +- **Linter** — Un outil qui signale les problèmes de style et de qualité dans + le code source sans l'exécuter (analyse statique). Le linter du projet est + Checkstyle. +- **Lombok** — Une bibliothèque qui génère le code répétitif (accesseurs, + constructeurs) à partir d'annotations, à la compilation. +- **MADR (Markdown ADR)** — Le format léger de modèle d'ADR utilisé dans + `docs/adr/`. +- **Maven Wrapper (`mvnw`)** — Un script de lancement versionné qui télécharge + et exécute la version de Maven épinglée par le projet, pour que les builds + ne dépendent pas d'un Maven installé localement (utilisé par la CI : + `./mvnw -B -ntp ...`). +- **Slice test (test de tranche)** — Un test qui ne charge qu'une couche du + contexte (par exemple `@DataJpaTest` pour la couche de persistance). +- **Smoke test (test de fumée)** — Un test minimal vérifiant que le contexte + de l'application démarre (`LearnDevApplicationTests`). +- **Surefire** — Le plugin Maven qui exécute les tests `*Test`/`*Tests` + (unitaires et d'intégration) dans la phase `test`. Tous les tests du projet + passent par Surefire. +- **Testcontainers** — Une bibliothèque qui démarre des conteneurs + Docker/Podman jetables pour les tests ; utilisée pour exécuter un vrai + PostgreSQL (voir [ADR-0006](docs/adr/0006-test-against-real-postgres-testcontainers.md)). +- **Ryuk** — Le conteneur compagnon de Testcontainers qui nettoie les + ressources ; désactivé sous Podman dans ce projet. +- **YAGNI (You Aren't Gonna Need It)** — Le principe de ne pas construire une + fonctionnalité avant d'en avoir réellement besoin (par exemple le report du + rôle `SUPERADMIN`). + +## Infrastructure et processus + +- **Advisory check (contrôle consultatif)** — Un contrôle de CI qui signale + les problèmes sans bloquer la fusion (goal en rapport seul et/ou + `continue-on-error`). Le lint et la couverture démarrent en mode consultatif + ici (voir [ADR-0011](docs/adr/0011-start-ci-quality-checks-as-advisory-reports.md)). +- **CI (intégration continue)** — Construire et tester automatiquement chaque + changement (chaque PR et chaque push) pour détecter les régressions au plus + tôt. Mise en oeuvre avec GitHub Actions (issues #45 à #48). +- **Docker Compose** — L'orchestration déclarative de plusieurs conteneurs ; + fait tourner ici Postgres et Mongo. Sur la machine de développement, + `docker` est Podman. +- **GitButler** — L'outil de gestion de versions qui enveloppe Git ; utilisé + via la CLI `but` quand la branche courante est `gitbutler/workspace`. +- **GitHub Actions** — Le service de CI de GitHub. Chaque workflow est un + fichier YAML sous `.github/workflows/` ; ce projet utilise un workflow ciblé + par préoccupation (voir [ADR-0010](docs/adr/0010-structure-ci-as-focused-workflows-per-concern.md)). +- **Podman** — Un moteur de conteneurs sans démon, utilisé comme remplaçant de + `docker`. +- **Runner (exécuteur)** — La machine qui exécute un job GitHub Actions + (`ubuntu-latest` ici) ; elle embarque un démon Docker, que Testcontainers + utilise directement. +- **Profil Spring (Spring profile)** — Un jeu de configuration nommé (par + exemple `dev`) qui sélectionne des propriétés spécifiques et des contextes + Liquibase. +- **Temurin** — La distribution Eclipse Adoptium de l'OpenJDK ; le build + Java 21 utilisé en local (via SDKMAN) et sur la CI (via + `actions/setup-java`). +- **Thymeleaf** — Le moteur de templates HTML côté serveur. Son **dialecte** + Spring Security (espace de noms `sec:`) expose l'utilisateur authentifié aux + templates. +- **Workflow (GitHub Actions)** — Un fichier YAML qui déclare quand + (déclencheurs) et comment (jobs, étapes) la CI s'exécute. Ce projet contient + `build.yml`, `test.yml`, `lint.yml` et `schema-drift.yml`. +- **Workflow artifact (artefact de workflow)** — Un fichier ou dossier publié + depuis une exécution de workflow et téléchargeable depuis la page de + l'exécution (ici : le rapport XML de Checkstyle et les rapports JaCoCo). + +## Certification + +- **CCP (Certificat de Compétences Professionnelles)** — Un bloc de + compétences d'un Titre Professionnel français ; le DWWM comprend un CCP + front-end et un CCP back-end. +- **DWWM (Développeur Web et Web Mobile)** — Le Titre Professionnel français + visé par ce projet de fin de formation. +- **REAC (Référentiel Emploi Activités Compétences)** — Le référentiel + officiel de compétences qui définit ce que la certification évalue. diff --git a/GLOSSARY.md b/GLOSSARY.md index ce7e41f..96d7fe2 100644 --- a/GLOSSARY.md +++ b/GLOSSARY.md @@ -5,6 +5,11 @@ project. For the concrete tools and versions, see [docs/tech-stacks.md](docs/tec for how the pieces fit together, see [ARCHITECTURE.md](ARCHITECTURE.md); for the rationale behind design decisions, see the [ADRs](docs/adr/README.md). +> [!NOTE] +> 🇫🇷 French version: [GLOSSAIRE.md](GLOSSAIRE.md). +> The two files are translations of each other: when you add, change, or +> remove an entry in one, apply the same change to the other. + ## Domain terms - **Archive** — Unpublish a course or lesson so it is no longer available to diff --git a/README.md b/README.md index 512e996..f7c1f88 100644 --- a/README.md +++ b/README.md @@ -367,7 +367,8 @@ visit [this link](https://github.com/users/ebouchut/projects/7/views/3). - [ARCHITECTURE.md](ARCHITECTURE.md) — how the pieces fit together (layers, request flow, authentication, data, testing). - [docs/tech-stacks.md](docs/tech-stacks.md) — catalogue of tools, languages, and frameworks with versions used in the project. -- [GLOSSARY.md](GLOSSARY.md) — definitions of the domain and technical terms used across the project. +- [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. From 67a04ba076b3e60c2e638e57cf7a577cd8dbe778 Mon Sep 17 00:00:00 2001 From: Eric Bouchut Date: Tue, 7 Jul 2026 15:17:46 +0200 Subject: [PATCH 8/8] docs(readme): Add CI status badges Add a badge block above the README title showing the status of the Build, Tests, Lint, and Schema drift workflows on dev, plus the open issue count, using reference-style links defined at the bottom of the file (same layout as the bet-no-loss project README). The Build, Tests, and Lint badges display a status once this branch merges into dev and the first push-triggered runs complete. --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index f7c1f88..4991878 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ + + +[![build status][build-image]][build-url] +[![test status][test-image]][test-url] +[![lint status][lint-image]][lint-url] +[![schema drift status][schema-drift-image]][schema-drift-url] +[![github issues][github-issues-image]][github-issues-url] + # Learn-dev: An Interactive Programming Learning Platform ## Presentation @@ -431,3 +439,16 @@ See [LICENSE](LICENSE) for details. - [Aubry Capitone](https://www.linkedin.com/in/a-capitone/) - [Esteban Bare](https://www.linkedin.com/in/esteban-bare-337927284/), - [REAC Developpeur Web et Web mobile](https://www.francecompetences.fr/recherche/rncp/37674/) + + + +[build-image]: https://github.com/ebouchut/learn-dev/actions/workflows/build.yml/badge.svg?branch=dev&event=push +[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 +[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 +[schema-drift-url]: https://github.com/ebouchut/learn-dev/actions/workflows/schema-drift.yml +[github-issues-image]: https://img.shields.io/github/issues/ebouchut/learn-dev +[github-issues-url]: https://github.com/ebouchut/learn-dev/issues