Skip to content

Commit

Permalink
feat: Allow passing Github title as arg to skip API request
Browse files Browse the repository at this point in the history
  • Loading branch information
benhodgson87 committed Aug 30, 2024
1 parent 14ff798 commit 4965e81
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 41 deletions.
36 changes: 31 additions & 5 deletions src/lint.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { setFailed, warning, error, info } from '@actions/core';
import { getOctokit } from '@actions/github';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { lint } from './lint';

Expand Down Expand Up @@ -49,22 +50,46 @@ vi.mock('@actions/github', async importOriginal => {
};
});

const mockArgs = ['TOKEN', './', './src/fixtures/commitlint.rules.js'];
const mockArgs = [
'TOKEN',
'./',
undefined,
'./src/fixtures/commitlint.rules.js'
];

describe('Linter', () => {
beforeEach(() => {
vi.clearAllMocks();
vi.restoreAllMocks();
});

it('should find and log the PR title', async () => {
it('should skip the API request if PR title provided as an arg and log the PR title', async () => {
mocks.getOctokit.mockImplementation(vi.fn());

const mockArgsWithManualTitle = [
...mockArgs.filter(arg => arg).slice(0, 2),
'chore(FOO-1234): hello i am a valid title passed manually',
...mockArgs
.filter(arg => arg)
.slice(2, mockArgs.filter(arg => arg).length)
];

await lint.apply(null, mockArgsWithManualTitle);

expect(getOctokit).not.toHaveBeenCalled();
expect(info).toHaveBeenCalledWith(
'🕵️ Found PR title in action args: "chore(FOO-1234): hello i am a valid title passed manually"'
);
});

it('should retrieve the pull request from the API if not passed as an arg and log the PR title', async () => {
mocks.getOctokit.mockReturnValue({
rest: {
pulls: {
get: vi.fn().mockReturnValue({
data: {
commits: 1,
title: 'feat(BAR-1234): hello i am a valid title'
title: 'feat(BAR-1234): hello i am a valid title from the API'
}
})
}
Expand All @@ -73,8 +98,9 @@ describe('Linter', () => {

await lint.apply(null, mockArgs);

expect(getOctokit).toHaveBeenCalledWith(mockArgs[0]);
expect(info).toHaveBeenCalledWith(
'🕵️ Found PR title: "feat(BAR-1234): hello i am a valid title"'
'🕵️ Found PR title from Github API: "feat(BAR-1234): hello i am a valid title from the API"'
);
});

Expand Down Expand Up @@ -129,7 +155,7 @@ describe('Linter', () => {

await lint.apply(
null,
mockArgs.filter(arg => arg !== mockArgs[1])
mockArgs.filter(arg => arg && !arg.includes('commitlint.rules.js'))
);

expect(info).toHaveBeenCalledWith('📋 Checking PR title with commitlint');
Expand Down
56 changes: 31 additions & 25 deletions src/lint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
logLintableScopeFound,
logLintingPrTitle,
logLintingPrTitleWithCustomRules,
logPrTitleFound,
logPrTitleFoundArg,
logPrTitleFoundApi,
logScopeCheckSkipped
} from './outputs/logs';
import {
Expand All @@ -32,6 +33,7 @@ import { errorLinting } from './outputs/errors';
const lint = async (
githubToken?: string,
githubWorkspace?: string,
prTitle?: string,
rulesPath?: string,
enforcedScopeTypes?: Array<string>,
scopeRegex?: RegExp
Expand All @@ -40,27 +42,35 @@ const lint = async (
return setFailedMissingToken();
}

const octokit = github.getOctokit(githubToken);
let pullRequestTitle = prTitle;

if (!github.context.payload.pull_request) {
return setFailedPrNotFound();
}
if (pullRequestTitle) {
logPrTitleFoundArg(pullRequestTitle);
} else {
const octokit = github.getOctokit(githubToken);

const {
number: pullNumber,
base: {
user: { login: owner },
repo: { name: repo }
if (!github.context.payload.pull_request) {
return setFailedPrNotFound();
}
} = github.context.payload.pull_request;

const { data: pullRequest } = await octokit.rest.pulls.get({
owner,
repo,
pull_number: pullNumber
});
const {
number: pullNumber,
base: {
user: { login: owner },
repo: { name: repo }
}
} = github.context.payload.pull_request;

logPrTitleFound(pullRequest.title);
const { data: pullRequest } = await octokit.rest.pulls.get({
owner,
repo,
pull_number: pullNumber
});

pullRequestTitle = pullRequest.title;

logPrTitleFoundApi(pullRequestTitle);
}

const commitlintRules = await getLintRules(rulesPath, githubWorkspace);

Expand All @@ -78,13 +88,9 @@ const lint = async (
conventionalChangelog: { parserOpts }
} = await createPreset(null, null);

const lintOutput = await commitlint(
pullRequest.title,
commitlintRules.rules,
{
parserOpts
}
);
const lintOutput = await commitlint(pullRequestTitle, commitlintRules.rules, {
parserOpts
});
lintOutput.warnings.forEach(warn => warnLinting(warn.message));
lintOutput.errors.forEach(err => errorLinting(err.message));

Expand All @@ -94,7 +100,7 @@ const lint = async (
return setFailedDoesNotMatchSpec();
}

const { scope, type } = conventionalCommitsParser.sync(pullRequest.title);
const { scope, type } = conventionalCommitsParser.sync(pullRequestTitle);

if (
!enforcedScopeTypes ||
Expand Down
5 changes: 3 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ try {
const {
githubToken,
githubWorkspace,
prTitle,
rulesPath,
enforcedScopeTypes,
scopeRegex
scopeRegex,
} = getActionConfig();

lint(githubToken, githubWorkspace, rulesPath, enforcedScopeTypes, scopeRegex);
lint(githubToken, githubWorkspace, prTitle, rulesPath, enforcedScopeTypes, scopeRegex);
} catch (e) {
core.setFailed(`Failed to run action with error: ${e}`);
}
16 changes: 12 additions & 4 deletions src/outputs/logs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
logLintableScopeFound,
logLintingPrTitle,
logLintingPrTitleWithCustomRules,
logPrTitleFound,
logPrTitleFoundArg,
logPrTitleFoundApi,
logScopeCheckSkipped
} from './logs';

Expand All @@ -24,10 +25,17 @@ describe('Log outputs', () => {
vi.resetAllMocks();
});

it('`logPrTitleFound` should pass the expected log to the output', () => {
logPrTitleFound(`fix(CDV-2812): Get with friends`);
it('`logPrTitleFoundArg` should pass the expected log to the output', () => {
logPrTitleFoundArg(`fix(CDV-2812): Get with friends`);
expect(info).toHaveBeenCalledWith(
`🕵️ Found PR title: "fix(CDV-2812): Get with friends"`
`🕵️ Found PR title in action args: "fix(CDV-2812): Get with friends"`
);
});

it('`logPrTitleFoundApi` should pass the expected log to the output', () => {
logPrTitleFoundApi(`fix(CDV-2812): Get with friends`);
expect(info).toHaveBeenCalledWith(
`🕵️ Found PR title from Github API: "fix(CDV-2812): Get with friends"`
);
});

Expand Down
7 changes: 5 additions & 2 deletions src/outputs/logs.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import * as core from '@actions/core';
import { Commit } from 'conventional-commits-parser';

export const logPrTitleFound = (title: string) =>
core.info(`🕵️ Found PR title: "${title}"`);
export const logPrTitleFoundArg = (title: string) =>
core.info(`🕵️ Found PR title in action args: "${title}"`);

export const logPrTitleFoundApi = (title: string) =>
core.info(`🕵️ Found PR title from Github API: "${title}"`);

export const logLintingPrTitle = () =>
core.info(`📋 Checking PR title with commitlint`);
Expand Down
22 changes: 19 additions & 3 deletions src/utils/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ describe('Config utils', () => {
process.env.INPUT_COMMITLINTRULESPATH = './commitlint.rules.js';
process.env.GITHUB_TOKEN = 'asdf';
process.env.GITHUB_WORKSPACE = './';
process.env.INPUT_PR_TITLE = 'chore(TEST-1234): Manually pass a PR title'
});

it('`getActionConfig` returns a valid config object with required values', () => {
const config = getActionConfig();
expect(config).toMatchObject({
rulesPath: expect.any(String),
githubToken: expect.any(String),
githubWorkspace: expect.any(String)
githubWorkspace: expect.any(String),
prTitle: expect.any(String)
});
});

Expand All @@ -27,7 +29,8 @@ describe('Config utils', () => {
enforcedScopeTypes: expect.any(Array),
rulesPath: expect.any(String),
githubToken: expect.any(String),
githubWorkspace: expect.any(String)
githubWorkspace: expect.any(String),
prTitle: expect.any(String)
});
expect(config.enforcedScopeTypes).toEqual(['feat', 'fix']);
});
Expand All @@ -40,7 +43,20 @@ describe('Config utils', () => {
scopeRegex: expect.any(RegExp),
rulesPath: expect.any(String),
githubToken: expect.any(String),
githubWorkspace: expect.any(String)
githubWorkspace: expect.any(String),
prTitle: expect.any(String)
});
});

it('`getActionConfig` returns a valid config object with `undefined` PR title if not provided', () => {
delete process.env.INPUT_PR_TITLE;

const config = getActionConfig();
expect(config).toMatchObject({
rulesPath: expect.any(String),
githubToken: expect.any(String),
githubWorkspace: expect.any(String),
prTitle: undefined
});
});
});
1 change: 1 addition & 0 deletions src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const getActionConfig = () => {
return {
githubToken: process.env.GITHUB_TOKEN,
githubWorkspace: process.env.GITHUB_WORKSPACE,
prTitle: process.env.INPUT_PR_TITLE,
rulesPath: process.env.INPUT_COMMITLINTRULESPATH,
...(enforcedScopeTypes ? { enforcedScopeTypes } : {}),
...(scopeRegex ? { scopeRegex } : {})
Expand Down

0 comments on commit 4965e81

Please sign in to comment.