Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@types/yargs": "^17.0.10",
"@typescript-eslint/eslint-plugin": "^4.21.0",
"@typescript-eslint/parser": "^4.21.0",
"deepmerge": "^4.2.2",
"eslint": "^7.23.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-import": "^2.22.1",
Expand Down
2 changes: 1 addition & 1 deletion src/fs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import util from 'util';
import rimraf from 'rimraf';
import { when } from 'jest-when';
import * as actionUtils from '@metamask/action-utils';
import { withSandbox } from '../tests/unit/helpers';
import { withSandbox } from '../tests/helpers';
import {
readFile,
writeFile,
Expand Down
250 changes: 250 additions & 0 deletions src/functional.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
import { withMonorepoProjectEnvironment } from '../tests/functional/helpers/with';
import { buildChangelog } from '../tests/functional/helpers/utils';

describe('create-release-branch (functional)', () => {
describe('against a monorepo with independent versions', () => {
it('updates the version of the root package to be the current date along with the versions of the specified packages', async () => {
Copy link
Contributor Author

@mcmire mcmire Aug 2, 2022

Choose a reason for hiding this comment

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

I'm only testing the happy paths right now. This file is going to grow larger as we add different features — for instance, right now there is no logic around changed packages, so once that happens we need to consider what happens when the repo has no tags, etc. — so I'm hesitant to add error/alternate cases. I figure it's easier to add more test cases later than remove them.

await withMonorepoProjectEnvironment(
{
packages: {
$root$: {
name: '@scope/monorepo',
version: '2022.1.1',
directoryPath: '.',
},
a: {
name: '@scope/a',
version: '0.1.2',
directoryPath: 'packages/a',
},
b: {
name: '@scope/b',
version: '1.1.4',
directoryPath: 'packages/b',
},
c: {
name: '@scope/c',
version: '2.0.13',
directoryPath: 'packages/c',
},
d: {
name: '@scope/d',
version: '1.2.3',
directoryPath: 'packages/d',
},
e: {
name: '@scope/e',
version: '0.0.3',
directoryPath: 'packages/e',
},
},
workspaces: {
'.': ['packages/*'],
},
today: new Date('2022-06-24'),
},
async (environment) => {
await environment.runTool({
releaseSpecification: {
packages: {
a: 'major',
b: 'minor',
c: 'patch',
d: '1.2.4',
},
},
});

expect(await environment.readJsonFile('package.json')).toMatchObject({
version: '2022.6.24',
});
expect(
await environment.readJsonFileWithinPackage('a', 'package.json'),
).toMatchObject({
version: '1.0.0',
});
expect(
await environment.readJsonFileWithinPackage('b', 'package.json'),
).toMatchObject({
version: '1.2.0',
});
expect(
await environment.readJsonFileWithinPackage('c', 'package.json'),
).toMatchObject({
version: '2.0.14',
});
expect(
await environment.readJsonFileWithinPackage('d', 'package.json'),
).toMatchObject({
version: '1.2.4',
});
expect(
await environment.readJsonFileWithinPackage('e', 'package.json'),
).toMatchObject({
version: '0.0.3',
});
},
);
});

it("updates each of the specified packages' changelogs by adding a new section which lists all commits concerning the package over the entire history of the repo", async () => {
await withMonorepoProjectEnvironment(
{
packages: {
$root$: {
name: '@scope/monorepo',
version: '2022.1.1',
directoryPath: '.',
},
a: {
name: '@scope/a',
version: '1.0.0',
directoryPath: 'packages/a',
},
b: {
name: '@scope/b',
version: '1.0.0',
directoryPath: 'packages/b',
},
},
workspaces: {
'.': ['packages/*'],
},
createInitialCommit: false,
},
async (environment) => {
// Create an initial commit
await environment.writeFileWithinPackage(
'a',
'CHANGELOG.md',
buildChangelog(`
## [Unreleased]

[Unreleased]: https://github.com/example-org/example-repo
`),
);
await environment.writeFileWithinPackage(
'b',
'CHANGELOG.md',
buildChangelog(`
## [Unreleased]

[Unreleased]: https://github.com/example-org/example-repo
`),
);
await environment.createCommit('Initial commit');

// Create another commit that only changes "a"
await environment.writeFileWithinPackage(
'a',
'dummy.txt',
'Some content',
);
await environment.createCommit('Update "a"');

// Run the tool
await environment.runTool({
releaseSpecification: {
packages: {
a: 'major',
b: 'major',
},
},
});

// Both changelogs should get updated, with an additional
// commit listed for "a"
expect(
await environment.readFileWithinPackage('a', 'CHANGELOG.md'),
).toStrictEqual(
buildChangelog(`
## [Unreleased]

## [2.0.0]
### Uncategorized
- Update "a"
- Initial commit

[Unreleased]: https://github.com/example-org/example-repo/compare/v2.0.0...HEAD
[2.0.0]: https://github.com/example-org/example-repo/releases/tag/v2.0.0
`),
);
expect(
await environment.readFileWithinPackage('b', 'CHANGELOG.md'),
).toStrictEqual(
buildChangelog(`
## [Unreleased]

## [2.0.0]
### Uncategorized
- Initial commit

[Unreleased]: https://github.com/example-org/example-repo/compare/v2.0.0...HEAD
[2.0.0]: https://github.com/example-org/example-repo/releases/tag/v2.0.0
`),
);
},
);
});

it('switches to a new release branch and commits the changes', async () => {
await withMonorepoProjectEnvironment(
{
packages: {
$root$: {
name: '@scope/monorepo',
version: '2022.1.1',
directoryPath: '.',
},
a: {
name: '@scope/a',
version: '1.0.0',
directoryPath: 'packages/a',
},
},
workspaces: {
'.': ['packages/*'],
},
today: new Date('2022-06-24'),
},
async (environment) => {
await environment.runTool({
releaseSpecification: {
packages: {
a: 'major',
},
},
});

// Tests four things:
// * The latest commit should be called "Release YYYY-MM-DD"
// * The latest commit should be the current commit (HEAD)
// * The latest branch should be called "release/YYYY-MM-DD"
// * The latest branch should point to the latest commit
const [latestCommitSubject, latestCommitId, latestCommitRevsMarker] =
(
await environment.runCommand('git', [
'log',
'--pretty=%s%x09%H%x09%D',
'--date-order',
'--max-count=1',
])
).stdout.split('\x09');
const latestCommitRevs = latestCommitRevsMarker.split(' -> ');
const latestBranchCommitId = (
await environment.runCommand('git', [
'rev-list',
'--branches',
'--date-order',
'--max-count=1',
])
).stdout;
expect(latestCommitSubject).toStrictEqual('Release 2022-06-24');
expect(latestCommitRevs).toContain('HEAD');
expect(latestCommitRevs).toContain('release/2022-06-24');
expect(latestBranchCommitId).toStrictEqual(latestCommitId);
},
);
});
});
});
7 changes: 2 additions & 5 deletions src/monorepo-workflow-operations.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import fs from 'fs';
import path from 'path';
import { SemVer } from 'semver';
import {
withSandbox,
buildMockPackage,
buildMockProject,
} from '../tests/unit/helpers';
import { withSandbox } from '../tests/helpers';
import { buildMockPackage, buildMockProject } from '../tests/unit/helpers';
import { followMonorepoWorkflow } from './monorepo-workflow-operations';
import * as editorModule from './editor';
import * as envModule from './env';
Expand Down
2 changes: 1 addition & 1 deletion src/package-manifest.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from 'fs';
import path from 'path';
import { SemVer } from 'semver';
import { withSandbox } from '../tests/unit/helpers';
import { withSandbox } from '../tests/helpers';
import { readPackageManifest } from './package-manifest';

describe('package-manifest', () => {
Expand Down
9 changes: 3 additions & 6 deletions src/package.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ import fs from 'fs';
import path from 'path';
import { when } from 'jest-when';
import * as autoChangelog from '@metamask/auto-changelog';
import {
buildMockProject,
buildMockManifest,
withSandbox,
} from '../tests/unit/helpers';
import { readPackage, updatePackage } from './package';
import { withSandbox } from '../tests/helpers';
import { buildMockProject, buildMockManifest } from '../tests/unit/helpers';
import * as fsModule from './fs';
import { readPackage, updatePackage } from './package';
import * as packageManifestModule from './package-manifest';

jest.mock('@metamask/auto-changelog');
Expand Down
7 changes: 2 additions & 5 deletions src/project.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import fs from 'fs';
import path from 'path';
import { when } from 'jest-when';
import {
buildMockManifest,
buildMockPackage,
withSandbox,
} from '../tests/unit/helpers';
import { withSandbox } from '../tests/helpers';
import { buildMockManifest, buildMockPackage } from '../tests/unit/helpers';
import { readProject } from './project';
import * as packageModule from './package';
import * as repoModule from './repo';
Expand Down
7 changes: 2 additions & 5 deletions src/release-specification.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ import { when } from 'jest-when';
import { MockWritable } from 'stdio-mock';
import YAML from 'yaml';
import { SemVer } from 'semver';
import {
withSandbox,
buildMockProject,
buildMockPackage,
} from '../tests/unit/helpers';
import { withSandbox } from '../tests/helpers';
import { buildMockProject, buildMockPackage } from '../tests/unit/helpers';
import {
generateReleaseSpecificationTemplateForMonorepo,
waitForUserToEditReleaseSpecification,
Expand Down
10 changes: 10 additions & 0 deletions tests/functional/helpers/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import path from 'path';

const ROOT_DIR = path.resolve(__dirname, '../../..');
export const TOOL_EXECUTABLE_PATH = path.join(ROOT_DIR, 'src', 'cli.ts');
export const TS_NODE_PATH = path.join(
ROOT_DIR,
'node_modules',
'.bin',
'ts-node',
);
Loading