Skip to content

Check license headers with Apache RAT in the build - #1732

Merged
papegaaij merged 1 commit into
masterfrom
rat-license-check
Nov 2, 2026
Merged

papegaaij merged 1 commit into
masterfrom
rat-license-check

Conversation

@papegaaij

Copy link
Copy Markdown
Contributor

Part of #1723. Independent of #1731; together they leave Apache RAT with nothing to report.

The Apache Trusted Releases platform (ATR) runs Apache RAT 0.18 on every source archive. Every unapproved file becomes a concern the release manager has to acknowledge before a vote. On master, RAT run with the ATR's arguments flags 1470 files. This PR brings that to zero and keeps it there.

What changes

  • .rat-excludes at the root. This is the file the ATR reads. It lists the files that stay without a header, grouped by reason:

    • third-party code, which LICENSE covers
    • generated release notes
    • IDE settings
    • the archetype's project templates
    • markup Wicket renders to the browser as is
    • example markup
    • test data that tests compare byte for byte

    The groups follow the ignore lists of the existing ApacheLicenceHeaderTests.

  • Headers added to the files that can carry one:

    • the root markdown files and .asf.yaml
    • the META-INF/services files
    • the 222 user guide .adoc files (in //// comments, which don't render)
    • a few XML and text files
    • two Java files that lacked one
  • Root pom runs apache-rat-plugin 0.18 at validate, over the whole tree, reading the same .rat-excludes.

    • Locally it also skips what Git ignores, node/node_modules, and minified files.
    • It takes about half a minute, so -Pfast skips it.

Worth knowing

  • Local files without a header now fail the build. That applies to any file neither committed nor ignored by Git, such as a local note.
  • The release needs no extra step. release:perform builds from a clean checkout of the tag, so this check runs on exactly what goes into the archive.
  • The ATR scans more than the local build. With a .rat-excludes present, it drops its own Git/Maven/IDE default exclusions, which is why .gitignore and MANIFEST.MF are listed explicitly.

Verification

  • mvn clean verify -Pjs-test passes.
  • A file without a header fails the build and is named in the output.
  • RAT 0.18 run with the ATR's exact arguments on a git archive reports 0 unapproved files. That holds for this branch alone and merged with List bundled third-party code in LICENSE and keep NOTICE to required notices #1731.
  • The user guide still renders (-Pguide), with no header text in the HTML or DocBook output.

🤖 Generated with Claude Code

Wicket checked license headers only with its own
ApacheLicenseHeaderTestCase, one test per module, each with its own ignore
lists and each covering only its module's directory. Files outside the
modules, the user guide, markdown, YAML, service files and anything
outside the file types the test knows were never checked. Apache RAT, run
over the source tree, reported 1470 files without an approved license.

The Apache Trusted Releases platform runs RAT 0.18 on every source archive
and reads its exclusions from a .rat-excludes file at the archive root.
Unapproved files are recorded as concerns the release manager has to
acknowledge before a vote can start.

The root pom now runs apache-rat-plugin 0.18 over the whole tree at
validate, reading the same .rat-excludes. Files that can carry a header now
have one: the markdown files, .asf.yaml, the service files, the user guide,
a few XML and text files and two Java files that lacked it. The
exclusions record the files that stay without one and why: third-party
code, which LICENSE covers, generated release notes, IDE settings, the
archetype's project templates, markup rendered to the browser as is,
example markup (as the examples' header test already decided) and test
data that tests compare byte for byte. These follow the ignore lists of
the existing header tests.

Locally the check also skips what Git ignores, node and node_modules, and
minified files. It takes about half a minute, so -Pfast skips it. A file
without a header that is neither committed nor ignored by Git, such as a
local note, now fails the build until it gets a header or is removed.

GitHub issue #1723

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.17%. Comparing base (75ba768) to head (3569543).

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #1732      +/-   ##
============================================
- Coverage     63.17%   63.17%   -0.01%     
+ Complexity    11558    11556       -2     
============================================
  Files          1253     1253              
  Lines         48635    48635              
  Branches       6844     6844              
============================================
- Hits          30725    30723       -2     
- Misses        15192    15193       +1     
- Partials       2718     2719       +1     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@papegaaij
papegaaij marked this pull request as ready for review October 31, 2026 08:31

@dashorst dashorst left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I ran RAT on the head, and again merged with current master: zero unapproved files both times, and a stray headerless file fails validate with its name in the output.

One non-blocking suggestion: the pom excludes a few things locally that the ATR does not, which makes the local check more lenient than the one that matters at release time.

  • **/*.min.js, **/*.min.css, **/node/** and **/node_modules/** currently exclude nothing extra: all tracked minified files are already covered by .rat-excludes, and node/node_modules are git-ignored. What they would do is let a future minified file pass locally while the ATR flags it. I'd drop these four and keep only what a working tree needs (the Git ignore parsing and the standard excludes for target and the like).
  • .github/workflows/maven.yml has no license header; it only passes because HIDDEN_DIR skips it locally. dependabot.yml and check-coverage-report.py next to it do have one. Adding a header there removes the dependency on HIDDEN_DIR lining up with what the ATR scans.

@papegaaij
papegaaij merged commit bd77ee5 into master Nov 2, 2026
3 checks passed
@papegaaij
papegaaij deleted the rat-license-check branch November 2, 2026 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants