Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 32 additions & 9 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
name: Lint

# Code quality check (Checkstyle, project ruleset) on every PR and push.
# Code quality check (Checkstyle, project ruleset) and API reference (Javadoc)
# 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, and on pushes
# to dev it is also published to GitHub Pages (rendered HTML, no download):
# Both reports are uploaded as workflow artifacts for review, and on pushes
# to dev they are also published to GitHub Pages (rendered HTML, no download):
# the official upload-pages-artifact + deploy-pages flow creates no commits.
# The Javadoc rides along in this workflow on purpose: GitHub Pages serves a
# single site artifact, so a second workflow deploying Pages would clobber the
# Checkstyle report. Each report lives under its own path (/checkstyle/,
# /javadoc/), so new reports can join without breaking existing URLs.
# Tighten later: switch the goal to checkstyle:check and set
# failOnViolation to true in pom.xml, then drop continue-on-error.

Expand Down Expand Up @@ -38,25 +43,43 @@ jobs:
name: checkstyle-report
path: |
target/reports/
!target/reports/apidocs/
target/checkstyle-result.xml
# On pushes to dev, publish the HTML report online via GitHub Pages.
# The site is namespaced under /checkstyle/ so future reports can
# join under their own paths without breaking URLs.
# The API reference, rendered from the Javadoc comments. Never blocking:
# the job already runs with continue-on-error.
- name: Generate the Javadoc
run: ./mvnw -B -ntp javadoc:javadoc
- name: Upload the Javadoc
if: always()
uses: actions/upload-artifact@v7
with:
name: javadoc
path: target/reports/apidocs/
# On pushes to dev, publish both HTML reports online via GitHub Pages.
# Each one gets its own path so they can be linked (and joined by
# future reports) without breaking URLs.
- name: Assemble the Pages site
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
run: |
mkdir -p _site/checkstyle
mkdir -p _site/checkstyle _site/javadoc
cp -R target/reports/apidocs/. _site/javadoc/
# Everything in target/reports/ except the Javadoc is Checkstyle's
# (checkstyle.html plus its css/fonts/images assets).
rm -rf target/reports/apidocs
cp -R target/reports/. _site/checkstyle/
cat > _site/index.html <<'HTML'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="0; url=checkstyle/checkstyle.html">
<title>learn-dev reports</title>
</head>
<body>
<p><a href="checkstyle/checkstyle.html">Checkstyle report</a></p>
<h1>learn-dev reports</h1>
<ul>
<li><a href="javadoc/index.html">API reference (Javadoc)</a></li>
<li><a href="checkstyle/checkstyle.html">Checkstyle report</a></li>
</ul>
</body>
</html>
HTML
Expand Down
99 changes: 97 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ Read the [Prerequisites section of the README](README.md#prerequisites).

#### Code Documentation

The code reference documentation is not yet available and will be added to this repository in a future update.
The code reference (Javadoc) is
[published on GitHub Pages](https://www.ericbouchut.com/learn-dev/javadoc/index.html),
rebuilt from `dev` on every merge. To read the reference for the branch you
are working on, build it locally with `make javadoc` and open
`target/reports/apidocs/index.html` (see
[Generating the Documentation](#generating-the-documentation)).

#### Architecture Decision Records (ADR)

Expand Down Expand Up @@ -1205,7 +1210,97 @@ coverage is reported, not yet enforced as a threshold).

### Generating the Documentation

TODO: Explain how to generate the documentation
Most of the documentation is **hand-written** and lives in the repository as
Markdown: [README](README.md), [ARCHITECTURE](ARCHITECTURE.md), the
[ADRs](docs/adr/README.md), the [glossaries](GLOSSARY.md), the
[accessibility docs](docs/rgaa.md), and the plans and design notes under
[docs/](docs/). Those you simply edit.

The rest is **generated** from the code or from the database. This section is
about those:

| Documentation | Generate with | Output |
|---|---|---|
| API reference (Javadoc) | `make javadoc` | `target/reports/apidocs/index.html` |
| Database diagrams (MCD, MLD, MPD) | `make diagrams` | `docs/database/merise/` |
| Code quality report (Checkstyle) | `./mvnw -B checkstyle:checkstyle` | `target/reports/checkstyle.html` |
| Test coverage report (JaCoCo) | `make test` | `target/site/jacoco/index.html` |

The Checkstyle and JaCoCo reports have their own sections above
([Checkstyle Report](#checkstyle-report),
[Test Coverage Report (JaCoCo)](#test-coverage-report-jacoco)).
The two below do not.

#### API Reference (Javadoc)

The API reference is the Java documentation rendered from the `/** */`
comments in `src/main/java`. It holds one page per `public` or `protected`
type of `com.ericbouchut.learndev` (classes, interfaces, enums, records) with
its methods, their parameters and return values, plus package summaries, the
class hierarchy, and a searchable index.

- **Locally**: generate it, then open it:
```bash
make javadoc
open target/reports/apidocs/index.html # macOS
```
This runs `./mvnw javadoc:javadoc`. The plugin is bound to no build phase,
so an ordinary `make test` or `./mvnw package` never pays the cost of
building it.
- **Online**: the reference built from `dev` is
[published on GitHub Pages](https://www.ericbouchut.com/learn-dev/javadoc/index.html)
(republished by the Lint workflow on each merge to `dev`, without any commit).
- **On CI**: every [Lint workflow run](https://github.com/ebouchut/learn-dev/actions/workflows/lint.yml)
uploads it as the **`javadoc`** artifact.
Open a run, scroll to its **Artifacts** section, download the archive,
and open `index.html` inside it.

Two things are worth knowing when reading the output:

- **The Lombok accessors are absent.** Javadoc reads the *source*, and the
getters and setters of the entities are generated at compile time by Lombok
(`@Getter`/`@Setter`), so they never reach it. The fields they expose are
documented; the accessors are not.
- **Javadoc does not police missing documentation.** It runs with
`doclint=all,-missing`: it fails on a malformed comment, broken HTML, or a
dangling `{@link}`, but says nothing about an absent `@param` or `@return`.
Reporting *missing* Javadoc is Checkstyle's job (`MissingJavadocType`,
`MissingJavadocMethod`), and per
[ADR-0011](docs/adr/0011-start-ci-quality-checks-as-advisory-reports.md)
it reports rather than blocks.

#### Database Diagrams (Merise)

The three Merise models are generated: the **MCD** and the **MLD** from the
Mocodo source `docs/database/merise/learn-dev.mcd`, and the **MPD** from the
**live database** with [tbls](https://github.com/k1LoW/tbls). What they write
under `docs/database/merise/` is committed to the repository but remains a
build artifact: **edit the `.mcd` source, never the generated `.svg`/`.md`.**

Prerequisites (see the
[Python Setup section of the README](README.md#python-setup)): a Python
virtual environment with `mocodo >= 4.3.3`, and `tbls` on the `PATH`. The MPD
additionally needs the database **running** (`docker compose up -d`), because
tbls reads the real schema; its connection string is built from `.env`.

```bash
make mcd # MCD → learn-dev.svg
make mld # MLD → learn-dev_mld.svg
make mpd # MPD → mpd/ (one page per table, read from the live database)
make diagrams # all three
make clean # remove the generated MCD/MLD files
```

After a schema change, regenerate the diagrams and check that the model and
the migrations still agree:

```bash
make check-schema-drift # fails if a Liquibase column is missing from the MCD
```

CI runs that same check on every change to a migration or to the MCD
([Schema drift workflow](https://github.com/ebouchut/learn-dev/actions/workflows/schema-drift.yml)),
so a diagram that has drifted from the schema blocks the merge.


### Running the CI Locally
Expand Down
11 changes: 10 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Ignore existing files with the same name as phony targets
.PHONY: help diagrams mcd mld mpd clean check-schema-drift test run
.PHONY: help diagrams mcd mld mpd javadoc clean check-schema-drift test run

# Default make target used if none specified
.DEFAULT_GOAL := help
Expand All @@ -11,6 +11,7 @@ help:
@echo " make mcd — generate MCD"
@echo " make mld — generate MLD"
@echo " make mpd — generate MPD"
@echo " make javadoc — generate the Java API reference (Javadoc)"
@echo " make clean — remove generated diagrams"
@echo " make check-schema-drift — fail if a Liquibase column is missing from the MCD"
@echo " make test — run the test suite via Testcontainers"
Expand All @@ -20,6 +21,14 @@ help:
diagrams: mcd mld mpd
@echo "All diagrams generated (MCD, MLD, MPD)"

# Generate the Java API reference (Javadoc) from the /** */ comments.
# The plugin is not bound to any lifecycle phase, so this is the only way it
# runs: a normal build (make test, mvn package) never pays for it.
javadoc:
@echo "Generating the Javadoc..."
./mvnw -q -B javadoc:javadoc
@echo "Javadoc generated in target/reports/apidocs/index.html"

# Run the test suite. Tests use Testcontainers (a real PostgreSQL), so a
# container engine must be running. Under Podman, point Testcontainers at the
# Podman socket and disable Ryuk. Under Docker, run the Maven wrapper directly.
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,11 @@ visit [this link](https://github.com/users/ebouchut/projects/7/views/3).

## Documentation

- [API reference (Javadoc)](https://www.ericbouchut.com/learn-dev/javadoc/index.html) —
the code reference rendered from the Javadoc comments, republished from `dev` on
each merge by the [Lint workflow](https://github.com/ebouchut/learn-dev/actions/workflows/lint.yml);
build it locally with `make javadoc` (see
[CONTRIBUTING](CONTRIBUTING.md#generating-the-documentation)).
- [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
Expand Down
25 changes: 25 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
<java.version>21</java.version>
<spring-dotenv.version>5.1.0</spring-dotenv.version>
<maven-checkstyle-plugin.version>3.6.0</maven-checkstyle-plugin.version>
<maven-javadoc-plugin.version>3.11.2</maven-javadoc-plugin.version>
<jacoco-maven-plugin.version>0.8.15</jacoco-maven-plugin.version>
<commonmark.version>0.24.0</commonmark.version>
<jsoup.version>1.21.1</jsoup.version>
Expand Down Expand Up @@ -251,6 +252,30 @@
<failOnViolation>false</failOnViolation>
</configuration>
</plugin>
<!--
API reference: Javadoc.
No <executions>, so the plugin stays inert during the normal
build (test, package) and only runs when invoked explicitly:
make javadoc (or ./mvnw javadoc:javadoc)
It writes the browsable API docs to target/reports/apidocs/.
doclint=all,-missing validates the syntax, the HTML and the
{@link} references, but does not complain about missing
@param/@return: Checkstyle already reports missing Javadoc
(MissingJavadocType/Method), and per ADR-0011 those quality
checks report rather than block.
Note: Javadoc reads the SOURCE, so the getters and setters
that Lombok generates (@Getter/@Setter) do not appear in the
output. Delombok is deliberately not added.
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<configuration>
<doclint>all,-missing</doclint>
<notimestamp>true</notimestamp>
</configuration>
</plugin>
<!--
Test coverage: JaCoCo.
prepare-agent instruments the JVM Surefire forks, and the report
Expand Down