pmd / pmd-github-action Goto Github PK
View Code? Open in Web Editor NEWGitHub Action for PMD
License: MIT License
GitHub Action for PMD
License: MIT License
This action calls PMD and PMD requires a Java runtime for execution.
In the README.md the following basic configuration is suggested:
steps:
- uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: '11'
- uses: pmd/pmd-github-action@v1
with:
rulesets: 'ruleset.xml'
However, the "actions/setup-java" step is not really necessary, since Java is one of the pre-installed tools in the runners. See https://github.com/actions/virtual-environments/ and more specifically https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md#java
This is available under all operating systems.
With the new input parameter analyzeModifiedFilesOnly
this action now determines the modified files of a push or pull_request and executes PMD only on these files. This new input parameter is enabled by default.
Instead of analyze all files under "sourcePath", only the files that have been touched in a pull request or push will be analyzed. This makes the analysis faster and helps especially bigger projects which gradually want to introduce PMD. This helps in enforcing that no new code violation is introduced.
Depending on the analyzed language, the results might be less accurate results. At the moment, this is not a problem, as PMD mostly analyzes each file individually, but that might change in the future.
If the change is very big, not all files might be analyzed. Currently the maximum number of modified files is 300.
Note: the touched files are analyzed completely and all found violations within these files are reported - regardless whether the specific lines have been modified or not.
For bigger projects or projects, which gradually want to introduce PMD, it would be beneficial if only the currently modified files would be analyzed. This helps in enforcing that no new code violation is introduced.
Maybe a new input parameter needs to be introduced, similar like pmd-analyser-action's analyze-all-code.
Running the action in this mode, we would probably ignore the sourcePath
input parameter and only look at the github event's compare payload: For pull requests we could look at the diff_url or patch_url. For pushes we might be able to use the "compare" url. The REST API also has a way to compare two commits. For pull requests there is list-pull-requests-files.
If the files can be determined by calling the GitHub API, then there is no full checkout needed (fetch-depth).
Instead of providing the sourcePath to PMD (-d
cli option), the --file-list
option needs to be used, generating a comma-delimited file list on the fly.
A simple solution for the first version could be: let PMD analyze all files and just filter the found violations.
Currently the action doesn't use an API token. This probably should be changed, if the patches/diffs are retrieved by the API calls. Then @actions-github. In theory, the default token should be available via the github-context. Since we only need read-only access, that should be sufficient. Then no extra configuration is required. At least we can provide a reasonable default value. The default value can be provided like the "checkout" action does it: https://github.com/actions/checkout/blob/230611dbd0eb52da1e1f4f7bc8bb0c3a339fc8b7/action.yml#L12-L24
Which mode is active (analyzing all files or only modified files) should be logged in the build log, e.g. "Running PMD on path xyz" or "Running PMD on x files".
You can configure a specific priority for each rule in your own ruleset (https://pmd.github.io/latest/pmd_userdocs_configuring_rules.html#message-and-priority-overriding).
The maven-pmd-plugin supports the parameter failurePriority
which can used to fail the build only for "high priority" violations. The lower priority violations are still reported, though.
Currently the action only provides the number of found violations regardless of the priority. So you can only fail the build if any violation is found. This probably has to be tackled together with #30 .
Log output:
Run pmd/pmd-github-action@features/annotation
with:
sourcePath: src/main/java
rulesets: ruleset.xml,category/java/design.xml/AbstractClassWithoutAnyMethod
version: latest
"C:\Program Files\PowerShell\7\pwsh.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command "$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.ZipFile } catch { } ; try { [System.IO.Compression.ZipFile]::ExtractToDirectory('D:\a\_temp\d900343f-1477-4896-849f-4ad7c682771e', 'D:\a\_temp\31b52bc9-9a59-4858-a700-f782163268ae', $true) } catch { if (($_.Exception.GetType().FullName -eq 'System.Management.Automation.MethodException') -or ($_.Exception.GetType().FullName -eq 'System.Management.Automation.RuntimeException') ){ Expand-Archive -LiteralPath 'D:\a\_temp\d900343f-1477-4896-849f-4ad7c682771e' -DestinationPath 'D:\a\_temp\31b52bc9-9a59-4858-a700-f782163268ae' -Force } else { throw $_ } } ;"
Using PMD 6.41.0 from cached path C:\hostedtoolcache\windows\pmd\6.41.0\x64
Error: Unable to locate executable file: C:\hostedtoolcache\windows\pmd\6.41.0\x64/pmd-bin-6.41.0/bin/run.sh. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.
PMD exited with undefined
PMD detected 0 violations.
Error: File pmd-report.sarif does not exist
With #7 inline annotations are created, but they can't be commented or resolved. The PMD GitHub Action could add comments for each found violation when running on a pull request. This requires to only consider the modified files (#6).
See https://github.com/rody/pmd-review-github-action for the idea.
This should add a new input parameter for the action, which can switch on this feature. When review comments are created, no annotations should be created then.
See also #12 (comment)
PMD produces a SARIF file with multiple location entries per result. It appears that on GitHub only the first location is used.
Example file: pmd-report.sarif.txt
In this case, we have in total 24 violations in 6 files. The violations are from one of 9 different rules.
In the end, we don't have 24 alerts but only 9 alerts after uploading. This is also visible in the build log: "num_results_in_sarif":9
.
Code scanning alerts: https://github.com/pmd/pmd-github-action-tests/security/code-scanning?query=branch%3Ajava
Test case, see https://github.com/pmd/pmd-github-action-tests/tree/java#code-scanning-alerts
Sarif feature in PMD: https://pmd.github.io/latest/pmd_userdocs_report_formats.html#sarif
Sarif Spec: https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html
3.14.23 results property
... an array of zero or more result objects (§3.27) each of which represents a single result detected in the course of the run
Could be interpreted in the way, that since we have 24 violations, each of these violations should be a single result...
3.27.12 locations property
a) A result object SHOULD contain a property named locations whose value is an array of zero or more location objects (§3.28) each of which specifies a location where the result occurred.
b) The locations array SHALL NOT contain more than one element unless the condition indicated by the result, if any, can only be corrected by making a change at every location specified in the array.
c) The locations array SHALL NOT be used to specify distinct occurrences of the same result which can be corrected independently.
ok, a) is what PMD does. All locations where a specific rule was violated.
sentence b) is probably violated: every location must be fixed to in order to correct the result
sentence c) is also violated: PMD only produces distinct results and they usually can be corrected independently.
So, I guess, that's a bug in PMD: pmd/pmd#3768.
First release of the official GitHub Action for PMD.
This action runs PMD static code analysis checks.
It can execute PMD with your own ruleset against your project. It creates a SARIF report which is uploaded as a build artifact. Furthermore the build can be failed based on the number of violations.
Please publish newer version using node20 you made 2 months ago. Latest version is +10 months stale. Lots of stuff has been added since
https://github.com/pmd/pmd-github-action/tree/v1.4.1
Related issues:
Maybe the annotations should be replaced with checks api, see #30
If you configure sourcePath: 'src/main/java'
and you have sources under src/main/java/**
and under src/main/java2/**
then the sources under java2 are still analyzed. This is unexpected.
Workaround: sourcePath: 'src/main/java/'
(with a trailing slash).
Note: this only is occurs when using "analyzeModifiedFilesOnly: true" (default). When all files are analyzed, then sourcePath is considered correctly.
When configured to run on a push
event and the GitHub's context.payload.before
commit is 0000000000000000000000000000000000000000
(meaning there was no prior commit) then the action fails with error Error: Not Found
.
The error is raised by util.js
by determineModifiedFiles(..)
function when it invokes octokit.rest.repos.compareCommitsWithBasehead(..)
https://github.com/pmd/pmd-github-action/blob/main/lib/util.js#L143
# .github/workflows/pmd.yml
name: Run PMD
on:
push:
branches:
- my-branch
paths:
- my-folder
jobs:
build:
name: Run PMD
runs-on: self-hosted
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Run Apex Rules
uses: pmd/pmd-github-action@v1
with:
rulesets: rulesets/PMD/apex-rules-github.xml
sourcePath: my-folder
analyzeModifiedFilesOnly: true
createGitHubAnnotations: true
$ git diff-tree --no-commit-id --name-only --diff-filter=AM -r <commit>
index.html
my-folder/some-file.java
const response = await octokit.rest.repos.getCommit({
...context.repo,
ref: eventData.after,
});
console.log(response);
---
{
status: 200,
url: 'https://api.github.com/repos/my-org/my-repo/commits/65a6b28ce342017b77bde00498434386961cdff7',
headers: {
...
},
data: {
sha: '65a6b28ce342017b77bde00498434386961cdff7',
node_id: 'C_kwDOFndAydoAKDY1YTZiMjhjZTM0MjAxN2I3N2JkZTAwNDk4NDM0Mzg2OTYxY2RmZjc',
commit: {
...
},
url: '...',
html_url: '...',
comments_url: '...',
author: {
...
},
committer: {
...
},
parents: [ { ... } ],
stats: { total: 40, additions: 36, deletions: 4 },
files: [
{
sha: '4b38cfc1be0f3290f3340093825b6bbc48fd69b4',
filename: 'index.html',
status: 'modified',
additions: 9,
deletions: 1,
changes: 10,
blob_url: '...',
raw_url: '...',
contents_url: '...',
patch: '...'
},
{
sha: '565abd034c00e10add52d15cfe478f5bee3fe1da',
filename: 'my-folder/my-file.java',
status: 'modified',
additions: 9,
deletions: 1,
changes: 10,
blob_url: '...',
raw_url: '...',
contents_url: '...',
patch: '...'
}
]
}
}
##[debug]finished caching tool
Using PMD 6.49.0 from cached path /home/docker/actions-runner/_work/_tool/pmd/6.49.0/x64
Determining modified files in my-folder...
##[debug]Push on refs/heads/my-branch: 0000000000000000000000000000000000000000...c46068a4fd0827f6c4365d24c02c1bc44707287a
Error: Not Found
##[debug]Node Action run completed with exit code 1
I have seen the similar problem that was already raised but quite unsure if those are identical so that is why i wanted to report it.
Im receiving the error below.
And here is the my action YML. Please advise.
# Unique name for this workflow
name: Pre-Release PR
# Definition when the workflow should run
on:
workflow_dispatch:
pull_request:
types: [opened, edited, synchronize, reopened]
permissions:
pull-requests: write
jobs:
pmd-run:
runs-on: catalyst
steps:
# Now we install nodejs in the VM, and specify version 14
- uses: actions/setup-node@v3
with:
node-version: "14"
# Install java as it is required for the next step
- uses: actions/setup-java@v3
with:
distribution: "temurin"
java-version: "8"
# Checkout the source code
- name: "Checkout source code"
uses: actions/checkout@v3
with:
fetch-depth: 0
# Run PMD scan
- name: "Run PMD scan"
uses: pmd/[email protected]
id: pmd
with:
sourcePath: "force-app"
rulesets: "ruleset.xml"
analyzeModifiedFilesOnly:
createGitHubAnnotations: true
# Check for PMD violations
- name: "Check for PMD violations"
if: steps.pmd.outputs.violations != 0
run: exit 1
Whether it uses a number 1-5 or "Low" "Medium Low" etc, it would be useful because it would let me use a single rules file for my VSCode PMD scanning and GitHub Actions scanning - and only use severity 1 & 2 in my CI workflow.
Otherwise, I have to have two separate files, and while I don't change them much, setting properties in both across many projects is time-consuming.
Thank you!
See https://docs.github.com/en/rest/reference/checks
The advantage over the currently implemented build annotations (#7) is, that we can mark the build as failed directly. This would make the extra build step, to make the build fail based on the number of violations (exit 1
), superfluous. Then this could be a built-in feature which can be enabled/disabled via a input parameter.
Currently the unit tests test everything except index.js.
Would be good to have an automated integration test.
Currently https://github.com/pmd/pmd-github-action-tests is used for a manual test
Code scanning seems to require the complete picture of the project. E.g. if a violation is not reported anymore, the code scanning alerts are getting closed.
This should be done:
analyzeModifiedFilesOnly
This should include a pointer to https://github.com/pmd/pmd-github-action-tests
The action is now written in plain old javascript. But typescript offers early type checking, so would be beneficial.
At the same time, prettier should be integerated, maybe some vs-code settings (.vscode/settings.json
).
When migrating to typescript, the eslint rules also need to be changed.
Does this offical Github Action have an option to run PMD on diffs only? Like the one in https://github.com/marketplace/actions/pmd-analyser? Or do you plan to add such a helpful option?
GitHub supports to show annotations on the file tab of a pull request or when viewing a single commit.
This PMD Action should create for each found violation that is in the pmd-report.sarif file such an inline annotation. The rule priorities can be used to map to either a error, warning or notice message.
The result might look like this:
Implementation notes:
git rev-parse --show-toplevel
one can figure out the current root checkout directory (which could be anywhere on the runner) and use that to make the absolute filepath in the sarif report into relative ones.When uploading the SARIF file to code-ql, the file in the repository is not found:
Preview unavailable
Sorry, we couldn't find this file in the repository.
Workaround
Add the following step before upload-sarif:
- name: Relativize SARIF
shell: bash
run: |
jq ".runs[0].results[].locations[].physicalLocation.artifactLocation.uri |= sub(\"${GITHUB_WORKSPACE}/\"; \"\")" pmd-report.sarif > pmd-report2.sarif
mv -f pmd-report2.sarif pmd-report.sarif
It seems, that issue #51 reappeared...
Log output:
src\classes2\AllInOne.cls:2:FieldNamingConventions (Priority: 1):The instance field name 'INSTANCE_FIELD' doesn't match '[a-z][a-zA-Z0-9]*'
Error: Configurable naming conventions for field declarations. This rule reports variable declarations
which do not match the regex that applies to their specific kind ---e.g. constants (static final),
static field, final field. Each regex can be configured through properties.
By default this rule uses the standard Apex naming convention (Camel case).
FieldNamingConventions (Priority: 1, Ruleset: Code Style)
https://pmd.github.io/pmd-6.55.0/pmd_rules_apex_codestyle.html#fieldnamingconventions
That means, we use backslashes as path separators. That means, in the sarif.json file, there are no valid URIs anymore...
{
"ruleId": "FieldNamingConventions",
"ruleIndex": 0,
"message": {
"text": "The instance field name 'INSTANCE_FIELD' doesn't match '[a-z][a-zA-Z0-9]*'"
},
"locations": [
{
"physicalLocation": {
"artifactLocation": {
"uri": "src\\classes2\\AllInOne.cls"
},
"region": {
"startLine": 2,
"startColumn": 13,
"endLine": 2,
"endColumn": 26
}
}
}
]
},
I think, these should be forward slashes....
When I created a PR with an Apex change the PMD Github Action aborted with this
analyze
Cannot read property 'split' of undefined
Looks like it aborted after parsing the SARIF of the second issue. At least only one is displayed correctly
Hello Folks !!
Is there any way to specify the type of report in the action ? per example , can i do this
- uses: pmd/pmd-github-action@v1
id: pmd
with:
version: '6.40.0'
sourcePath: 'src/main/java'
rulesets: 'rulesets/java/quickstart.xml,ruleset.xml'
reportFile: 'pmd-report.xlst' "Or another report file extension"
Thanks!
If the action is executed under Windows, then no code annotations are created. This is probably because of platform specific file paths (e.g. src/main/java
vs. src\main\java
) and github can't map this to the files.
Hi,
I have shifted all my Github Action(Pipeline) from 16 to 20 th version for Node, but I am facing warning only for PMD pipeline, Kindly help me to resolve this.
Pipeline code:
# Unique name for this workflow
name: PMD Code Scan
# Definition when the workflow should run
on:
# The workflow will run whenever an event happens on a pull request
pull_request:
# The events are that a PR is opened, or when a commit is pushed
# to a branch that has an existing pull request
types: [opened, synchronize]
# The branches filter allows to specify that this workflow should only
# run if the branch name is as listed below. This way we prevent this workflow
# from running when PRs are opened on other branches
branches: [ environment/*/dev , environment/qa ]
# We only care about changes to the force-app directory, which is the
# root directory of the sfdx project. This prevents the job from running
# when changing non-salesforce files (like this yml file).
paths:
- 'force-app/**'
# Jobs to be executed when the above conditions are met
jobs:
# This is the name of the job. You can give it whatever name you want
Run-PMD-Code-Scan:
# As mentioned in the blog post, this job runs inside a VM. Here we
# can specify which OS this VM should run on.
# In this case, we are going to run our commands on the latest version
# of ubuntu
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
# required for all workflows
security-events: write
# only required for workflows in private repositories
actions: read
if: ${{ github.actor != 'dependabot[bot]' }}
steps:
# Now we install nodejs in the VM, and specify version 14
- uses: actions/setup-node@v4
with:
node-version: '20'
# The idea is that the VM can access your remote repository
# because your repository is an sfdx project.
# This is a default action that allows us to enter the root
# directory of the repository
# Make sure to specify fetch-depth:0. This allows us to
# access previous commits that have been pushed to the repository.
# We'll need this later when we try to figure out which metadata has
# changed between commits, so that we can only deploy that metadata
# to the destination org
- name: 'Checkout source code'
uses: actions/checkout@v4
with:
fetch-depth: 0
# Run PMD Scan
- name: 'Run PMD Scan'
uses: pmd/pmd-github-action@v1
id: pmd
with:
sourcePath: 'force-app'
rulesets: 'ruleset.xml'
analyzeModifiedFilesOnly: true
createGitHubAnnotations: true
- name: Fail build if there are violations
if: steps.pmd.outputs.violations != 0
run: exit 1
Warning:
Run-PMD-Code-Scan
Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: pmd/pmd-github-action@v1. For more information see: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/.
Thanks
Hi,
All dependabot commits are marked as failed due to the "not found" error because the change doesn't have any code line.
See https://github.com/steve-community/steve/commits/master
Maybe an extra option (failIfNoCode: true|false
?) could help to configure the behavior.
The motivation for this is I would like to generate the xml format that I could then use another github action to upload as part of the run check. Or could you add support for uploading run check. See https://github.com/lcollins/pmd-github-action
Hello,
As PMD introduced ver 6.46.0 on May 28, GitHub action started to target also "Unchanged files with check annotations" which are not part of the PR.
We are forced to rollback to ver 6.45.0 because this behavior was blocking our deployment.
Is this an expected thing in 6.46? And is there a way to skip the "Unchanged files with check annotations" check from the violations
property of the action output
and use the ver 6.46, or this is a bug?
Thank you.
No matter what I put into my action
https://github.com/rsoesemann/salesforce-recipes/runs/7668564645?check_suite_focus=true
as ruleset.xml path
I always get the same error:
WARNING: No rules found. Maybe you misspelled a rule name? (./ruleset.xml)
PMD exited with 1
Error: Unexpected end of JSON input
The PMD CLI has the --force-language
options to force a language to be used for all input files, irrespective of file names.
This feature allows us to use GitHub Actions for Salesforce projects.
See https://github.com/actions/starter-workflows
There is also an old PR (actions/starter-workflows#1200) which should be replaced by using this action now.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.