Skip to content

PMD for Java

Actions

About

🐶 Run PMD analysis on Java code and report results directly to pull request with the help of reviewdog
v0.1.0
Latest
Star (7)

action-pmd

Test reviewdog depup release GitHub release (latest SemVer) action-bumpr supported

This is a GitHub action to run PMD check on your Java code and report status via reviewdog on pull request.

🚨 BREAKING CHANGES (v0.1.0+)

This version includes major updates and breaking changes:

  • PMD 7.20.0: Upgraded from PMD 6.55.0 to 7.20.0
  • Java 21: Now using Eclipse Temurin 21 (upgraded from OpenJDK 17)
  • Reviewdog v0.21.0: Updated from v0.14.1
  • Default Ruleset Change: category/java/bestpractices.xml (was rulesets/java/quickstart.xml)
  • PMD CLI Change: Uses pmd check command (PMD 7.x syntax)

Migration Required:

  • If you explicitly set rulesets_path, update to PMD 7.x compatible paths (see Migration Guide)
  • Legacy ruleset paths like rulesets/java/basic.xml are no longer supported
  • Review your custom rulesets for deprecated rules

Version Strategy:

  • v1.x branch: Uses PMD 6.x (previous version)
  • v0.1.x: Uses PMD 7.x (current)

Version Information

Component Version
Java Eclipse Temurin 21 (LTS)
PMD 7.20.0
Reviewdog v0.21.0

Example

An example of how the reported pmd violations will look like on pull request is shown below (link to PR):

PR comment with violation

Inputs

inputs:
  github_token:
    description: 'GITHUB_TOKEN'
    default: '${{ github.token }}'
  workdir:
    description: 'Working directory relative to the root directory.'
    default: '.'
  ### Flags for reviewdog ###
  level:
    description: 'Report level for reviewdog [info,warning,error]'
    default: 'error'
  reporter:
    description: 'Reporter of reviewdog command [github-pr-check,github-pr-review].'
    default: 'github-pr-check'
  filter_mode:
    description: |
      Filtering mode for the reviewdog command [added,diff_context,file,nofilter].
      Default is added.
    default: 'added'
  fail_level:
    description: |
      Fail level for reviewdog [none,any,info,warning,error]
      Default is `none`.
    default: 'none'
  tool_name:
    description: 'Tool name to use for reviewdog reporter'
    default: 'pmd'
  reviewdog_flags:
    description: 'Additional reviewdog flags'
    default: ''
  ### Flags for PMD ###
  src_path:
    description: 'Specify the directory where the sources to be analyzed are stored. Default is `src/main/java`.'
    default: 'src/main/java'
  rulesets_path:
    description: 'Specify the path of the PMD rule set. Default is `category/java/bestpractices.xml`.'
    default: 'category/java/bestpractices.xml'
  pmd_cache:
    description: 'Enable PMD incremental analysis with cache file path (e.g., "/tmp/pmd-cache/pmd.cache"). Must be a file path, not a directory. Leave empty to disable.'
    default: ''

Usage

name: pmd
on: [pull_request]
jobs:
  pmd_job:
    runs-on: ubuntu-latest
    name: PMD job
    steps:
    - name: Checkout
      uses: actions/checkout@v3
    - name: Run PMD
      uses: kemsakurai/action-pmd@v0.1.0
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        reporter: 'github-pr-review'
        tool_name: 'pmd_reviewdog'

With PMD Cache (Performance Optimization)

name: pmd
on: [pull_request]
jobs:
  pmd_job:
    runs-on: ubuntu-latest
    name: PMD job with cache
    steps:
    - name: Checkout
      uses: actions/checkout@v3
    - name: Run PMD
      uses: kemsakurai/action-pmd@v0.1.0
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        reporter: 'github-pr-review'
        tool_name: 'pmd_reviewdog'
        pmd_cache: '/tmp/pmd-cache/pmd.cache'  # Enable incremental analysis

With Custom Ruleset

name: pmd
on: [pull_request]
jobs:
  pmd_job:
    runs-on: ubuntu-latest
    name: PMD job with custom ruleset
    steps:
    - name: Checkout
      uses: actions/checkout@v3
    - name: Run PMD
      uses: kemsakurai/action-pmd@v0.1.0
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        reporter: 'github-pr-check'
        rulesets_path: 'category/java/errorprone.xml'  # Use different built-in ruleset

Migration Guide from PMD 6.x to 7.x

Official Documentation

For comprehensive migration information, please refer to:

Key Breaking Changes

  1. CLI Command Change

    • Old: pmd -d <dir> -R <ruleset>
    • New: pmd check -d <dir> -R <ruleset>
  2. Ruleset Path Format

    • ❌ Removed: rulesets/java/basic.xml, rulesets/java/quickstart.xml
    • ✅ Use: category/java/bestpractices.xml, category/java/errorprone.xml
  3. Deprecated Rules Removed

  4. Property Delimiter Change

    • Old: Pipe | separator
    • New: Comma , separator

Migration Steps

  1. Verify Current Ruleset Compatibility

    # Test your current ruleset with PMD 7.x
    docker build --build-arg PMD_VERSION=7.20.0 -t action-pmd:test .
    docker run -v $(pwd):/workspace action-pmd:test pmd check -d /workspace/src -R category/java/bestpractices.xml
  2. Update Workflow Configuration

    # Before (v1.x)
    - uses: kemsakurai/action-pmd@v1
      with:
        rulesets_path: 'rulesets/java/quickstart.xml'
    
    # After (v0.1.0)
    - uses: kemsakurai/action-pmd@v0.1.0
      with:
        rulesets_path: 'category/java/bestpractices.xml'  # Updated path
  3. Review Custom Rulesets

    • Update ruleset references to use category/ prefix
    • Remove references to deleted rules
    • Test thoroughly before deploying

Recommended Rulesets

PMD 7.x provides category-based rulesets. Here are recommended options:

Ruleset Description Use Case
category/java/bestpractices.xml Best practice rules (default) General code quality
category/java/errorprone.xml Error-prone patterns Bug prevention
category/java/codestyle.xml Code style conventions Style enforcement
category/java/design.xml Design principles Architecture quality
category/java/performance.xml Performance optimizations Performance-critical code
category/java/security.xml Security vulnerabilities Security-sensitive applications

Multiple Rulesets Example

- uses: kemsakurai/action-pmd@v0.1.0
  with:
    rulesets_path: 'category/java/bestpractices.xml,category/java/errorprone.xml'

Custom Ruleset Template

Create a custom pmd-ruleset.xml in your repository:

<?xml version="1.0"?>
<ruleset name="Custom Ruleset"
         xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
    
    <description>Custom PMD ruleset for our project</description>
    
    <!-- Include built-in rulesets -->
    <rule ref="category/java/bestpractices.xml"/>
    <rule ref="category/java/errorprone.xml"/>
    
    <!-- Exclude specific rules -->
    <rule ref="category/java/bestpractices.xml">
        <exclude name="UnusedPrivateMethod"/>
    </rule>
    
    <!-- Customize rule properties -->
    <rule ref="category/java/codestyle.xml/LongVariable">
        <properties>
            <property name="minimum" value="30"/>
        </properties>
    </rule>
</ruleset>

Then use it in your workflow:

- uses: kemsakurai/action-pmd@v0.1.0
  with:
    rulesets_path: './pmd-ruleset.xml'

Performance Optimization

PMD Cache

PMD 7.x supports incremental analysis via the --cache option, which can significantly reduce CI execution time for large codebases.

Enable Cache:

- uses: kemsakurai/action-pmd@v0.1.0
  with:
    pmd_cache: '/tmp/pmd-cache/pmd.cache'

Benefits:

  • Analyzes only changed files
  • Reduces analysis time by 30-70% for subsequent runs
  • Automatically managed by PMD

Best Practices:

  • Use a consistent cache path across workflow runs
  • Consider using GitHub Actions cache to persist between runs:
- name: Cache PMD results
  uses: actions/cache@v3
  with:
    path: /tmp/pmd-cache
    key: pmd-cache-${{ github.sha }}
    restore-keys: |
      pmd-cache-

- uses: kemsakurai/action-pmd@v0.1.0
  with:
    pmd_cache: '/tmp/pmd-cache/pmd.cache'

Troubleshooting

Common Errors and Solutions

Error: "Ruleset not found"

Symptom:

Error: Unable to load ruleset: rulesets/java/quickstart.xml

Solution: Update to PMD 7.x category-based paths:

rulesets_path: 'category/java/bestpractices.xml'

Error: "Rule not found"

Symptom:

Error: Rule 'SomeRuleName' not found

Solution: The rule may have been removed in PMD 7.x. Check the removed rules list and find alternatives.

Error: "Permission denied" (Cache)

Symptom:

Warning: Failed to create cache directory

Solution: Ensure the cache path is writable. The action automatically sets permissions, but if using a custom path, verify access:

pmd_cache: '/tmp/pmd-cache/pmd.cache'  # /tmp is always writable

Error: "Java version mismatch"

Symptom:

Error: PMD requires Java 8 or later

Solution: This action includes Java 21. If you're building with a different Java version in previous steps, ensure PMD runs in the action's container context.

Getting Help

Custom Docker Build

You can build the Docker image with custom versions of PMD or Reviewdog:

# Build with specific PMD version
docker build --build-arg PMD_VERSION=7.18.0 -t action-pmd:custom .

# Build with specific Reviewdog version
docker build --build-arg REVIEWDOG_VERSION=v0.20.0 -t action-pmd:custom .

# Build with both custom versions
docker build \
  --build-arg PMD_VERSION=7.18.0 \
  --build-arg REVIEWDOG_VERSION=v0.20.0 \
  -t action-pmd:custom .

License

MIT

PMD for Java is not certified by GitHub. It is provided by a third-party and is governed by separate terms of service, privacy policy, and support documentation.

About

🐶 Run PMD analysis on Java code and report results directly to pull request with the help of reviewdog
v0.1.0
Latest

PMD for Java is not certified by GitHub. It is provided by a third-party and is governed by separate terms of service, privacy policy, and support documentation.