Skip to content

Commit

Permalink
issue-289 feature: add pr-number optional input (#293)
Browse files Browse the repository at this point in the history
* issue-289 feature: add pr-number optional input

* issue-289 feature: update shell env var

* issue-289 test: repair broken tests, add new case

* issue-289 test: fix tests, build new dist

* add debugging

* rebuild assets

* rebuild assets

* rebuild

* issue-289 fix: remove debugging code

* issue-289 fix: remove dead import

* issue-289 test|fix: address pr comments, add tests

* issue-289 docs: update README with prnumber section
  • Loading branch information
dalevfenton committed Jul 14, 2022
1 parent 52ffa37 commit 1c305f8
Show file tree
Hide file tree
Showing 17 changed files with 4,474 additions and 4,186 deletions.
31 changes: 31 additions & 0 deletions README.md
Expand Up @@ -191,6 +191,37 @@ Accepted values are:
- `coverage` - Will annotate those sections of your code that test did not cover
- `failed-tests` - Will annotate those sections of your code that failed test

## Pull Request Number

If you are using the `push` event to trigger this action, by default it does not know which PR to comment on or the base branch of the PR to compare code coverage with.

You can pass the `prnumber` to the action so that coverage change can be run and comments will be updated on each push, instead of creating a new comment with each run of the action.

You can find the PR number with a number of methods, the [jwalton/gh-find-current-pr](https://github.com/jwalton/gh-find-current-pr) action makes it easy:

```yml
name: 'coverage'
on:
push:
branches:
- master
- main
jobs:
coverage:
permissions:
checks: write
pull-requests: write
contents: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: jwalton/gh-find-current-pr@v1
id: findPr
- uses: ArtiomTr/jest-coverage-report-action@v2
with:
prnumber: ${{ steps.findPr.outputs.number }}
```

## Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Expand Up @@ -44,6 +44,9 @@ inputs:
base-coverage-file:
required: false
description: Path to the report.json file to compare against. This should be from the branch the PR is merging into.
prnumber:
required: false
description: Pull Request number for this commit. Use if your action is running in a PR, but non on the pull_request event, so that you do not get multiple comments.
runs:
using: composite
steps:
Expand All @@ -61,3 +64,4 @@ runs:
INPUT_CUSTOM-TITLE: ${{ inputs.custom-title }}
INPUT_COVERAGE-FILE: ${{ inputs.coverage-file }}
INPUT_BASE-COVERAGE-FILE: ${{ inputs.base-coverage-file }}
INPUT_PRNUMBER: ${{ inputs.prnumber }}
61 changes: 31 additions & 30 deletions dist/index.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions dist/index.js.map

Large diffs are not rendered by default.

8,255 changes: 4,126 additions & 4,129 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions src/format/annotations/formatCoverageAnnotations.ts
Expand Up @@ -2,14 +2,16 @@ import { context } from '@actions/github';

import { CreateCheckOptions } from './CreateCheckOptions';
import { Annotation } from '../../annotations/Annotation';
import { Options } from '../../typings/Options';
import { i18n } from '../../utils/i18n';

export const formatCoverageAnnotations = (
annotations: Array<Annotation>
annotations: Array<Annotation>,
options: Options
): CreateCheckOptions => ({
...context.repo,
status: 'completed',
head_sha: context.payload.pull_request?.head.sha ?? context.sha,
head_sha: options?.pullRequest?.head?.sha ?? context.sha,
conclusion: 'success',
name: i18n('coveredCheckName'),
output: {
Expand Down
6 changes: 4 additions & 2 deletions src/format/annotations/formatFailedTestsAnnotations.ts
Expand Up @@ -3,16 +3,18 @@ import { context } from '@actions/github';
import { CreateCheckOptions } from './CreateCheckOptions';
import { getFailedTestsAnnotationsBody } from './getFailedTestsAnnotationsBody';
import { Annotation } from '../../annotations/Annotation';
import { Options } from '../../typings/Options';
import { TestRunReport } from '../../typings/Report';
import { i18n } from '../../utils/i18n';

export const formatFailedTestsAnnotations = (
runReport: TestRunReport,
annotations: Array<Annotation>
annotations: Array<Annotation>,
options: Options
): CreateCheckOptions => ({
...context.repo,
status: 'completed',
head_sha: context.payload.pull_request?.head.sha ?? context.sha,
head_sha: options?.pullRequest?.head?.sha ?? context.sha,
conclusion: 'failure',
name: i18n('failedTestsCheckName'),
output: {
Expand Down
14 changes: 7 additions & 7 deletions src/run.ts
Expand Up @@ -21,13 +21,12 @@ import { runStage } from './utils/runStage';
export const run = async (
dataCollector = createDataCollector<JsonReport>()
) => {
const isInPR = context.eventName === 'pull_request';

const [isInitialized, options] = await runStage(
'initialize',
dataCollector,
getOptions
);
const isInPR = !!options?.pullRequest;

if (!isInitialized || !options) {
throw Error('Initialization failed.');
Expand Down Expand Up @@ -65,7 +64,7 @@ export const run = async (
'switchToBase',
dataCollector,
async (skip) => {
const baseBranch = context.payload.pull_request?.base.ref;
const baseBranch = options?.pullRequest?.base?.ref;

// no need to switch branch when:
// - this is not a PR
Expand All @@ -75,7 +74,7 @@ export const run = async (
skip();
}

await switchBranch(baseBranch);
await switchBranch(baseBranch as string);
}
);

Expand Down Expand Up @@ -147,7 +146,7 @@ export const run = async (
summaryReport!.text,
options,
context.repo,
context.payload.pull_request!,
options.pullRequest as { number: number },
octokit
);
} else {
Expand Down Expand Up @@ -177,7 +176,8 @@ export const run = async (
await octokit.checks.create(
formatFailedTestsAnnotations(
summaryReport!.runReport,
failedAnnotations
failedAnnotations,
options
)
);
});
Expand All @@ -198,7 +198,7 @@ export const run = async (

const octokit = getOctokit(options.token);
await octokit.checks.create(
formatCoverageAnnotations(coverageAnnotations)
formatCoverageAnnotations(coverageAnnotations, options)
);
});

Expand Down
28 changes: 26 additions & 2 deletions src/typings/Options.ts
@@ -1,4 +1,5 @@
import { getInput } from '@actions/core';
import { context, getOctokit } from '@actions/github';
import * as yup from 'yup';

import { icons } from '../format/strings.json';
Expand All @@ -8,7 +9,11 @@ export type IconType = keyof typeof icons;
export type AnnotationType = 'all' | 'none' | 'coverage' | 'failed-tests';
export type PackageManagerType = 'npm' | 'yarn' | 'pnpm';
export type SkipStepType = 'all' | 'none' | 'install';

export type PullRequest = {
base: { ref: string };
head: { ref: string; sha: string };
number: number;
};
export type Options = {
token: string;
testScript: string;
Expand All @@ -21,6 +26,8 @@ export type Options = {
customTitle?: string;
coverageFile?: string;
baseCoverageFile?: string;
prNumber: null | number;
pullRequest: null | PullRequest;
};

const validAnnotationOptions: Array<AnnotationType> = [
Expand Down Expand Up @@ -56,6 +63,8 @@ const optionSchema = yup.object().shape({
customTitle: yup.string(),
coverageFile: yup.string(),
baseCoverageFile: yup.string(),
prNumber: yup.number().nullable(),
pullRequest: yup.object().nullable(),
});

export const shouldInstallDeps = (skipStep: SkipStepType): Boolean =>
Expand All @@ -68,7 +77,7 @@ export const getOptions = async (): Promise<Options> => {
const token = getInput('github-token', {
required: true,
});

const octokit = getOctokit(token);
const testScript = getInput('test-script');
const threshold = getInput('threshold');
const workingDirectory = getInput('working-directory');
Expand All @@ -79,6 +88,19 @@ export const getOptions = async (): Promise<Options> => {
const customTitle = getInput('custom-title');
const coverageFile = getInput('coverage-file');
const baseCoverageFile = getInput('base-coverage-file');
const prNumber: number | null = Number(
getInput('prnumber') || context?.payload?.pull_request?.number
);
let pullRequest = context?.payload?.pull_request || null;

if (!pullRequest && !Number.isNaN(prNumber)) {
const { data: pr } = await octokit.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
});
pullRequest = pr as PullRequest;
}

try {
const options: Options = (await optionSchema.validate({
Expand All @@ -93,6 +115,8 @@ export const getOptions = async (): Promise<Options> => {
customTitle,
coverageFile,
baseCoverageFile,
prNumber: prNumber || null,
pullRequest,
})) as Options;

return options;
Expand Down
35 changes: 32 additions & 3 deletions tests/format/annotations/formatCoverageAnnotations.test.ts
Expand Up @@ -2,9 +2,25 @@ import * as all from '@actions/github';

import { Annotation } from '../../../src/annotations/Annotation';
import { formatCoverageAnnotations } from '../../../src/format/annotations/formatCoverageAnnotations';
import { Options } from '../../../src/typings/Options';

const { mockContext, clearContextMock } = all as any;

const DEFAULT_OPTIONS: Options = {
token: '',
testScript: '',
iconType: 'emoji',
annotations: 'all',
packageManager: 'npm',
skipStep: 'all',
prNumber: 5,
pullRequest: {
number: 5,
head: { sha: '123456', ref: '123' },
base: { ref: '456' },
},
};

const annotations: Annotation[] = [
{
start_line: 5,
Expand Down Expand Up @@ -62,7 +78,9 @@ describe('formatCoverageAnnotations', () => {
},
});

expect(formatCoverageAnnotations(annotations)).toMatchSnapshot();
expect(
formatCoverageAnnotations(annotations, DEFAULT_OPTIONS)
).toMatchSnapshot();
});

it('should format annotations for commit', () => {
Expand All @@ -71,7 +89,13 @@ describe('formatCoverageAnnotations', () => {
sha: '111111',
});

expect(formatCoverageAnnotations(annotations)).toMatchSnapshot();
expect(
formatCoverageAnnotations(annotations, {
...DEFAULT_OPTIONS,
prNumber: null,
pullRequest: null,
})
).toMatchSnapshot();
});

it('should leave only 50 annotations', () => {
Expand All @@ -84,7 +108,12 @@ describe('formatCoverageAnnotations', () => {
formatCoverageAnnotations(
new Array(52).fill(0).map(() => ({
...annotations[0],
}))
})),
{
...DEFAULT_OPTIONS,
prNumber: null,
pullRequest: null,
}
)
).toMatchSnapshot();
});
Expand Down
25 changes: 22 additions & 3 deletions tests/format/annotations/formatFailedTestsAnnotations.test.ts
Expand Up @@ -2,9 +2,25 @@ import * as all from '@actions/github';

import { Annotation } from '../../../src/annotations/Annotation';
import { formatFailedTestsAnnotations } from '../../../src/format/annotations/formatFailedTestsAnnotations';
import { Options } from '../../../src/typings/Options';

const { mockContext, clearContextMock } = all as any;

const DEFAULT_OPTIONS: Options = {
token: '',
testScript: '',
iconType: 'emoji',
annotations: 'all',
packageManager: 'npm',
skipStep: 'all',
prNumber: 5,
pullRequest: {
number: 5,
head: { sha: '987654', ref: '123' },
base: { ref: '456' },
},
};

const annotations: Annotation[] = [
{
annotation_level: 'failure',
Expand Down Expand Up @@ -49,7 +65,8 @@ describe('formatFailedTestsAnnotations', () => {
summary: 'Some summary',
failures: 'Failures',
},
annotations
annotations,
DEFAULT_OPTIONS
)
).toMatchSnapshot();
});
Expand All @@ -71,7 +88,8 @@ describe('formatFailedTestsAnnotations', () => {
summary: 'Some summary',
failures: 'Failures',
},
annotations
annotations,
{ ...DEFAULT_OPTIONS, prNumber: null, pullRequest: null }
)
).toMatchSnapshot();
});
Expand All @@ -93,7 +111,8 @@ describe('formatFailedTestsAnnotations', () => {
summary: 'Some summary',
failures: 'Failures',
},
new Array(53).fill(0).map(() => ({ ...annotations[0] }))
new Array(53).fill(0).map(() => ({ ...annotations[0] })),
{ ...DEFAULT_OPTIONS, prNumber: null, pullRequest: null }
)
).toMatchSnapshot();
});
Expand Down
6 changes: 6 additions & 0 deletions tests/report/fetchPreviousReport.test.ts
Expand Up @@ -11,6 +11,12 @@ const DEFAULT_OPTIONS: Options = {
annotations: 'all',
packageManager: 'npm',
skipStep: 'all',
prNumber: 5,
pullRequest: {
number: 5,
head: { sha: '123', ref: '123' },
base: { ref: '456' },
},
};

describe('fetchPreviousReport', () => {
Expand Down
6 changes: 6 additions & 0 deletions tests/report/generatePRReport.test.ts
Expand Up @@ -11,6 +11,12 @@ const DEFAULT_OPTIONS: Options = {
annotations: 'all',
packageManager: 'npm',
skipStep: 'all',
prNumber: 7,
pullRequest: {
number: 7,
head: { sha: '123456', ref: '123' },
base: { ref: '456' },
},
};

describe('generatePRReport', () => {
Expand Down

0 comments on commit 1c305f8

Please sign in to comment.