From 98b7698a6bd3d4824d251f85dedcd18c410178e0 Mon Sep 17 00:00:00 2001 From: Mikael Andersson Date: Wed, 9 Nov 2022 18:56:15 +0100 Subject: [PATCH 1/3] fix: use event name to set isPrerelease on pull requests (#1) Use the GITHUB_EVENT_NAME environment variable to determine if the triggering event of the workflow was a pull request. --- src/action.ts | 12 +++++++++--- src/utils.ts | 4 ++-- tests/action.test.ts | 2 ++ tests/helper.test.ts | 4 ++++ tests/utils.test.ts | 6 +++--- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/action.ts b/src/action.ts index 2a073169e..6af5c1c27 100644 --- a/src/action.ts +++ b/src/action.ts @@ -38,13 +38,18 @@ export default async function main() { mappedReleaseRules = mapCustomReleaseRules(customReleaseRules); } - const { GITHUB_REF, GITHUB_SHA } = process.env; + const { GITHUB_REF, GITHUB_SHA, GITHUB_EVENT_NAME } = process.env; if (!GITHUB_REF) { core.setFailed('Missing GITHUB_REF.'); return; } + if (!GITHUB_EVENT_NAME) { + core.setFailed('Missing GITHUB_EVENT_NAME'); + return; + } + const commitRef = commitSha || GITHUB_SHA; if (!commitRef) { core.setFailed('Missing commit_sha or GITHUB_SHA.'); @@ -58,8 +63,9 @@ export default async function main() { const isPreReleaseBranch = preReleaseBranches .split(',') .some((branch) => currentBranch.match(branch)); - const isPullRequest = isPr(GITHUB_REF); - const isPrerelease = !isReleaseBranch && !isPullRequest && isPreReleaseBranch; + const isPullRequest = isPr(GITHUB_EVENT_NAME); + const isPrerelease = + !isReleaseBranch && (isPullRequest || isPreReleaseBranch); // Sanitize identifier according to // https://semver.org/#backusnaur-form-grammar-for-valid-semver-versions diff --git a/src/utils.ts b/src/utils.ts index 05b1247f3..be77901f0 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -49,8 +49,8 @@ export function getBranchFromRef(ref: string) { return ref.replace('refs/heads/', ''); } -export function isPr(ref: string) { - return ref.includes('refs/pull/'); +export function isPr(eventName: string) { + return eventName.includes('pull_request'); } export function getLatestTag( diff --git a/tests/action.test.ts b/tests/action.test.ts index 413e7bfae..26709341b 100644 --- a/tests/action.test.ts +++ b/tests/action.test.ts @@ -8,6 +8,7 @@ import { setCommitSha, setInput, setRepository, + setEventName, } from './helper.test'; jest.spyOn(core, 'debug').mockImplementation(() => {}); @@ -33,6 +34,7 @@ describe('github-tag-action', () => { jest.clearAllMocks(); setBranch('master'); setCommitSha('79e0ea271c26aa152beef77c3275ff7b8f8d8274'); + setEventName('push'); loadDefaultInputs(); }); diff --git a/tests/helper.test.ts b/tests/helper.test.ts index d56b50be5..99cf5feb1 100644 --- a/tests/helper.test.ts +++ b/tests/helper.test.ts @@ -18,6 +18,10 @@ export function setCommitSha(sha: string) { process.env['GITHUB_SHA'] = sha; } +export function setEventName(eventName: string) { + process.env['GITHUB_EVENT_NAME'] = eventName; +} + export function setInput(key: string, value: string) { process.env[`INPUT_${key.toUpperCase()}`] = value; } diff --git a/tests/utils.test.ts b/tests/utils.test.ts index 417d8791e..eb04d9385 100644 --- a/tests/utils.test.ts +++ b/tests/utils.test.ts @@ -27,16 +27,16 @@ describe('utils', () => { expect(branch).toEqual('master'); }); - it('test if ref is PR', () => { + it('test if triggering event is PR', () => { /* * Given */ - const remoteRef = 'refs/pull/123/merge'; + const eventName = 'pull_request'; /* * When */ - const isPullRequest = utils.isPr(remoteRef); + const isPullRequest = utils.isPr(eventName); /* * Then From 898bb8e58ad1c7ce6a1126a7f0118732d95b7ba9 Mon Sep 17 00:00:00 2001 From: Mikael Andersson Date: Wed, 9 Nov 2022 20:18:14 +0100 Subject: [PATCH 2/3] test: add test case for triggered on pull requests (#2) add test case to verify that tag does not get created on pull requests --- tests/action.test.ts | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/action.test.ts b/tests/action.test.ts index 26709341b..ffa81ceb2 100644 --- a/tests/action.test.ts +++ b/tests/action.test.ts @@ -224,6 +224,7 @@ describe('github-tag-action', () => { jest.clearAllMocks(); setBranch('release'); setInput('release_branches', 'release'); + setEventName('push'); }); it('does create patch tag', async () => { @@ -875,4 +876,46 @@ describe('github-tag-action', () => { expect(mockSetFailed).not.toBeCalled(); }); }); + + describe('pull requests', () => { + beforeEach(() => { + jest.clearAllMocks(); + setBranch('branch-with-my-first-feature'); + setEventName('pull_request'); + }); + + it('does not create tag on pull request', async () => { + /* + * Given + */ + const commits = [{ message: 'fix: this is my first fix', hash: null }]; + jest + .spyOn(utils, 'getCommits') + .mockImplementation(async (sha) => commits); + + const validTags = [ + { + name: 'v1.2.3', + commit: { sha: '012345', url: '' }, + zipball_url: '', + tarball_url: 'string', + node_id: 'string', + }, + ]; + jest + .spyOn(utils, 'getValidTags') + .mockImplementation(async () => validTags); + + /* + * When + */ + await action(); + + /* + * Then + */ + expect(mockCreateTag).not.toHaveBeenCalledWith(); + expect(mockSetFailed).not.toBeCalled(); + }); + }); }); From 151a6a09b735bfc3b1d60ca60dda691420b6b553 Mon Sep 17 00:00:00 2001 From: Mikael Andersson Date: Sun, 13 Nov 2022 20:39:38 +0100 Subject: [PATCH 3/3] refactor: move prerelease branch check to function (#3) * refactor: move prerelease branch check to function * refactor: move prerelease identifier to function Get commit sha as identifier on pr. Get identifier for prereleases * fix: create tag for pull requests with shortened commit sha * ci: update actions checkout to v3 --- .github/workflows/test.yml | 2 +- src/action.ts | 28 +++++++++++++++++++--------- src/utils.ts | 32 ++++++++++++++++++++++++++++++++ tests/action.test.ts | 12 +++++++++--- 4 files changed, 61 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f52760ca2..2243f24ce 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,7 +9,7 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - run: npm ci - run: npm run test - run: npm run check diff --git a/src/action.ts b/src/action.ts index 6af5c1c27..a1339e1bf 100644 --- a/src/action.ts +++ b/src/action.ts @@ -5,12 +5,14 @@ import { generateNotes } from '@semantic-release/release-notes-generator'; import { getBranchFromRef, isPr, + isPrereleaseBranch, getCommits, getLatestPrereleaseTag, getLatestTag, getValidTags, mapCustomReleaseRules, mergeWithDefaultChangelogRules, + getIdentifier, } from './utils'; import { createTag } from './github'; import { Await } from './ts'; @@ -60,18 +62,22 @@ export default async function main() { const isReleaseBranch = releaseBranches .split(',') .some((branch) => currentBranch.match(branch)); - const isPreReleaseBranch = preReleaseBranches - .split(',') - .some((branch) => currentBranch.match(branch)); + const isPreReleaseBranch = isPrereleaseBranch( + preReleaseBranches, + currentBranch + ); const isPullRequest = isPr(GITHUB_EVENT_NAME); - const isPrerelease = - !isReleaseBranch && (isPullRequest || isPreReleaseBranch); + const isPrerelease = !isReleaseBranch && !isPullRequest && isPreReleaseBranch; // Sanitize identifier according to // https://semver.org/#backusnaur-form-grammar-for-valid-semver-versions - const identifier = ( - appendToPreReleaseTag ? appendToPreReleaseTag : currentBranch - ).replace(/[^a-zA-Z0-9-]/g, '-'); + const identifier = getIdentifier( + appendToPreReleaseTag, + currentBranch, + isPullRequest, + isPrerelease, + commitRef + ); const prefixRegex = new RegExp(`^${tagPrefix}`); @@ -187,7 +193,11 @@ export default async function main() { return; } - newVersion = incrementedVersion; + if (isPullRequest) { + newVersion = `${incrementedVersion}-${identifier}`; + } else { + newVersion = incrementedVersion; + } } core.info(`New version is ${newVersion}.`); diff --git a/src/utils.ts b/src/utils.ts index be77901f0..614009bff 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -53,6 +53,18 @@ export function isPr(eventName: string) { return eventName.includes('pull_request'); } +export function isPrereleaseBranch( + preReleaseBranches: string, + currentBranch: string +) { + if (preReleaseBranches) { + return preReleaseBranches + .split(',') + .some((branch) => currentBranch.match(branch)); + } + return false; +} + export function getLatestTag( tags: Tags, prefixRegex: RegExp, @@ -139,3 +151,23 @@ export function mergeWithDefaultChangelogRules( return Object.values(mergedRules).filter((rule) => !!rule.section); } + +export function getIdentifier( + appendToPreReleaseTag: string, + currentBranch: string, + isPullRequest: boolean, + isPrerelease: boolean, + commitRef: string +): string { + // On prerelease: Sanitize identifier according to + // https://semver.org/#backusnaur-form-grammar-for-valid-semver-versions + let identifier: string; + if (isPullRequest) { + // On pull request, use commit SHA for identifier + return commitRef.slice(0, 7).replace(/[^a-zA-Z0-9-]/g, '-'); + } + identifier = ( + appendToPreReleaseTag ? appendToPreReleaseTag : currentBranch + ).replace(/[^a-zA-Z0-9-]/g, '-'); + return identifier; +} diff --git a/tests/action.test.ts b/tests/action.test.ts index ffa81ceb2..9e505a527 100644 --- a/tests/action.test.ts +++ b/tests/action.test.ts @@ -28,12 +28,13 @@ const mockSetOutput = jest .mockImplementation(() => {}); const mockSetFailed = jest.spyOn(core, 'setFailed'); +const commitSha = '79e0ea271c26aa152beef77c3275ff7b8f8d8274'; describe('github-tag-action', () => { beforeEach(() => { jest.clearAllMocks(); setBranch('master'); - setCommitSha('79e0ea271c26aa152beef77c3275ff7b8f8d8274'); + setCommitSha(commitSha); setEventName('push'); loadDefaultInputs(); }); @@ -487,6 +488,7 @@ describe('github-tag-action', () => { /* * Then */ + expect(mockCreateTag).not.toBeCalled(); expect(mockSetFailed).not.toBeCalled(); }); @@ -880,11 +882,11 @@ describe('github-tag-action', () => { describe('pull requests', () => { beforeEach(() => { jest.clearAllMocks(); - setBranch('branch-with-my-first-feature'); + setBranch('branch-with-my-first-fix'); setEventName('pull_request'); }); - it('does not create tag on pull request', async () => { + it('does create new version with commit sha suffix on pull request', async () => { /* * Given */ @@ -914,6 +916,10 @@ describe('github-tag-action', () => { /* * Then */ + expect(mockSetOutput).toHaveBeenCalledWith( + 'new_version', + `1.2.4-${commitSha.slice(0, 7)}` + ); expect(mockCreateTag).not.toHaveBeenCalledWith(); expect(mockSetFailed).not.toBeCalled(); });