Skip to content

Commit

Permalink
feat: Allows multiple selections for the comment-on option
Browse files Browse the repository at this point in the history
  • Loading branch information
davelosert committed Sep 1, 2024
1 parent a7a72ad commit e5edf3b
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 53 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,4 @@ jobs:
with:
file-coverage-mode: "all"
json-summary-compare-path: coverage-main/coverage-summary.json
comment-on: 'commit'
comment-on: 'pr,commit'
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,18 @@ This action requires the `pull-request: write` permission to add a comment to yo

### Options

| Option | Description | Default |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `working-directory` | The main path to search for coverage- and configuration files (adjusting this is especially useful in monorepos). | `./` |
| `json-summary-path` | The path to the json summary file. | `${working-directory}/coverage/coverage-summary.json` |
| `json-final-path` | The path to the json final file. | `${working-directory}/coverage/coverage-final.json` |
| `vite-config-path` | The path to the vite config file. Will check the same paths as vite and vitest | Checks pattern `${working-directory}/vite[st].{config | workspace}.{t\|mt\|ct\|j\|mj\|cj}s` |
| `github-token` | A GitHub access token with permissions to write to issues (defaults to `secrets.GITHUB_TOKEN`). | `${{ github.token }}` |
| `file-coverage-mode` | Defines how file-based coverage is reported. Possible values are `all`, `changes` or `none`. | `changes` |
| `name` | Give the report a custom name. This is useful if you want multiple reports for different test suites within the same PR. Needs to be unique. | '' |
| `json-summary-compare-path` | The path to the json summary file to compare against. If given, will display a trend indicator and the difference in the summary. Respects the `working-directory` option. | undefined |
| `pr-number` | The number of the PR to post a comment to (if any) | If in the context of a PR, the number of that PR.<br/> If in the context of a triggered workflow, the PR of the triggering workflow. <br/>If no PR context is found, it defaults to `undefined` |
| `comment-on` | Select whether you want a comment to appear on a pull-request (if it exists) or on the commit in which context the action was ran. | `pr` |
| Option | Description | Default |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `working-directory` | The main path to search for coverage- and configuration files (adjusting this is especially useful in monorepos). | `./` |
| `json-summary-path` | The path to the json summary file. | `${working-directory}/coverage/coverage-summary.json` |
| `json-final-path` | The path to the json final file. | `${working-directory}/coverage/coverage-final.json` |
| `vite-config-path` | The path to the vite config file. Will check the same paths as vite and vitest | Checks pattern `${working-directory}/vite[st].{config | workspace}.{t\|mt\|ct\|j\|mj\|cj}s` |
| `github-token` | A GitHub access token with permissions to write to issues (defaults to `secrets.GITHUB_TOKEN`). | `${{ github.token }}` |
| `file-coverage-mode` | Defines how file-based coverage is reported. Possible values are `all`, `changes` or `none`. | `changes` |
| `name` | Give the report a custom name. This is useful if you want multiple reports for different test suites within the same PR. Needs to be unique. | '' |
| `json-summary-compare-path` | The path to the json summary file to compare against. If given, will display a trend indicator and the difference in the summary. Respects the `working-directory` option. | undefined |
| `pr-number` | The number of the PR to post a comment to (if any) | If in the context of a PR, the number of that PR.<br/> If in the context of a triggered workflow, the PR of the triggering workflow. <br/>If no PR context is found, it defaults to `undefined` |
| `comment-on` | Specify where you want a comment to appear: "pr" for pull-request (if one can be found), "commit" for the commit in which context the action was run, or "none" for no comments. You can provide a comma-separated list of "pr" and "commit" to comment on both. | `pr` |

#### File Coverage Mode

Expand Down
2 changes: 1 addition & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ inputs:
default: ''
comment-on:
required: false
description: 'Select wether you want a comment to appear on the PR (if it exists) or on the commit. Uses "pr" by default.'
description: 'Specify where you want a comment to appear: "pr" for pull-request (if one can be found), "commit" for the commit in which context the action was run, or "none" for no comments. You can provide a comma-separated list of "pr" and "commit" to comment on both. Uses "pr" by default.'
default: pr
runs:
using: 'node20'
Expand Down
87 changes: 57 additions & 30 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@ import * as github from "@actions/github";
import { RequestError } from "@octokit/request-error";
import { FileCoverageMode } from "./inputs/FileCoverageMode.js";
import { getPullChanges } from "./inputs/getPullChanges.js";
import { readOptions } from "./inputs/options.js";
import { type Options, readOptions } from "./inputs/options.js";
import {
parseVitestJsonFinal,
parseVitestJsonSummary,
} from "./inputs/parseJsonReports.js";
import { createOctokit } from "./octokit.js";
import { createOctokit, type Octokit } from "./octokit.js";
import { generateCommitSHAUrl } from "./report/generateCommitSHAUrl.js";
import { generateFileCoverageHtml } from "./report/generateFileCoverageHtml.js";
import { generateHeadline } from "./report/generateHeadline.js";
import { generateSummaryTableHtml } from "./report/generateSummaryTableHtml.js";
import type { JsonSummary } from "./types/JsonSummary.js";
import { writeSummaryToCommit } from "./writeSummaryToComment.js";
import { writeSummaryToPR } from "./writeSummaryToPR.js";
import { aw } from "vitest/dist/chunks/reporters.C_zwCd4j.js";

type GitHubSummary = typeof core.summary;

const run = async () => {
const octokit = createOctokit();
Expand Down Expand Up @@ -72,48 +75,72 @@ const run = async () => {
`<em>Generated in workflow <a href=${getWorkflowSummaryURL()}>#${github.context.runNumber}</a> for commit <a href="${commitSHAUrl}">${options.commitSHA.substring(0, 7)}</a> by the <a href="https://github.com/davelosert/vitest-coverage-report-action">Vitest Coverage Report Action</a></em>`,
);

if (options.commentOn.includes("pr")) {
await commentOnPR(octokit, summary, options);
}

if (options.commentOn.includes("commit")) {
await commentOnCommit(octokit, summary, options);
}

await summary.write();
};

async function commentOnPR(
octokit: Octokit,
summary: GitHubSummary,
options: Options,
) {
try {
if (options.commentOn === "pr") {
await writeSummaryToPR({
octokit,
summary,
markerPostfix: getMarkerPostfix({
name: options.name,
workingDirectory: options.workingDirectory,
}),
prNumber: options.prNumber,
});
await writeSummaryToPR({
octokit,
summary,
markerPostfix: getMarkerPostfix({
name: options.name,
workingDirectory: options.workingDirectory,
}),
prNumber: options.prNumber,
});
} catch (error) {
if (
error instanceof RequestError &&
(error.status === 404 || error.status === 403)
) {
core.warning(
`Couldn't write a comment to the pull request. Please make sure your job has the permission 'pull-request: write'.
Original Error was: [${error.name}] - ${error.message}`,
);
} else {
throw error;
}
}
}

if (options.commentOn === "commit") {
await writeSummaryToCommit({
octokit,
summary,
commitSha: options.commitSHA,
});
}
async function commentOnCommit(
octokit: Octokit,
summary: GitHubSummary,
options: Options,
) {
try {
await writeSummaryToCommit({
octokit,
summary,
commitSha: options.commitSHA,
});
} catch (error) {
if (
error instanceof RequestError &&
(error.status === 404 || error.status === 403)
) {
const item = options.commentOn === "pr" ? "pull request" : "commit";
const requiredPermission =
options.commentOn === "pr" ? "pull-request: write" : "contents: read";

core.warning(
`Couldn't write a comment to the ${item}. Please make sure your job has the permission '${requiredPermission}'.
Original Error was: [${error.name}] - ${error.message}
`,
`Couldn't write a comment to the commit. Please make sure your job has the permission 'contents: read'.
Original Error was: [${error.name}] - ${error.message}`,
);
} else {
// Rethrow to handle it in the catch block of the run()-call.
throw error;
}
}

await summary.write();
};
}

function getMarkerPostfix({
name,
Expand Down
73 changes: 73 additions & 0 deletions src/inputs/getCommentOn.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import * as core from "@actions/core";
import { getCommentOn, type CommentOn } from "./getCommentOn";

vi.mock("@actions/core");

describe("getCommentOn()", () => {
beforeEach(() => {
vi.clearAllMocks();
});

afterEach(() => {
vi.clearAllMocks();
});

it("returns the default value ['pr'] if no valid values are provided", () => {
vi.spyOn(core, "getInput").mockReturnValue("invalid1, invalid2");

const result = getCommentOn();
expect(result).toEqual(["pr"]);
expect(core.warning).toHaveBeenCalledWith(
'No valid options for comment-on found. Falling back to default value "pr".',
);
});

it("logs invalid values", () => {
vi.spyOn(core, "getInput").mockReturnValue("pr, invalid, commit");

const result = getCommentOn();
expect(result).toEqual(["pr", "commit"]);
expect(core.warning).toHaveBeenCalledWith(
'Invalid options for comment-on: invalid. Valid options are "pr" and "commit".',
);
});

it("returns valid values correctly", () => {
vi.spyOn(core, "getInput").mockReturnValue("pr, commit");

const result = getCommentOn();
expect(result).toEqual(["pr", "commit"]);
expect(core.warning).not.toHaveBeenCalled();
});

it("trims whitespace from the input", () => {
vi.spyOn(core, "getInput").mockReturnValue("pr, commit");

const result = getCommentOn();

expect(result).toEqual(["pr", "commit"]);

expect(core.warning).not.toHaveBeenCalled();
});

it("returns valid values and logs invalid values", () => {
vi.spyOn(core, "getInput").mockReturnValue(
"pr, invalid, commit, anotherInvalid",
);

const result = getCommentOn();
expect(result).toEqual(["pr", "commit"]);
expect(core.warning).toHaveBeenCalledWith(
'Invalid options for comment-on: invalid, anotherInvalid. Valid options are "pr" and "commit".',
);
});

it("for value 'none', returns empty array", () => {
vi.spyOn(core, "getInput").mockReturnValue("none");

const result = getCommentOn();

expect(result).toEqual([]);
});
});
Loading

1 comment on commit e5edf3b

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 67.26%
⬇️ -1.63%
524 / 779
🔵 Statements 67.26%
⬇️ -1.63%
524 / 779
🔵 Functions 86.66%
⬆️ +0.95%
26 / 30
🔵 Branches 94.4%
⬆️ +0.77%
118 / 125
File Coverage
File Stmts % Branch % Funcs % Lines Uncovered Lines
Changed Files
src/index.ts 0% 0% 0% 0% 1-6, 10-15, 17-18, 23-24, 26-27, 29, 31-36, 38-52, 54-59, 61-70, 72, 74-76, 78-80, 82-84, 86-87, 89-117, 119-143, 145-152, 154-158, 160-166
src/writeSummaryToComment.ts 100% 100% 100% 100%
src/inputs/getCommentOn.ts 100% 100% 100% 100%
src/inputs/options.ts 0% 0% 0% 0% 1-2, 5-10, 25, 27, 29-30, 32-35, 37-40, 42-49, 51, 53, 56-59, 61-63, 65, 67, 69-81
Unchanged Files
src/icons.ts 100% 100% 100% 100%
src/octokit.ts 0% 0% 0% 0% 1-2, 6-9
src/writeSummaryToPR.ts 100% 100% 100% 100%
src/inputs/FileCoverageMode.ts 100% 100% 100% 100%
src/inputs/getCommitSHA.ts 100% 100% 100% 100%
src/inputs/getPullChanges.ts 80.39% 85.71% 100% 80.39% 53-61, 63
src/inputs/getPullRequestNumber.ts 92.06% 90% 100% 92.06% 73-77
src/inputs/getViteConfigPath.ts 97.95% 87.5% 100% 97.95% 47
src/inputs/parseCoverageThresholds.ts 100% 100% 100% 100%
src/inputs/parseJsonReports.ts 0% 0% 0% 0% 1-4, 8-14, 16-24, 28-29, 32-34, 36-44, 48-52
src/report/generateCommitSHAUrl.ts 100% 100% 100% 100%
src/report/generateFileCoverageHtml.ts 100% 100% 100% 100%
src/report/generateFileUrl.ts 100% 100% 100% 100%
src/report/generateHeadline.ts 100% 100% 100% 100%
src/report/generateSummaryTableHtml.ts 100% 100% 100% 100%
src/report/getUncoveredLinesFromStatements.ts 100% 100% 100% 100%
Generated in workflow #725 for commit e5edf3b by the Vitest Coverage Report Action

Please sign in to comment.