Skip to content

Add support for github pull request annotations #367

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Nov 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ Value|Behaviour
`errors_in_pr`| Check fails if any errors are present in the files added/modified in the PR branch (even if already in base branche).
`errors_in_code`| Check fails if any errors are present in the whole branch.

The output behaviour depends on the value of `output-behaviour`

Value|Behaviour
-- | --
`comment` | Default, comments on the PR with the errors found for this run.
`annotate` | Uses github line annotations with the errors found for this run.
`both` | Does both of the above.

## Use a specific tsconfig file

By default, this actions uses tsconfig file located at './tsconfig.json'
Expand All @@ -86,4 +94,4 @@ parameter `ts-config-path` :

```yml
ts-config-path: './tsconfig.check.json'
```
```
6 changes: 5 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ inputs:
check-fail-mode:
description: "Allowed values : added, errors_in_pr, errors_in_code"
required: true
output-behaviour:
description: "Allowed values : comment, annotate, both"
default: "comment"
required: false
debug:
description: "Set true to log ts errors in base branch and pr branc"
description: "Set true to log ts errors in base branch and pr branch"
default: false
runs:
using: 'node16'
Expand Down
90 changes: 57 additions & 33 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ function getAndValidateArgs() {
lineNumbers: (_d = JSON.parse((0, core_1.getInput)('line-numbers'))) !== null && _d !== void 0 ? _d : [],
useCheck: (0, core_1.getBooleanInput)('use-check'),
checkFailMode: (0, core_1.getInput)('check-fail-mode'),
outputBehaviour: (0, core_1.getInput)('output-behaviour'),
debug: (0, core_1.getBooleanInput)('debug')
};
if (![
Expand All @@ -186,6 +187,13 @@ function getAndValidateArgs() {
].includes(args.checkFailMode)) {
throw new Error(`Invalid value ${args.checkFailMode} for input check-fail-mode`);
}
if (![
"comment" /* OUTPUT_BEHAVIOUR.COMMENT */,
"annotate" /* OUTPUT_BEHAVIOUR.ANNOTATE */,
"both" /* OUTPUT_BEHAVIOUR.COMMENT_AND_ANNOTATE */
].includes(args.outputBehaviour)) {
throw new Error(`Invalid value ${args.outputBehaviour} for input output-behaviour`);
}
return args;
}
exports.getAndValidateArgs = getAndValidateArgs;
Expand Down Expand Up @@ -369,6 +377,9 @@ const parseOutputTsc_1 = __nccwpck_require__(4155);
async function run() {
try {
const args = (0, getAndValidateArgs_1.getAndValidateArgs)();
if (args.debug) {
(0, core_1.info)(`[config] args: \n${JSON.stringify(args)}`);
}
const workingDir = path.join(process.cwd(), args.directory);
(0, core_1.info)(`working directory: ${workingDir}`);
const tsconfigPath = path.join(workingDir, args.tsConfigPath);
Expand Down Expand Up @@ -461,44 +472,57 @@ async function run() {
});
(0, core_1.info)(`${newErrorsInModifiedFiles.length} added errors in modified files`);
(0, core_1.endGroup)();
(0, core_1.startGroup)(`Creating comment`);
const commentInfo = {
...github_1.context.repo,
issue_number: github_1.context.payload.pull_request.number
};
const comment = {
...commentInfo,
body: (0, getBodyComment_1.getBodyComment)({
errorsInProjectBefore: errorsBaseBranch,
errorsInProjectAfter: errorsPr,
newErrorsInProject: resultCompareErrors.errorsAdded,
errorsInModifiedFiles,
newErrorsInModifiedFiles
})
};
(0, core_1.info)(`comment body obtained`);
try {
await octokit.rest.issues.createComment(comment);
if (["annotate" /* OUTPUT_BEHAVIOUR.ANNOTATE */, "both" /* OUTPUT_BEHAVIOUR.COMMENT_AND_ANNOTATE */].includes(args.outputBehaviour)) {
resultCompareErrors.errorsAdded.forEach(err => {
var _a;
(0, core_1.error)(`${err.fileName}:${err.line}:${err.column} - ${err.message}`, {
file: err.fileName,
startLine: parseInt(err.line),
startColumn: parseInt(err.column),
title: (_a = err.extraMsg) !== null && _a !== void 0 ? _a : err.message
});
});
}
catch (e) {
(0, core_1.info)(`Error creating comment: ${e.message}`);
(0, core_1.info)(`Submitting a PR review comment instead...`);
if (["comment" /* OUTPUT_BEHAVIOUR.COMMENT */, "both" /* OUTPUT_BEHAVIOUR.COMMENT_AND_ANNOTATE */].includes(args.outputBehaviour)) {
(0, core_1.startGroup)(`Creating comment`);
const commentInfo = {
...github_1.context.repo,
issue_number: github_1.context.payload.pull_request.number
};
const comment = {
...commentInfo,
body: (0, getBodyComment_1.getBodyComment)({
errorsInProjectBefore: errorsBaseBranch,
errorsInProjectAfter: errorsPr,
newErrorsInProject: resultCompareErrors.errorsAdded,
errorsInModifiedFiles,
newErrorsInModifiedFiles
})
};
(0, core_1.info)(`comment body obtained`);
try {
const issue = github_1.context.issue || pr;
await octokit.rest.pulls.createReview({
owner: issue.owner,
repo: issue.repo,
pull_number: issue.number,
event: 'COMMENT',
body: comment.body
});
await octokit.rest.issues.createComment(comment);
}
catch (errCreateComment) {
(0, core_1.info)(`Error creating PR review ${errCreateComment.message}`);
catch (e) {
(0, core_1.info)(`Error creating comment: ${e.message}`);
(0, core_1.info)(`Submitting a PR review comment instead...`);
try {
const issue = github_1.context.issue || pr;
await octokit.rest.pulls.createReview({
owner: issue.owner,
repo: issue.repo,
pull_number: issue.number,
event: 'COMMENT',
body: comment.body
});
}
catch (errCreateComment) {
(0, core_1.info)(`Error creating PR review ${errCreateComment.message}`);
}
}
(0, core_1.info)(`comment created`);
(0, core_1.endGroup)();
}
(0, core_1.info)(`comment created`);
(0, core_1.endGroup)();
let shouldFailCheck = false;
let title = '';
let summary = '';
Expand Down
2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/checkoutAndInstallBaseBranch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@ export async function checkoutAndInstallBaseBranch({ installScript, payload, exe
startGroup(`[base branch] Install Dependencies`)
await exec(installScript, [], execOptions)
endGroup()
}
}
21 changes: 19 additions & 2 deletions src/getAndValidateArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ export const enum CHECK_FAIL_MODE {
ON_ERRORS_PRESENT_IN_PR = 'errors_in_pr',
ON_ERRORS_PRESENT_IN_CODE = 'errors_in_code'
}

export const enum OUTPUT_BEHAVIOUR {
COMMENT = 'comment',
ANNOTATE = 'annotate',
COMMENT_AND_ANNOTATE = 'both'
}

type Args = {
repoToken: string
directory: string
Expand Down Expand Up @@ -34,11 +41,12 @@ type Args = {
* 2
* ]
* }
* ]
* ]
*/
lineNumbers: { path: string, added: number[], removed: number[] }[]
useCheck: boolean
checkFailMode: CHECK_FAIL_MODE,
checkFailMode: CHECK_FAIL_MODE
outputBehaviour: OUTPUT_BEHAVIOUR
debug: boolean
}

Expand All @@ -53,6 +61,7 @@ export function getAndValidateArgs(): Args {
lineNumbers: JSON.parse(getInput('line-numbers')) ?? [],
useCheck: getBooleanInput('use-check'),
checkFailMode: getInput('check-fail-mode') as CHECK_FAIL_MODE,
outputBehaviour: getInput('output-behaviour') as OUTPUT_BEHAVIOUR,
debug: getBooleanInput('debug')
}

Expand All @@ -64,5 +73,13 @@ export function getAndValidateArgs(): Args {
throw new Error(`Invalid value ${args.checkFailMode} for input check-fail-mode`)
}

if (![
OUTPUT_BEHAVIOUR.COMMENT,
OUTPUT_BEHAVIOUR.ANNOTATE,
OUTPUT_BEHAVIOUR.COMMENT_AND_ANNOTATE
].includes(args.outputBehaviour)) {
throw new Error(`Invalid value ${args.outputBehaviour} for input output-behaviour`)
}

return args
}
96 changes: 54 additions & 42 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { info, startGroup, endGroup, setFailed } from '@actions/core'
import { info, startGroup, endGroup, error, setFailed } from '@actions/core'
import * as path from 'path'
import { context, getOctokit } from '@actions/github'
import { createCheck } from './createCheck'
import * as github from '@actions/github'
import * as fs from 'fs'
import { parseTsConfigFile } from './tscHelpers/parseTsConfigFileToCompilerOptions'
import { getAndValidateArgs, CHECK_FAIL_MODE } from './getAndValidateArgs'
import { getAndValidateArgs, CHECK_FAIL_MODE, OUTPUT_BEHAVIOUR } from './getAndValidateArgs'
import { exec } from '@actions/exec'
import { getBodyComment } from './getBodyComment'
import { checkoutAndInstallBaseBranch } from './checkoutAndInstallBaseBranch'
Expand All @@ -24,16 +24,15 @@ export type ErrorTs = {
/** for long error messages */
extraMsg?: string
}
interface PullRequest {
number: number;
html_url?: string
body?: string
changed_files: number
}

async function run(): Promise<void> {
try {
const args = getAndValidateArgs()

if (args.debug) {
info(`[config] args: \n${JSON.stringify(args)}`)
}

const workingDir = path.join(process.cwd(), args.directory)
info(`working directory: ${workingDir}`)

Expand Down Expand Up @@ -161,47 +160,60 @@ async function run(): Promise<void> {

endGroup()

startGroup(`Creating comment`)

const commentInfo = {
...context.repo,
issue_number: context.payload.pull_request!.number
}

const comment = {
...commentInfo,
body: getBodyComment({
errorsInProjectBefore: errorsBaseBranch,
errorsInProjectAfter: errorsPr,
newErrorsInProject: resultCompareErrors.errorsAdded,
errorsInModifiedFiles,
newErrorsInModifiedFiles
if ([OUTPUT_BEHAVIOUR.ANNOTATE, OUTPUT_BEHAVIOUR.COMMENT_AND_ANNOTATE].includes(args.outputBehaviour)) {
resultCompareErrors.errorsAdded.forEach(err => {
error(`${err.fileName}:${err.line}:${err.column} - ${err.message}`, {
file: err.fileName,
startLine: parseInt(err.line),
startColumn: parseInt(err.column),
title: err.extraMsg ?? err.message
})
})
}
info(`comment body obtained`)

try {
await octokit.rest.issues.createComment(comment)
} catch (e) {
info(`Error creating comment: ${(e as Error).message}`)
info(`Submitting a PR review comment instead...`)
try {
const issue = context.issue || pr
await octokit.rest.pulls.createReview({
owner: issue.owner,
repo: issue.repo,
pull_number: issue.number,
event: 'COMMENT',
body: comment.body
if ([OUTPUT_BEHAVIOUR.COMMENT, OUTPUT_BEHAVIOUR.COMMENT_AND_ANNOTATE].includes(args.outputBehaviour)) {
startGroup(`Creating comment`)

const commentInfo = {
...context.repo,
issue_number: context.payload.pull_request!.number
}

const comment = {
...commentInfo,
body: getBodyComment({
errorsInProjectBefore: errorsBaseBranch,
errorsInProjectAfter: errorsPr,
newErrorsInProject: resultCompareErrors.errorsAdded,
errorsInModifiedFiles,
newErrorsInModifiedFiles
})
} catch (errCreateComment) {
info(`Error creating PR review ${(errCreateComment as Error).message}`)
}
}
info(`comment body obtained`)

try {
await octokit.rest.issues.createComment(comment)
} catch (e) {
info(`Error creating comment: ${(e as Error).message}`)
info(`Submitting a PR review comment instead...`)
try {
const issue = context.issue || pr
await octokit.rest.pulls.createReview({
owner: issue.owner,
repo: issue.repo,
pull_number: issue.number,
event: 'COMMENT',
body: comment.body
})
} catch (errCreateComment) {
info(`Error creating PR review ${(errCreateComment as Error).message}`)
}
}

info(`comment created`)
info(`comment created`)

endGroup()
endGroup()
}

let shouldFailCheck = false
let title = ''
Expand Down