Skip to content

CI: Run the code quality checks once, in the job that is meant to run them - #211

Open
MarkusPaulsen wants to merge 1 commit into
mainfrom
chore/ci-quality-gate-separation
Open

CI: Run the code quality checks once, in the job that is meant to run them#211
MarkusPaulsen wants to merge 1 commit into
mainfrom
chore/ci-quality-gate-separation

Conversation

@MarkusPaulsen

@MarkusPaulsen MarkusPaulsen commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

Ares checks its own code with four tools: Checkstyle, PMD, CPD and SpotBugs. They are
wired into the Maven build, so six CI jobs ran them when only one was meant to. A Maven
profile now switches them off for the jobs whose purpose is something else, so the build
job only builds and the analysis job only checks. The analysis job also gains the
duplicate-code check, which it never actually ran.

Linked issues

No linked issues

1. Problem

Nothing in Ares itself is broken, and no security part of Ares is at fault. This is about
how the project checks its own code.

Checkstyle, PMD, CPD and SpotBugs are attached to the Maven package phase, so any
command that packages the project runs them. Six jobs per pull request did: Build, Static
Code Analysis, CodeQL, both Examples jobs and Coverage Report. Five of them paid for a
check that was not their job, about two and a half minutes of runner time per pull
request, and nobody reading the workflow files could tell which job checks what.

Worse, Static Code Analysis never ran the duplicate-code check. It calls pmd:check,
which is a different goal from pmd:cpd-check. Duplicated code was found only by
accident, in the jobs that happened to package the project. Switching those off, which is
what this pull request does, would otherwise have removed that check with nothing turning
red.

2. Improvement from the user's perspective

No Improvement from the user's perspective

3. Improvement from the maintainer's perspective

Each job now answers one question. Build answers whether the project builds, Static Code
Analysis answers whether the code is written the way this repository writes code, and the
workflow files say which is which.

The duplicate-code check runs on purpose rather than by accident, and its report is
uploaded with the other three, so a reviewer can read it.

Measured against the same jobs on main: Build drops from 1m32s to 54s and Coverage
Report from 1m31s to 1m02s, both on the critical path, so the pipeline is about 67
seconds shorter. CodeQL drops from 3m30s to 2m48s, and the install
step of the two example jobs by 21 and 11 seconds. Static Code Analysis gains 5 seconds
for the CPD step it was missing. Runner time falls by about two minutes per pull request.

The list of checks lives in one place in pom.xml. A job that does not want them says so
with one flag rather than five, and a check added later cannot creep back into those jobs
unnoticed.

4. Testing manual

Prerequisites

  1. For the steps below, nothing to install: a GitHub account that can read this repository
    is enough.
  2. For the negative case at the end, a terminal with a JDK (17 or 21) and Maven 3.9 or
    newer, and this branch checked out. The change is build-tool independent on the
    exercise side, because it touches only how Ares itself is built, never how an exercise
    consumes it.

Steps

Not reproducible from an exercise. This changes the CI setup of Ares itself, so a reviewer
verifies it from this pull request's own workflow runs.

Read the latest attempt of each run. The first attempt of every run on this branch had an
empty dependency cache, because the cache key is a hash of pom.xml and this pull request
changes it, so its timings say nothing about the change.

  1. Open the "Java CI with Maven" run of this pull request and its "Build" job. Expect one
    step after the setup, called "Build", and no "Spotless Check" step. Search the log for
    checkstyle:, pmd: and spotbugs: and expect no match, because the job now only
    builds.
  2. Open the "Static Code Analysis" job of the same run. Expect the steps Spotless,
    Checkstyle, PMD, CPD and SpotBugs. Open "CPD" and expect a line reading
    --- pmd:3.28.0:cpd-check.
  3. Download the "static-analysis-reports" artefact of that run. Expect four files:
    checkstyle-result.xml, pmd.xml, cpd.xml and spotbugsXml.xml. The third is the
    new one.
  4. Open the "Coverage Report" job of the same run. Search the log for spotbugs: and
    expect no match, then open the job summary and confirm the "Aggregated code coverage"
    table is still there.
  5. Open the "CodeQL" run of this pull request and its "Build" step, then the "Examples"
    run and its "Install Ares from this commit" step. Search both for spotbugs: and
    expect no match in either.

Expected result

Every job named above is green. The quality checks appear in exactly one job, Static Code
Analysis, and that job now reports five tools where it reported four. Nothing that was
checked before this pull request is unchecked after it.

Negative case (what must still be rejected)

This part needs a terminal, and it is the part worth doing, because the risk of this
change is a check that quietly stops running.

  1. On a throwaway branch, paste an exact copy of an existing method into the class it came
    from, then run mvn pmd:cpd-check. Expect it to fail and to name the duplication. This
    is the check that had no step of its own before this pull request.
  2. Break the formatting of any Java file, for example by replacing the leading tabs of one
    line with spaces, then run mvn spotless:check. Expect it to fail.
  3. With both changes still in place, run
    mvn clean package -DskipTests -Pwithout-quality-gates. Expect it to succeed: the
    profile switches the style checks off, and it must not hide anything else.
  4. Run mvn clean package -DskipTests without the profile. Expect it to fail. That is
    what keeps a local build honest, and it is why the profile is not active by default.
  5. Throw the branch away.

Optional extra, the measurement behind section 3: from a clean checkout run
mvn clean package -DskipTests followed by ls target/*.xml, expecting the four report
files, then mvn clean package -DskipTests -Pwithout-quality-gates followed by
ls target/*.xml, expecting none and a noticeably shorter build. Locally on a JDK 17 this
was 30.5 seconds against 18.6 seconds.

Modes exercised

No mode-specific behaviour changed.

  • ArchUnit + AspectJ
  • ArchUnit + instrumentation
  • WALA + AspectJ
  • WALA + instrumentation

5. Test case coverage regarding this PR

No production Java code changed.

Breaking changes and migration

No breaking changes or migration.

Checklist

  • CI is green, or every remaining failure is explained above.
  • No secrets, tokens or absolute local paths are contained in the diff.

Review progress

  • Code review
  • Manual test

Checkstyle, PMD, CPD and SpotBugs are bound to the package phase, so every
command that reaches it runs them. Six jobs per pull request did: build, static
analysis, CodeQL, both example jobs and the coverage report. Only the second was
meant to.

A new profile, without-quality-gates, turns the whole gate off for one
invocation. The four jobs whose purpose is something else activate it, so Build
answers only whether the project builds and Static Code Analysis answers whether
the code is written the way this repository writes code. The profile is not
active by default, so a local build still crosses the gate.

The build job loses its Spotless step for the same reason: formatting is the
analysis job's question. Spotless keeps no lifecycle binding of its own, so
nothing changes for a local build or for the release path.

Static Code Analysis was missing CPD. It runs pmd:check, which does not include
cpd-check, so duplicated code was found only as a side effect of the
package-bound execution the other jobs happened to run. Switching those off
would have removed that check without a single test turning red. The step is
added and cpd.xml is uploaded with the other three reports.

Measured on JDK 17 from a clean target: mvn clean package -DskipTests takes
30.5s and writes all four report files, with the profile it takes 18.6s and
writes none. In CI that is roughly 30 seconds off Build and off Coverage Report,
both on the critical path, 30 off CodeQL and 25 off each example job.

Two comments were wrong and are corrected. The one above the compile step
claimed only SpotBugs needs compiled classes; PMD needs them too, and without
them reports 18 unused wildcard imports it cannot resolve. The one above the
analysis plugins ran to 890 characters, well past the 500 this repository allows.
@MarkusPaulsen
MarkusPaulsen requested a review from a team August 25, 2026 15:37
@MarkusPaulsen
MarkusPaulsen requested review from a team and krusche as code owners August 25, 2026 15:37
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0ee7511f-76cc-49fe-97b5-51303d2835d8


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the other Automated area label: other label Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

other Automated area label: other

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant