Skip to content

Commit

Permalink
Initial Checkstyle support
Browse files Browse the repository at this point in the history
  • Loading branch information
jwgmeligmeyling committed Jun 14, 2020
1 parent 982e408 commit 252fa7d
Show file tree
Hide file tree
Showing 12 changed files with 5,104 additions and 716 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ jobs:
- uses: actions/checkout@v2
- uses: ./
with:
path: '**/pmd.xml'
path: '**/checkstyle-result.xml'
28 changes: 13 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
![build-test](https://github.com/jwgmeligmeyling/pmd-github-action/workflows/build-test/badge.svg)
![build-test](https://github.com/jwgmeligmeyling/checkstyle-github-action/workflows/build-test/badge.svg)

# PMD GitHub Action
# Checkstyle GitHub Action

This action pushes results from [PMD](https://pmd.github.io/) as check run annotations. :rocket:
This action pushes results from [Checkstyle](https://checkstyle.github.io/) as check run annotations. :rocket:

The action can also be used for any other static analysis tools that produce reports in the PMD XML format.
The action can also be used for any other static analysis tools that produce reports in the Checkstyle XML format.
The report itself must be generated in a former build step, for example a Maven build.

![example](images/example.png)
Expand All @@ -13,13 +13,13 @@ The report itself must be generated in a former build step, for example a Maven

### `path`
Required. A file, directory or wildcard pattern that describes where to find the reports.
Multiple files can be processed through a [glob expression](https://github.com/actions/toolkit/tree/master/packages/glob), for example: `'**/pmd.xml'`.
Multiple files can be processed through a [glob expression](https://github.com/actions/toolkit/tree/master/packages/glob), for example: `'**/checkstyle.xml'`.

### `name`
Optional. Name for the check run to create. Defaults to `PMD`.
Optional. Name for the check run to create. Defaults to `Checkstyle`.

### `title`
Optional. Title for the check run to create. Defaults to `PMD Source Code Analyzer report`.
Optional. Title for the check run to create. Defaults to `Checkstyle Source Code Analyzer report`.

### `token`
Optional. GitHub API access token. Defaults to `${{ github.token }}`, which is set by `actions/checkout@v2` minimally.
Expand Down Expand Up @@ -47,10 +47,10 @@ jobs:
restore-keys: |
${{ runner.os }}-maven-
- name: Build with Maven
run: mvn -B verify pmd:pmd
- uses: jwgmeligmeyling/pmd-github-action@v1
run: mvn -B verify checkstyle:checkstyle
- uses: jwgmeligmeyling/checkstyle-github-action@v1
with:
path: '**/pmd.xml'
path: '**/checkstyle-result.xml'
```
And do not forget to enable XML output for the Maven plugin:
Expand All @@ -60,12 +60,10 @@ And do not forget to enable XML output for the Maven plugin:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.13.0</version>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<includeTests>true</includeTests>
<failOnViolation>false</failOnViolation>
<skipEmptyReport>false</skipEmptyReport>
<failsOnError>false</failsOnError>
</configuration>
</plugin>
</plugins>
Expand Down
11 changes: 8 additions & 3 deletions __tests__/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ beforeAll(() => {
})

test('parses file', async () => {
const spotBugsXml = path.resolve(__dirname, '..', 'reports', 'pmd.xml')
const annotations = annotationsForPath(spotBugsXml)
expect(annotations).toHaveLength(171)
const report = path.resolve(
__dirname,
'..',
'reports',
'checkstyle-result.xml'
)
const annotations = annotationsForPath(report)
expect(annotations).toHaveLength(1928)
})
8 changes: 4 additions & 4 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
name: 'Push PMD report'
description: 'Push PMD Code Analysis report'
name: 'Push Checkstyle report'
description: 'Push Checkstyle code adherence report'
author: 'Jan-Willem Gmelig Meyling'
inputs:
path:
description: 'A file, directory or wildcard pattern that describes where to find the reports'
required: true
name:
description: 'Check run name under which the report is created'
default: PMD
default: Checkstyle
title:
description: 'Check run title under which the report is created'
default: PMD Source Code Analyzer report
default: Checkstyle report
token:
description: >
Personal access token (PAT) used to fetch the repository. The PAT is configured
Expand Down
71 changes: 53 additions & 18 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6871,6 +6871,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
};
Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(__webpack_require__(470));
const checkstyle_1 = __webpack_require__(646);
const fast_xml_parser_1 = __importDefault(__webpack_require__(989));
const fs_1 = __importDefault(__webpack_require__(747));
const path = __importStar(__webpack_require__(622));
Expand All @@ -6886,10 +6887,9 @@ function asArray(arg) {
}
function getWarningLevel(arg) {
switch (arg) {
case '1':
case checkstyle_1.Severity.error:
return github_1.AnnotationLevel.failure;
case '2':
case '3':
case checkstyle_1.Severity.warning:
return github_1.AnnotationLevel.warning;
default:
return github_1.AnnotationLevel.notice;
Expand All @@ -6903,16 +6903,16 @@ function annotationsForPath(resultFile) {
return ramda_1.chain(file => {
return ramda_1.map(violation => {
const annotation = {
annotation_level: getWarningLevel(violation.priority),
annotation_level: getWarningLevel(violation.severity),
path: path.relative(root, file.name),
start_line: Number(violation.beginline || 1),
end_line: Number(violation.endline || violation.beginline || 1),
title: `${violation.ruleset} ${violation.rule}`,
message: violation['#text']
start_line: Number(violation.line || 1),
end_line: Number(violation.line || 1),
title: violation.source,
message: violation.message
};
return annotation;
}, asArray(file.violation));
}, asArray((_a = result.pmd) === null || _a === void 0 ? void 0 : _a.file));
}, asArray(file.error));
}, asArray((_a = result.checkstyle) === null || _a === void 0 ? void 0 : _a.file));
}
exports.annotationsForPath = annotationsForPath;

Expand Down Expand Up @@ -8457,7 +8457,8 @@ const search_1 = __webpack_require__(589);
const constants_1 = __webpack_require__(32);
const annotations_1 = __webpack_require__(147);
const ramda_1 = __webpack_require__(61);
const github_1 = __webpack_require__(469);
const github_1 = __webpack_require__(824);
const github_2 = __webpack_require__(469);
const MAX_ANNOTATIONS_PER_REQUEST = 50;
function run() {
return __awaiter(this, void 0, void 0, function* () {
Expand All @@ -8476,8 +8477,9 @@ function run() {
core.debug(`Grouping ${annotations.length} annotations into chunks of ${MAX_ANNOTATIONS_PER_REQUEST}`);
const groupedAnnotations = ramda_1.splitEvery(MAX_ANNOTATIONS_PER_REQUEST, annotations);
core.debug(`Created ${groupedAnnotations.length} buckets`);
const conclusion = getConclusion(annotations);
for (const annotationSet of groupedAnnotations) {
yield createCheck(name, title, annotationSet, annotations.length);
yield createCheck(name, title, annotationSet, annotations.length, conclusion);
}
}
}
Expand All @@ -8486,14 +8488,31 @@ function run() {
}
});
}
function createCheck(name, title, annotations, numErrors) {
function getConclusion(annotations) {
if (annotations.length === 0) {
return 'success';
}
const annotationsByLevel = ramda_1.groupBy(a => a.annotation_level, annotations);
if (annotationsByLevel[github_1.AnnotationLevel.failure] &&
annotationsByLevel[github_1.AnnotationLevel.failure].length) {
return 'failure';
}
else if (annotationsByLevel[github_1.AnnotationLevel.warning] &&
annotationsByLevel[github_1.AnnotationLevel.warning].length) {
return 'neutral';
}
return 'success';
}
function createCheck(name, title, annotations, numErrors, conclusion) {
return __awaiter(this, void 0, void 0, function* () {
const octokit = github_1.getOctokit(core.getInput(constants_1.Inputs.Token));
const req = Object.assign(Object.assign({}, github_1.context.repo), { ref: github_1.context.sha });
core.info(`Uploading ${annotations.length} / ${numErrors} annotations to GitHub as ${name} with conclusion ${conclusion}`);
const octokit = github_2.getOctokit(core.getInput(constants_1.Inputs.Token));
const req = Object.assign(Object.assign({}, github_2.context.repo), { ref: github_2.context.sha });
const res = yield octokit.checks.listForRef(req);
const existingCheckRun = res.data.check_runs.find(check => check.name === name);
if (!existingCheckRun) {
const createRequest = Object.assign(Object.assign({}, github_1.context.repo), { head_sha: github_1.context.sha, name, status: 'completed', conclusion: numErrors === 0 ? 'success' : 'neutral', output: {
const createRequest = Object.assign(Object.assign({}, github_2.context.repo), { head_sha: github_2.context.sha, conclusion,
name, status: 'completed', output: {
title,
summary: `${numErrors} violation(s) found`,
annotations
Expand All @@ -8502,7 +8521,8 @@ function createCheck(name, title, annotations, numErrors) {
}
else {
const check_run_id = existingCheckRun.id;
const update_req = Object.assign(Object.assign({}, github_1.context.repo), { check_run_id, status: 'completed', conclusion: numErrors === 0 ? 'success' : 'neutral', output: {
const update_req = Object.assign(Object.assign({}, github_2.context.repo), { conclusion,
check_run_id, status: 'completed', output: {
title,
summary: `${numErrors} violation(s) found`,
annotations
Expand Down Expand Up @@ -20798,7 +20818,22 @@ module.exports = join;

/***/ }),
/* 645 */,
/* 646 */,
/* 646 */
/***/ (function(__unusedmodule, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", { value: true });
var Severity;
(function (Severity) {
Severity["error"] = "error";
Severity["warning"] = "warning";
Severity["info"] = "info";
Severity["ignore"] = "ignore";
})(Severity = exports.Severity || (exports.Severity = {}));


/***/ }),
/* 647 */,
/* 648 */
/***/ (function(module, __unusedexports, __webpack_require__) {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "pmd-github-action",
"name": "checkstyle-github-action",
"version": "1.0.0",
"private": false,
"description": "PMD GitHub action",
"description": "Checkstyle GitHub action",
"main": "lib/main.js",
"scripts": {
"build": "tsc",
Expand Down
Loading

0 comments on commit 252fa7d

Please sign in to comment.