Skip to content

Commit d422085

Browse files
committed
Reformat root version to include the release no.
This commit changes how the root version is bumped per release so that instead of looking like `<yyyy>.<mm>.<dd>`, it looks like `<yyyy><mm><dd>.<release-number>.0`. That is, the root version consists of the date that the release was created + a release number, which is incremented every time a new release is issued.
1 parent 5b63b9e commit d422085

14 files changed

+361
-97
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"dependencies": {
2525
"@metamask/action-utils": "^0.0.2",
2626
"@metamask/utils": "^2.1.0",
27+
"date-fns": "^2.29.1",
2728
"debug": "^4.3.4",
2829
"execa": "^5.0.0",
2930
"glob": "^8.0.3",

src/functional.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe('create-release-branch (functional)', () => {
99
packages: {
1010
$root$: {
1111
name: '@scope/monorepo',
12-
version: '2022.1.1',
12+
version: '20220101.1.0',
1313
directoryPath: '.',
1414
},
1515
a: {
@@ -41,7 +41,7 @@ describe('create-release-branch (functional)', () => {
4141
workspaces: {
4242
'.': ['packages/*'],
4343
},
44-
today: new Date('2022-06-24'),
44+
today: new Date(2022, 5, 24),
4545
},
4646
async (environment) => {
4747
await environment.updateJsonFile('package.json', {
@@ -88,7 +88,7 @@ describe('create-release-branch (functional)', () => {
8888

8989
expect(await environment.readJsonFile('package.json')).toStrictEqual({
9090
name: '@scope/monorepo',
91-
version: '2022.6.24',
91+
version: '20220624.2.0',
9292
private: true,
9393
workspaces: ['packages/*'],
9494
scripts: { foo: 'bar' },
@@ -138,7 +138,7 @@ describe('create-release-branch (functional)', () => {
138138
packages: {
139139
$root$: {
140140
name: '@scope/monorepo',
141-
version: '2022.1.1',
141+
version: '20220101.1.0',
142142
directoryPath: '.',
143143
},
144144
a: {
@@ -238,7 +238,7 @@ describe('create-release-branch (functional)', () => {
238238
packages: {
239239
$root$: {
240240
name: '@scope/monorepo',
241-
version: '2022.1.1',
241+
version: '20220101.1.0',
242242
directoryPath: '.',
243243
},
244244
a: {
@@ -250,7 +250,7 @@ describe('create-release-branch (functional)', () => {
250250
workspaces: {
251251
'.': ['packages/*'],
252252
},
253-
today: new Date('2022-06-24'),
253+
today: new Date(2022, 5, 24),
254254
},
255255
async (environment) => {
256256
await environment.runTool({
@@ -262,9 +262,9 @@ describe('create-release-branch (functional)', () => {
262262
});
263263

264264
// Tests four things:
265-
// * The latest commit should be called "Release YYYY-MM-DD"
265+
// * The latest commit should be called "Release YYYY-MM-DD (RN)"
266266
// * The latest commit should be the current commit (HEAD)
267-
// * The latest branch should be called "release/YYYY-MM-DD"
267+
// * The latest branch should be called "release/YYYY-MM-DD/N"
268268
// * The latest branch should point to the latest commit
269269
const [latestCommitSubject, latestCommitId, latestCommitRevsMarker] =
270270
(
@@ -284,9 +284,9 @@ describe('create-release-branch (functional)', () => {
284284
'--max-count=1',
285285
])
286286
).stdout;
287-
expect(latestCommitSubject).toStrictEqual('Release 2022-06-24');
287+
expect(latestCommitSubject).toStrictEqual('Release 2022-06-24 (R2)');
288288
expect(latestCommitRevs).toContain('HEAD');
289-
expect(latestCommitRevs).toContain('release/2022-06-24');
289+
expect(latestCommitRevs).toContain('release/2022-06-24/2');
290290
expect(latestBranchCommitId).toStrictEqual(latestCommitId);
291291
},
292292
);

src/initial-parameters.test.ts

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe('initial-parameters', () => {
4646
project,
4747
tempDirectoryPath: '/path/to/temp',
4848
reset: true,
49-
today: new Date('2022-06-22'),
49+
today: new Date(2022, 5, 22),
5050
});
5151
});
5252

@@ -125,9 +125,81 @@ describe('initial-parameters', () => {
125125
);
126126
});
127127

128-
it('uses the current date if the TODAY environment variable was not provided', async () => {
128+
it('returns initial parameters including reset: false, derived from a command-line argument of "--reset true"', async () => {
129129
const project = buildMockProject();
130-
const today = new Date('2022-01-01');
130+
when(jest.spyOn(commandLineArgumentsModule, 'readCommandLineArguments'))
131+
.calledWith(['arg1', 'arg2'])
132+
.mockResolvedValue({
133+
projectDirectory: '/path/to/project',
134+
tempDirectory: '/path/to/temp',
135+
reset: true,
136+
});
137+
jest
138+
.spyOn(envModule, 'getEnvironmentVariables')
139+
.mockReturnValue({ TODAY: undefined, EDITOR: undefined });
140+
when(jest.spyOn(projectModule, 'readProject'))
141+
.calledWith('/path/to/project')
142+
.mockResolvedValue(project);
143+
144+
const config = await determineInitialParameters(
145+
['arg1', 'arg2'],
146+
'/path/to/somewhere',
147+
);
148+
149+
expect(config.reset).toBe(true);
150+
});
151+
152+
it('returns initial parameters including reset: false, derived from a command-line argument of "--reset false"', async () => {
153+
const project = buildMockProject();
154+
when(jest.spyOn(commandLineArgumentsModule, 'readCommandLineArguments'))
155+
.calledWith(['arg1', 'arg2'])
156+
.mockResolvedValue({
157+
projectDirectory: '/path/to/project',
158+
tempDirectory: '/path/to/temp',
159+
reset: false,
160+
});
161+
jest
162+
.spyOn(envModule, 'getEnvironmentVariables')
163+
.mockReturnValue({ TODAY: undefined, EDITOR: undefined });
164+
when(jest.spyOn(projectModule, 'readProject'))
165+
.calledWith('/path/to/project')
166+
.mockResolvedValue(project);
167+
168+
const config = await determineInitialParameters(
169+
['arg1', 'arg2'],
170+
'/path/to/somewhere',
171+
);
172+
173+
expect(config.reset).toBe(false);
174+
});
175+
176+
it("returns initial parameters including today's date, derived from the TODAY environment variable", async () => {
177+
const project = buildMockProject();
178+
when(jest.spyOn(commandLineArgumentsModule, 'readCommandLineArguments'))
179+
.calledWith(['arg1', 'arg2'])
180+
.mockResolvedValue({
181+
projectDirectory: '/path/to/project',
182+
tempDirectory: '/path/to/temp',
183+
reset: true,
184+
});
185+
jest
186+
.spyOn(envModule, 'getEnvironmentVariables')
187+
.mockReturnValue({ TODAY: '2022-01-01', EDITOR: undefined });
188+
when(jest.spyOn(projectModule, 'readProject'))
189+
.calledWith('/path/to/project')
190+
.mockResolvedValue(project);
191+
192+
const config = await determineInitialParameters(
193+
['arg1', 'arg2'],
194+
'/path/to/somewhere',
195+
);
196+
197+
expect(config.today).toStrictEqual(new Date(2022, 0, 1));
198+
});
199+
200+
it('uses the current date if TODAY is undefined', async () => {
201+
const project = buildMockProject();
202+
const today = new Date(2022, 0, 1);
131203
when(jest.spyOn(commandLineArgumentsModule, 'readCommandLineArguments'))
132204
.calledWith(['arg1', 'arg2'])
133205
.mockResolvedValue({
@@ -153,7 +225,7 @@ describe('initial-parameters', () => {
153225

154226
it('uses the current date if TODAY is not a parsable date', async () => {
155227
const project = buildMockProject();
156-
const today = new Date('2022-01-01');
228+
const today = new Date(2022, 0, 1);
157229
when(jest.spyOn(commandLineArgumentsModule, 'readCommandLineArguments'))
158230
.calledWith(['arg1', 'arg2'])
159231
.mockResolvedValue({

src/initial-parameters.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import os from 'os';
22
import path from 'path';
3-
import { getEnvironmentVariables } from './env';
3+
import { parseISO as parseDateAsISO } from 'date-fns';
44
import { readCommandLineArguments } from './command-line-arguments';
5+
import { getEnvironmentVariables } from './env';
56
import { readProject, Project } from './project';
67

78
interface InitialParameters {
@@ -37,7 +38,7 @@ export async function determineInitialParameters(
3738
)
3839
: path.resolve(cwd, inputs.tempDirectory);
3940
const parsedTodayTimestamp =
40-
TODAY === undefined ? NaN : new Date(TODAY).getTime();
41+
TODAY === undefined ? NaN : parseDateAsISO(TODAY).getTime();
4142
const today = isNaN(parsedTodayTimestamp)
4243
? new Date()
4344
: new Date(parsedTodayTimestamp);

src/monorepo-workflow-operations.test.ts

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -89,21 +89,19 @@ function buildMockReleaseSpecification({
8989
*
9090
* @param overrides - The properties you want to override in the mock release
9191
* plan.
92-
* @param overrides.releaseName - The name of the new release. For a polyrepo or
93-
* a monorepo with fixed versions, this will be a version string with the shape
94-
* `<major>.<minor>.<patch>`; for a monorepo with independent versions, this
95-
* will be a version string with the shape `<year>.<month>.<day>-<build
96-
* number>`.
92+
* @param overrides.releaseDate - The date of the release.
93+
* @param overrides.releaseNumber - The number of the release.
9794
* @param overrides.packages - Information about all of the packages in the
9895
* project. For a polyrepo, this consists of the self-same package; for a
9996
* monorepo it consists of the root package and any workspace packages.
10097
* @returns The mock release specification.
10198
*/
10299
function buildMockReleasePlan({
103-
releaseName = 'release-name',
100+
releaseDate = new Date(),
101+
releaseNumber = 1,
104102
packages = [],
105103
}: Partial<ReleasePlan> = {}): ReleasePlan {
106-
return { releaseName, packages };
104+
return { releaseDate, releaseNumber, packages };
107105
}
108106

109107
/**
@@ -178,8 +176,9 @@ async function setupFollowMonorepoWorkflow({
178176
const releaseSpecification = buildMockReleaseSpecification({
179177
path: releaseSpecificationPath,
180178
});
181-
const releaseName = 'some-release-name';
182-
const releasePlan = buildMockReleasePlan({ releaseName });
179+
const releaseDate = new Date(2022, 0, 1);
180+
const releaseNumber = 12345;
181+
const releasePlan = buildMockReleasePlan({ releaseDate, releaseNumber });
183182
const projectDirectoryPath = '/path/to/project';
184183
const project = buildMockProject({ directoryPath: projectDirectoryPath });
185184
const today = new Date();
@@ -221,12 +220,21 @@ async function setupFollowMonorepoWorkflow({
221220
}
222221

223222
if (errorUponExecutingReleasePlan) {
224-
executeReleasePlanSpy.mockRejectedValue(errorUponExecutingReleasePlan);
223+
when(executeReleasePlanSpy)
224+
.calledWith(project, releasePlan, stderr)
225+
.mockRejectedValue(errorUponExecutingReleasePlan);
225226
} else {
226-
executeReleasePlanSpy.mockResolvedValue();
227+
when(executeReleasePlanSpy)
228+
.calledWith(project, releasePlan, stderr)
229+
.mockResolvedValue(undefined);
227230
}
228231

229-
captureChangesInReleaseBranchSpy.mockResolvedValue();
232+
when(captureChangesInReleaseBranchSpy)
233+
.calledWith(projectDirectoryPath, {
234+
releaseDate,
235+
releaseNumber,
236+
})
237+
.mockResolvedValue();
230238

231239
if (doesReleaseSpecFileExist) {
232240
await fs.promises.writeFile(
@@ -246,7 +254,8 @@ async function setupFollowMonorepoWorkflow({
246254
executeReleasePlanSpy,
247255
captureChangesInReleaseBranchSpy,
248256
releasePlan,
249-
releaseName,
257+
releaseDate,
258+
releaseNumber,
250259
releaseSpecificationPath,
251260
};
252261
}
@@ -295,7 +304,8 @@ describe('monorepo-workflow-operations', () => {
295304
stderr,
296305
captureChangesInReleaseBranchSpy,
297306
projectDirectoryPath,
298-
releaseName,
307+
releaseDate,
308+
releaseNumber,
299309
} = await setupFollowMonorepoWorkflow({
300310
sandbox,
301311
doesReleaseSpecFileExist: false,
@@ -313,7 +323,10 @@ describe('monorepo-workflow-operations', () => {
313323

314324
expect(captureChangesInReleaseBranchSpy).toHaveBeenCalledWith(
315325
projectDirectoryPath,
316-
releaseName,
326+
{
327+
releaseDate,
328+
releaseNumber,
329+
},
317330
);
318331
});
319332
});
@@ -688,7 +701,8 @@ describe('monorepo-workflow-operations', () => {
688701
stderr,
689702
captureChangesInReleaseBranchSpy,
690703
projectDirectoryPath,
691-
releaseName,
704+
releaseDate,
705+
releaseNumber,
692706
} = await setupFollowMonorepoWorkflow({
693707
sandbox,
694708
doesReleaseSpecFileExist: true,
@@ -705,7 +719,10 @@ describe('monorepo-workflow-operations', () => {
705719

706720
expect(captureChangesInReleaseBranchSpy).toHaveBeenCalledWith(
707721
projectDirectoryPath,
708-
releaseName,
722+
{
723+
releaseDate,
724+
releaseNumber,
725+
},
709726
);
710727
});
711728
});
@@ -849,7 +866,8 @@ describe('monorepo-workflow-operations', () => {
849866
stderr,
850867
captureChangesInReleaseBranchSpy,
851868
projectDirectoryPath,
852-
releaseName,
869+
releaseDate,
870+
releaseNumber,
853871
} = await setupFollowMonorepoWorkflow({
854872
sandbox,
855873
doesReleaseSpecFileExist: false,
@@ -867,7 +885,10 @@ describe('monorepo-workflow-operations', () => {
867885

868886
expect(captureChangesInReleaseBranchSpy).toHaveBeenCalledWith(
869887
projectDirectoryPath,
870-
releaseName,
888+
{
889+
releaseDate,
890+
releaseNumber,
891+
},
871892
);
872893
});
873894
});
@@ -1247,7 +1268,8 @@ describe('monorepo-workflow-operations', () => {
12471268
stderr,
12481269
captureChangesInReleaseBranchSpy,
12491270
projectDirectoryPath,
1250-
releaseName,
1271+
releaseDate,
1272+
releaseNumber,
12511273
} = await setupFollowMonorepoWorkflow({
12521274
sandbox,
12531275
doesReleaseSpecFileExist: true,
@@ -1265,7 +1287,10 @@ describe('monorepo-workflow-operations', () => {
12651287

12661288
expect(captureChangesInReleaseBranchSpy).toHaveBeenCalledWith(
12671289
projectDirectoryPath,
1268-
releaseName,
1290+
{
1291+
releaseDate,
1292+
releaseNumber,
1293+
},
12691294
);
12701295
});
12711296
});

src/monorepo-workflow-operations.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ export async function followMonorepoWorkflow({
114114
});
115115
await executeReleasePlan(project, releasePlan, stderr);
116116
await removeFile(releaseSpecificationPath);
117-
await captureChangesInReleaseBranch(
118-
project.directoryPath,
119-
releasePlan.releaseName,
120-
);
117+
await captureChangesInReleaseBranch(project.directoryPath, {
118+
releaseDate: releasePlan.releaseDate,
119+
releaseNumber: releasePlan.releaseNumber,
120+
});
121121
}

0 commit comments

Comments
 (0)