Skip to content
This repository has been archived by the owner on May 21, 2021. It is now read-only.

Commit

Permalink
Validate new version in action.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
rekmarks committed May 12, 2021
1 parent 86ec0ec commit 38d3eef
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 7 deletions.
25 changes: 25 additions & 0 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7343,6 +7343,9 @@ var inc_default = /*#__PURE__*/__nccwpck_require__.n(inc);
// EXTERNAL MODULE: ./node_modules/semver/functions/diff.js
var diff = __nccwpck_require__(4297);
var diff_default = /*#__PURE__*/__nccwpck_require__.n(diff);
// EXTERNAL MODULE: ./node_modules/semver/functions/gt.js
var gt = __nccwpck_require__(4123);
var gt_default = /*#__PURE__*/__nccwpck_require__.n(gt);
// EXTERNAL MODULE: external "path"
var external_path_ = __nccwpck_require__(5622);
var external_path_default = /*#__PURE__*/__nccwpck_require__.n(external_path_);
Expand Down Expand Up @@ -7988,6 +7991,7 @@ function getTruncatedPath(absolutePath) {




/**
* Action entry function. Gets git tags, reads the work space root package.json,
* and updates the package(s) of the repository per the Action inputs.
Expand Down Expand Up @@ -8015,6 +8019,9 @@ async function performUpdate(actionInputs) {
newVersion = actionInputs.ReleaseVersion;
versionDiff = diff_default()(currentVersion, newVersion);
}
// Ensure that the new version is greater than the current version, and that
// there's no existing tag for it.
validateVersion(currentVersion, newVersion, tags);
if (FieldNames.Workspaces in rootManifest) {
console.log('Project appears to have workspaces. Applying monorepo workflow.');
await updateMonorepo(newVersion, versionDiff, validatePackageManifest(WORKSPACE_ROOT, rootManifest, [
Expand Down Expand Up @@ -8075,6 +8082,24 @@ async function updateMonorepo(newVersion, versionDiff, rootManifest, repositoryU
await updatePackages(allPackages, updateSpecification);
await updatePackage({ dirPath: WORKSPACE_ROOT, manifest: rootManifest }, { ...updateSpecification, shouldUpdateChangelog: false });
}
/**
* Throws an error if the current version is equal to the new version, if a
* tag for the new version already exists, or if the new version is less than
* the current version.
*
* @param currentVersion - The most recently released version.
* @param newVersion - The new version to be released.
* @param tags - All tags reachable from the current git HEAD, as from "git
* tag --merged".
*/
function validateVersion(currentVersion, newVersion, tags) {
if (!gt_default()(newVersion, currentVersion)) {
throw new Error(`The new version "${newVersion}" is not greater than the current version "${currentVersion}".`);
}
if (tags.has(`v${newVersion}`)) {
throw new Error(`Tag "v${newVersion}" for new version "${newVersion}" already exists.`);
}
}
//# sourceMappingURL=update.js.map
;// CONCATENATED MODULE: ./lib/index.js

Expand Down
92 changes: 85 additions & 7 deletions src/update.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,7 @@ describe('performUpdate', () => {
getRepositoryHttpsUrlMock = jest
.spyOn(gitOperations, 'getRepositoryHttpsUrl')
.mockImplementationOnce(async () => mockRepoUrl);
getTagsMock = jest
.spyOn(gitOperations, 'getTags')
.mockImplementationOnce(async () => [
new Set(['1.0.0', '1.1.0']),
'1.1.0',
]);
getTagsMock = jest.spyOn(gitOperations, 'getTags');
consoleLogMock = jest
.spyOn(console, 'log')
.mockImplementation(() => undefined);
Expand All @@ -72,6 +67,11 @@ describe('performUpdate', () => {
const oldVersion = '1.1.0';
const newVersion = '2.0.0';

getTagsMock.mockImplementationOnce(async () => [
new Set(['v1.0.0', 'v1.1.0']),
'v1.1.0',
]);

getPackageManifestMock.mockImplementationOnce(async () => {
return {
name: packageName,
Expand Down Expand Up @@ -103,6 +103,11 @@ describe('performUpdate', () => {
const oldVersion = '1.1.0';
const newVersion = '2.0.0';

getTagsMock.mockImplementationOnce(async () => [
new Set(['v1.0.0', 'v1.1.0']),
'v1.1.0',
]);

getPackageManifestMock.mockImplementationOnce(async () => {
return {
name: packageName,
Expand Down Expand Up @@ -138,6 +143,11 @@ describe('performUpdate', () => {
const newVersion = '2.0.0';
const workspaces: readonly string[] = ['a', 'b', 'c'];

getTagsMock.mockImplementationOnce(async () => [
new Set(['v1.0.0', 'v1.1.0']),
'v1.1.0',
]);

getPackageManifestMock.mockImplementationOnce(async () => {
return {
name: rootManifestName,
Expand Down Expand Up @@ -171,7 +181,7 @@ describe('performUpdate', () => {
expect(getPackagesToUpdateMock).toHaveBeenCalledWith(
{ a: {}, b: {}, c: {} },
true,
new Set(['1.0.0', '1.1.0']),
new Set(['v1.0.0', 'v1.1.0']),
);

expect(packageOperations.updatePackages).toHaveBeenCalledTimes(1);
Expand Down Expand Up @@ -209,4 +219,72 @@ describe('performUpdate', () => {
expect(setActionOutputMock).toHaveBeenCalledTimes(1);
expect(setActionOutputMock).toHaveBeenCalledWith('NEW_VERSION', newVersion);
});

it('throws if the new version is less than the current version', async () => {
const packageName = 'A';
const oldVersion = '1.1.0';
const newVersion = '1.0.0';

getTagsMock.mockImplementationOnce(async () => [
new Set(['v1.1.0']),
'v1.1.0',
]);

getPackageManifestMock.mockImplementationOnce(async () => {
return {
name: packageName,
version: oldVersion,
};
});

await expect(
performUpdate({ ReleaseType: null, ReleaseVersion: newVersion }),
).rejects.toThrow(/^The new version "1\.0\.0" is not greater than/u);
});

it('throws if the new version is equal to the current version', async () => {
const packageName = 'A';
const oldVersion = '1.1.0';
const newVersion = '1.1.0';

getTagsMock.mockImplementationOnce(async () => [
new Set(['v1.1.0']),
'v1.1.0',
]);

getPackageManifestMock.mockImplementationOnce(async () => {
return {
name: packageName,
version: oldVersion,
};
});

await expect(
performUpdate({ ReleaseType: null, ReleaseVersion: newVersion }),
).rejects.toThrow(/^The new version "1\.1\.0" is not greater than/u);
});

it('throws if there is already a tag for the new version', async () => {
const packageName = 'A';
const oldVersion = '1.1.0';
const newVersion = '2.0.0';

getTagsMock.mockImplementationOnce(async () => [
new Set(['v1.0.0', 'v1.1.0', 'v2.0.0']),
'v2.0.0',
]);

getPackageManifestMock.mockImplementationOnce(async () => {
return {
name: packageName,
version: oldVersion,
};
});

await expect(
performUpdate({ ReleaseType: null, ReleaseVersion: newVersion }),
).rejects.toThrow(
/^Tag "v2\.0\.0" for new version "2\.0\.0" already exists\.$/u,
);
});
});
32 changes: 32 additions & 0 deletions src/update.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { setOutput as setActionOutput } from '@actions/core';
import semverIncrement from 'semver/functions/inc';
import semverDiff from 'semver/functions/diff';
import semverGt from 'semver/functions/gt';
import type { ReleaseType as SemverReleaseType } from 'semver';

import { getRepositoryHttpsUrl, getTags } from './git-operations';
Expand Down Expand Up @@ -51,6 +52,10 @@ export async function performUpdate(actionInputs: ActionInputs): Promise<void> {
versionDiff = semverDiff(currentVersion, newVersion) as SemverReleaseType;
}

// Ensure that the new version is greater than the current version, and that
// there's no existing tag for it.
validateVersion(currentVersion, newVersion, tags);

if (FieldNames.Workspaces in rootManifest) {
console.log(
'Project appears to have workspaces. Applying monorepo workflow.',
Expand Down Expand Up @@ -153,3 +158,30 @@ async function updateMonorepo(
{ ...updateSpecification, shouldUpdateChangelog: false },
);
}

/**
* Throws an error if the current version is equal to the new version, if a
* tag for the new version already exists, or if the new version is less than
* the current version.
*
* @param currentVersion - The most recently released version.
* @param newVersion - The new version to be released.
* @param tags - All tags reachable from the current git HEAD, as from "git
* tag --merged".
*/
function validateVersion(
currentVersion: string,
newVersion: string,
tags: ReadonlySet<string>,
) {
if (!semverGt(newVersion, currentVersion)) {
throw new Error(
`The new version "${newVersion}" is not greater than the current version "${currentVersion}".`,
);
}
if (tags.has(`v${newVersion}`)) {
throw new Error(
`Tag "v${newVersion}" for new version "${newVersion}" already exists.`,
);
}
}

0 comments on commit 38d3eef

Please sign in to comment.