Skip to content

Commit

Permalink
Add option to configure commenting strategy (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
Wise-StenRaudmets committed Jan 29, 2024
1 parent f0ac7cf commit be9d6e4
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 90 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ Add the following step to a workflow which runs on a [pull_request](https://docs
with:
# Optional, specifies where to look for .next folder. Defaults to cwd.
working-directory: ./apps/my-next-app
# Optional, configures commenting strategy around insignificant changes, defaults to `always`.
# Available options:
# always: Always comment on PRs, even if it's just to say there are no significant changes.
# skip-insignificant: Skip commenting on PRs if there are no signficant changes in page sizes.
comment-strategy: 'always'
# Optional, defaults to `github.token`.
github-token: ${{ github.token }}
```
Expand Down
9 changes: 9 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ inputs:
description: 'Directory containing built files'
required: false
default: ''
comment-strategy:
description: >
The desired behavior for commenting on Pull Requests.
Available options:
always: Always comment on PRs, even if it's just to say there are no significant changes.
skip-insignificant: Skip commenting on PRs if there are no signficant changes in page sizes.
required: false
default: 'always'
github-token:
description: 'The GitHub token used to authenticate with the GitHub API.'
required: false
Expand Down
84 changes: 51 additions & 33 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -127772,9 +127772,16 @@ function loadBuildManifest(workingDir) {
const file = external_fs_default().readFileSync(external_path_default().join(process.cwd(), workingDir, '.next', 'build-manifest.json'), 'utf-8');
return JSON.parse(file);
}
function getMarkdownTable(referenceBundleSizes = [], bundleSizes, name = 'Route') {
function getSingleColumnMarkdownTable({ bundleSizes, name, }) {
const rows = getPageChangeInfo([], bundleSizes);
return formatTableNoDiff(name, rows);
}
/**
* @returns a Markdown table of changes or null if there are no significant changes.
*/
function getComparisonMarkdownTable({ referenceBundleSizes, actualBundleSizes, name, }) {
// Produce a Markdown table with each page, its size and difference to default branch
const rows = getPageChangeInfo(referenceBundleSizes, bundleSizes);
const rows = getPageChangeInfo(referenceBundleSizes, actualBundleSizes);
if (rows.length === 0) {
return `${name}: None found.`;
}
Expand All @@ -127786,12 +127793,7 @@ function getMarkdownTable(referenceBundleSizes = [], bundleSizes, name = 'Route'
if (significant.length > 0) {
return formatTable(name, significant);
}
return `${name}: No significant changes found`;
}
function getBundleComparisonInfo({ referenceSha, referenceBundleSizes, actualBundleSizes, }) {
const info = `Compared against ${referenceSha}`;
const routesTable = getMarkdownTable(referenceBundleSizes, actualBundleSizes, 'Route');
return { info, routesTable };
return null;
}
function getPageChangeInfo(referenceBundleSizes, bundleSizes) {
const addedAndChanged = bundleSizes.map(({ page, size }) => {
Expand Down Expand Up @@ -127881,29 +127883,26 @@ function createContentByDelimiter({ title, content, delimiterIdentifier, }) {
;// CONCATENATED MODULE: ./src/comments.ts



const FALLBACK_COMPARISON_TEXT = 'No significant changes found';
async function findCommentByTextMatch({ octokit, issueNumber, text, }) {
const { data: comments } = await octokit.rest.issues.listComments(Object.assign(Object.assign({}, github.context.repo), { issue_number: issueNumber }));
return comments.find((comment) => { var _a; return (_a = comment.body) === null || _a === void 0 ? void 0 : _a.includes(text); });
}
async function createOrReplaceComment({ octokit, issueNumber, appName, referenceSha, referenceBundleSizes, actualBundleSizes, }) {
const title = `### Bundle sizes [${appName}]`;
const { info, routesTable } = getBundleComparisonInfo({
referenceSha,
referenceBundleSizes,
actualBundleSizes,
});
const body = formatTextFragments(title, info, routesTable);
async function createOrReplaceComment({ octokit, issueNumber, title, shaInfo, routesTable, strategy, }) {
const existingComment = await findCommentByTextMatch({
octokit,
issueNumber,
text: title,
});
const body = formatTextFragments(title, shaInfo, routesTable !== null && routesTable !== void 0 ? routesTable : FALLBACK_COMPARISON_TEXT);
if (existingComment) {
console.log(`Updating comment ${existingComment.id}`);
const response = await octokit.rest.issues.updateComment(Object.assign(Object.assign({}, github.context.repo), { comment_id: existingComment.id, body }));
console.log(`Done with status ${response.status}`);
}
else if (!existingComment && !routesTable && strategy === 'skip-insignificant') {
console.log(`Skipping comment [${title}]: no significant changes`);
}
else {
console.log(`Creating comment on PR ${issueNumber}`);
const response = await octokit.rest.issues.createComment(Object.assign(Object.assign({}, github.context.repo), { issue_number: issueNumber, body }));
Expand Down Expand Up @@ -127998,16 +127997,27 @@ async function downloadArtifactAsJson(octokit, branch, artifactName, fileName) {
}
}

;// CONCATENATED MODULE: ./src/issue.ts
;// CONCATENATED MODULE: ./src/input-helper.ts

function getInputs() {
const workingDirectory = core.getInput('working-directory');
const commentStrategy = core.getInput('comment-strategy');
const githubToken = core.getInput('github-token');
const inputs = {
workingDirectory,
commentStrategy: commentStrategy === 'skip-insignificant' ? 'skip-insignificant' : 'always',
githubToken,
};
return inputs;
}

;// CONCATENATED MODULE: ./src/issue.ts

async function findIssueByTitleMatch({ octokit, title }) {
const { data: issues } = await octokit.rest.issues.listForRepo(github.context.repo);
return issues.find((issue) => issue.title === title);
}
async function createOrReplaceIssue({ octokit, appName, actualBundleSizes, }) {
const title = `Bundle sizes [${appName}]`;
const routesTable = getMarkdownTable([], actualBundleSizes, 'Route');
async function createOrReplaceIssue({ octokit, title, routesTable, }) {
const existingIssue = await findIssueByTitleMatch({ octokit, title });
if (existingIssue) {
console.log(`Updating issue ${existingIssue.number} with latest bundle sizes`);
Expand Down Expand Up @@ -128048,43 +128058,51 @@ async function uploadJsonAsArtifact(artifactName, fileName, data) {




const ARTIFACT_NAME_PREFIX = 'next-bundle-analyzer__';
const FILE_NAME = 'bundle-sizes.json';
async function run() {
var _a;
try {
const workingDir = core.getInput('working-directory');
const token = core.getInput('github-token');
const appName = determineAppName(workingDir);
const inputs = getInputs();
const appName = determineAppName(inputs.workingDirectory);
const artifactName = `${ARTIFACT_NAME_PREFIX}${appName}`;
const octokit = (0,github.getOctokit)(token);
const octokit = (0,github.getOctokit)(inputs.githubToken);
const { data: { default_branch }, } = await octokit.rest.repos.get(github.context.repo);
const issueNumber = (_a = github.context.payload.pull_request) === null || _a === void 0 ? void 0 : _a.number;
console.log(`> Downloading bundle sizes from ${default_branch}`);
const referenceBundleSizes = (await downloadArtifactAsJson(octokit, default_branch, artifactName, FILE_NAME)) || { sha: 'none', data: [] };
console.log(referenceBundleSizes);
console.log('> Calculating local bundle sizes');
const bundleSizes = getStaticBundleSizes(workingDir);
const bundleSizes = getStaticBundleSizes(inputs.workingDirectory);
console.log(bundleSizes);
console.log('> Uploading local bundle sizes');
await uploadJsonAsArtifact(artifactName, FILE_NAME, bundleSizes);
if (issueNumber) {
console.log('> Commenting on PR');
const title = `### Bundle sizes [${appName}]`;
const shaInfo = `Compared against ${referenceBundleSizes.sha}`;
const routesTable = getComparisonMarkdownTable({
referenceBundleSizes: referenceBundleSizes.data,
actualBundleSizes: bundleSizes,
name: 'Route',
});
createOrReplaceComment({
octokit,
issueNumber,
appName,
referenceSha: referenceBundleSizes.sha,
referenceBundleSizes: referenceBundleSizes.data,
actualBundleSizes: bundleSizes,
title,
shaInfo,
routesTable,
strategy: inputs.commentStrategy,
});
}
else if (github.context.ref === `refs/heads/${default_branch}`) {
console.log('> Creating/updating bundle size issue');
const title = `Bundle sizes [${appName}]`;
const routesTable = getSingleColumnMarkdownTable({ bundleSizes, name: 'Route' });
createOrReplaceIssue({
octokit,
appName,
actualBundleSizes: bundleSizes,
title,
routesTable,
});
}
}
Expand Down
46 changes: 25 additions & 21 deletions src/bundle-size.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,31 @@ function loadBuildManifest(workingDir: string): BuildManifest {
return JSON.parse(file);
}

export function getMarkdownTable(
referenceBundleSizes: PageBundleSizes = [],
bundleSizes: PageBundleSizes,
name: string = 'Route',
): string {
export function getSingleColumnMarkdownTable({
bundleSizes,
name,
}: {
bundleSizes: PageBundleSizes;
name: string;
}): string {
const rows = getPageChangeInfo([], bundleSizes);
return formatTableNoDiff(name, rows);
}

/**
* @returns a Markdown table of changes or null if there are no significant changes.
*/
export function getComparisonMarkdownTable({
referenceBundleSizes,
actualBundleSizes,
name,
}: {
referenceBundleSizes: PageBundleSizes;
actualBundleSizes: PageBundleSizes;
name: string;
}): string | null {
// Produce a Markdown table with each page, its size and difference to default branch
const rows = getPageChangeInfo(referenceBundleSizes, bundleSizes);
const rows = getPageChangeInfo(referenceBundleSizes, actualBundleSizes);
if (rows.length === 0) {
return `${name}: None found.`;
}
Expand All @@ -57,21 +75,7 @@ export function getMarkdownTable(
if (significant.length > 0) {
return formatTable(name, significant);
}
return `${name}: No significant changes found`;
}

export function getBundleComparisonInfo({
referenceSha,
referenceBundleSizes,
actualBundleSizes,
}: {
referenceSha: string;
referenceBundleSizes: PageBundleSizes;
actualBundleSizes: PageBundleSizes;
}) {
const info = `Compared against ${referenceSha}`;
const routesTable = getMarkdownTable(referenceBundleSizes, actualBundleSizes, 'Route');
return { info, routesTable };
return null;
}

type PageChangeInfo = {
Expand Down
31 changes: 15 additions & 16 deletions src/comments.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { context } from '@actions/github';

import { PageBundleSizes, getBundleComparisonInfo } from './bundle-size';
import { formatTextFragments } from './text-format';
import type { Octokit } from './types';
import { ActionInputs } from './input-helper';

const FALLBACK_COMPARISON_TEXT = 'No significant changes found';

async function findCommentByTextMatch({
octokit,
Expand All @@ -23,31 +25,26 @@ async function findCommentByTextMatch({
export async function createOrReplaceComment({
octokit,
issueNumber,
appName,
referenceSha,
referenceBundleSizes,
actualBundleSizes,
title,
shaInfo,
routesTable,
strategy,
}: {
octokit: Octokit;
issueNumber: number;
appName: string;
referenceSha: string;
referenceBundleSizes: PageBundleSizes;
actualBundleSizes: PageBundleSizes;
title: string;
shaInfo: string;
routesTable: string | null;
strategy: ActionInputs['commentStrategy'];
}): Promise<void> {
const title = `### Bundle sizes [${appName}]`;
const { info, routesTable } = getBundleComparisonInfo({
referenceSha,
referenceBundleSizes,
actualBundleSizes,
});
const body = formatTextFragments(title, info, routesTable);
const existingComment = await findCommentByTextMatch({
octokit,
issueNumber,
text: title,
});

const body = formatTextFragments(title, shaInfo, routesTable ?? FALLBACK_COMPARISON_TEXT);

if (existingComment) {
console.log(`Updating comment ${existingComment.id}`);
const response = await octokit.rest.issues.updateComment({
Expand All @@ -56,6 +53,8 @@ export async function createOrReplaceComment({
body,
});
console.log(`Done with status ${response.status}`);
} else if (!existingComment && !routesTable && strategy === 'skip-insignificant') {
console.log(`Skipping comment [${title}]: no significant changes`);
} else {
console.log(`Creating comment on PR ${issueNumber}`);
const response = await octokit.rest.issues.createComment({
Expand Down
38 changes: 25 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import * as core from '@actions/core';
import { context, getOctokit } from '@actions/github';
import { getStaticBundleSizes } from './bundle-size';
import {
getComparisonMarkdownTable,
getSingleColumnMarkdownTable,
getStaticBundleSizes,
} from './bundle-size';

import { createOrReplaceComment } from './comments';
import { determineAppName } from './determine-app-name';
import { downloadArtifactAsJson } from './download-artifacts';
import { getInputs } from './input-helper';
import { createOrReplaceIssue } from './issue';
import { uploadJsonAsArtifact } from './upload-artifacts';

Expand All @@ -13,12 +18,11 @@ const FILE_NAME = 'bundle-sizes.json';

async function run() {
try {
const workingDir = core.getInput('working-directory');
const token = core.getInput('github-token');
const appName = determineAppName(workingDir);
const inputs = getInputs();
const appName = determineAppName(inputs.workingDirectory);
const artifactName = `${ARTIFACT_NAME_PREFIX}${appName}`;

const octokit = getOctokit(token);
const octokit = getOctokit(inputs.githubToken);

const {
data: { default_branch },
Expand All @@ -36,28 +40,36 @@ async function run() {
console.log(referenceBundleSizes);

console.log('> Calculating local bundle sizes');
const bundleSizes = getStaticBundleSizes(workingDir);
const bundleSizes = getStaticBundleSizes(inputs.workingDirectory);
console.log(bundleSizes);

console.log('> Uploading local bundle sizes');
await uploadJsonAsArtifact(artifactName, FILE_NAME, bundleSizes);

if (issueNumber) {
console.log('> Commenting on PR');
const title = `### Bundle sizes [${appName}]`;
const shaInfo = `Compared against ${referenceBundleSizes.sha}`;
const routesTable = getComparisonMarkdownTable({
referenceBundleSizes: referenceBundleSizes.data,
actualBundleSizes: bundleSizes,
name: 'Route',
});
createOrReplaceComment({
octokit,
issueNumber,
appName,
referenceSha: referenceBundleSizes.sha,
referenceBundleSizes: referenceBundleSizes.data,
actualBundleSizes: bundleSizes,
title,
shaInfo,
routesTable,
strategy: inputs.commentStrategy,
});
} else if (context.ref === `refs/heads/${default_branch}`) {
console.log('> Creating/updating bundle size issue');
const title = `Bundle sizes [${appName}]`;
const routesTable = getSingleColumnMarkdownTable({ bundleSizes, name: 'Route' });
createOrReplaceIssue({
octokit,
appName,
actualBundleSizes: bundleSizes,
title,
routesTable,
});
}
} catch (e) {
Expand Down
Loading

0 comments on commit be9d6e4

Please sign in to comment.