From df1750c6cfacd466390f901106edcbf39c280282 Mon Sep 17 00:00:00 2001 From: Dotan Simha Date: Sun, 3 Jul 2022 12:10:23 +0300 Subject: [PATCH 01/24] Added `getCurrentCommitId` helper --- .changeset/short-cats-invent.md | 5 +++++ packages/git/src/index.ts | 12 ++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 .changeset/short-cats-invent.md diff --git a/.changeset/short-cats-invent.md b/.changeset/short-cats-invent.md new file mode 100644 index 000000000..2f10ba463 --- /dev/null +++ b/.changeset/short-cats-invent.md @@ -0,0 +1,5 @@ +--- +"@changesets/git": minor +--- + +Added a new helper function: `getCurrentCommitId` diff --git a/packages/git/src/index.ts b/packages/git/src/index.ts index eebc903d8..5af8d1ee7 100644 --- a/packages/git/src/index.ts +++ b/packages/git/src/index.ts @@ -286,3 +286,15 @@ export async function getChangedPackagesSinceRef({ .filter((pkg, idx, packages) => packages.indexOf(pkg) === idx) ); } + +export async function getCurrentCommitId({ + cwd +}: { + cwd: string; +}): Promise { + return ( + await spawn("git", ["show", `--format="%h"`, "--no-patch"], { cwd }) + ).stdout + .toString() + .trim(); +} From 8668392bd548faee7d7df0e678d894fe8ad8ce45 Mon Sep 17 00:00:00 2001 From: Dotan Simha Date: Tue, 5 Jul 2022 13:33:45 +0300 Subject: [PATCH 02/24] Added snapshotPreidTemplate --- .../assemble-release-plan/src/index.test.ts | 14 +- packages/assemble-release-plan/src/index.ts | 110 +++++--- packages/cli/src/commands/version/index.ts | 18 +- .../cli/src/commands/version/version.test.ts | 248 +++++++++++------- packages/config/src/index.test.ts | 6 +- packages/config/src/index.ts | 20 +- packages/types/src/index.ts | 1 + 7 files changed, 276 insertions(+), 141 deletions(-) diff --git a/packages/assemble-release-plan/src/index.test.ts b/packages/assemble-release-plan/src/index.test.ts index 6b6cbc5f1..b625c9762 100644 --- a/packages/assemble-release-plan/src/index.test.ts +++ b/packages/assemble-release-plan/src/index.test.ts @@ -37,7 +37,12 @@ describe("assemble-release-plan", () => { setup.packages, defaultConfig, undefined, - true + { + tag: undefined, + timestamp: "1657013578416", + datetime: "20220705094844", + commit: "abcdef" + } ); expect(releases.length).toBe(1); @@ -50,7 +55,12 @@ describe("assemble-release-plan", () => { setup.packages, defaultConfig, undefined, - "foo" + { + tag: "foo", + timestamp: "1657013578416", + datetime: "20220705094844", + commit: "abcdef" + } ); expect(releases.length).toBe(1); diff --git a/packages/assemble-release-plan/src/index.ts b/packages/assemble-release-plan/src/index.ts index f302369c2..f337152a5 100644 --- a/packages/assemble-release-plan/src/index.ts +++ b/packages/assemble-release-plan/src/index.ts @@ -27,51 +27,63 @@ function getPreVersion(version: string) { return preVersion; } -function getSnapshotSuffix(snapshot?: string | boolean): string | undefined { - if (snapshot === undefined) { - return; +function getSnapshotVersion( + release: InternalRelease, + preInfo: PreInfo | undefined, + snapshotParameters: { + preidTemplate: string | null; + commit: string; + timestamp: string; + datetime: string; + tag: string | undefined; + useCalculatedVersion: boolean; } +): string { + if (release.type === "none") { + return release.oldVersion; + } + + const baseVersion = snapshotParameters.useCalculatedVersion + ? incrementVersion(release, preInfo) + : `0.0.0`; + + // This is way to handle the old behavior, where `snapshotPreidTemplate` is not in use. + // We need a special handling because we need to handle a case where `--snapshot` is used, + // and the resulting version needs to be composed without a tag. + if (!snapshotParameters.preidTemplate) { + const legacySuffix = [snapshotParameters.tag, snapshotParameters.datetime] + .filter(Boolean) + .join("-"); - let dateAndTime = new Date() - .toISOString() - .replace(/\.\d{3}Z$/, "") - .replace(/[^\d]/g, ""); - let tag = ""; + return [baseVersion, legacySuffix].join("-"); + } else { + const composedSuffix = snapshotParameters.preidTemplate + .replace("{timestamp}", snapshotParameters.timestamp) + .replace("{datetime}", snapshotParameters.datetime) + .replace("{commit}", snapshotParameters.commit) + .replace("{tag}", () => { + if (snapshotParameters.tag === undefined) { + throw new Error( + 'Failed to compose snapshot version: "{tag}" placeholder is used without specifying a tag name' + ); + } - if (typeof snapshot === "string") tag = `-${snapshot}`; + return snapshotParameters.tag; + }); - return `${tag}-${dateAndTime}`; + return [baseVersion, composedSuffix].filter(Boolean).join("-"); + } } function getNewVersion( release: InternalRelease, - preInfo: PreInfo | undefined, - snapshotSuffix: string | undefined, - useCalculatedVersionForSnapshots: boolean + preInfo: PreInfo | undefined ): string { if (release.type === "none") { return release.oldVersion; } - /** - * Using version as 0.0.0 so that it does not hinder with other version release - * For example; - * if user has a regular pre-release at 1.0.0-beta.0 and then you had a snapshot pre-release at 1.0.0-canary-git-hash - * and a consumer is using the range ^1.0.0-beta, most people would expect that range to resolve to 1.0.0-beta.0 - * but it'll actually resolve to 1.0.0-canary-hash. Using 0.0.0 solves this problem because it won't conflict with other versions. - * - * You can set `useCalculatedVersionForSnapshots` flag to true to use calculated versions if you don't care about the above problem. - */ - if (snapshotSuffix && !useCalculatedVersionForSnapshots) { - return `0.0.0${snapshotSuffix}`; - } - - const calculatedVersion = incrementVersion(release, preInfo); - if (snapshotSuffix && useCalculatedVersionForSnapshots) { - return `${calculatedVersion}${snapshotSuffix}`; - } - - return calculatedVersion; + return incrementVersion(release, preInfo); } function assembleReleasePlan( @@ -80,7 +92,15 @@ function assembleReleasePlan( config: Config, // intentionally not using an optional parameter here so the result of `readPreState` has to be passed in here preState: PreState | undefined, - snapshot?: string | boolean + // snapshot: undefined -> not using snaphot + // snapshot: { tag: undefined } -> --snapshot (empty tag) + // snapsgot: { tag: "canary" } -> --snapshot canary + snapshot?: { + tag: string | undefined; + commit: string; + timestamp: string; + datetime: string; + } ): ReleasePlan { let packagesByName = new Map( packages.packages.map(x => [x.packageJson.name, x]) @@ -94,9 +114,6 @@ function assembleReleasePlan( const preInfo = getPreInfo(changesets, packagesByName, config, preState); - // Caching the snapshot version here and use this if it is snapshot release - const snapshotSuffix = getSnapshotSuffix(snapshot); - // releases is, at this point a list of all packages we are going to releases, // flattened down to one release per package, having a reference back to their // changesets, and with a calculated new versions @@ -163,13 +180,20 @@ function assembleReleasePlan( releases: [...releases.values()].map(incompleteRelease => { return { ...incompleteRelease, - newVersion: getNewVersion( - incompleteRelease, - preInfo, - snapshotSuffix, - config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH - .useCalculatedVersionForSnapshots - ) + newVersion: snapshot + ? getSnapshotVersion(incompleteRelease, preInfo, { + commit: snapshot.commit, + timestamp: snapshot.timestamp, + datetime: snapshot.datetime, + tag: snapshot.tag, + preidTemplate: + config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH + .snapshotPreidTemplate, + useCalculatedVersion: + config.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH + .useCalculatedVersionForSnapshots + }) + : getNewVersion(incompleteRelease, preInfo) }; }), preState: preInfo?.state diff --git a/packages/cli/src/commands/version/index.ts b/packages/cli/src/commands/version/index.ts index 308435a3b..4b538356b 100644 --- a/packages/cli/src/commands/version/index.ts +++ b/packages/cli/src/commands/version/index.ts @@ -12,6 +12,7 @@ import { removeEmptyFolders } from "../../utils/v1-legacy/removeFolders"; import { readPreState } from "@changesets/pre"; import { ExitError } from "@changesets/errors"; import { getCommitFunctions } from "../../commit/getCommitFunctions"; +import { getCurrentCommitId } from "@changesets/git"; let importantSeparator = chalk.red( "===============================IMPORTANT!===============================" @@ -33,10 +34,11 @@ export default async function version( // Disable committing when in snapshot mode commit: options.snapshot ? false : config.commit }; - const [changesets, preState] = await Promise.all([ + const [changesets, preState, , commit] = await Promise.all([ readChangesets(cwd), readPreState(cwd), - removeEmptyFolders(path.resolve(cwd, ".changeset")) + removeEmptyFolders(path.resolve(cwd, ".changeset")), + getCurrentCommitId({ cwd }) ]); if (preState?.mode === "pre") { @@ -64,6 +66,11 @@ export default async function version( } let packages = await getPackages(cwd); + const timestamp = String(Date.now()); + const datetime = new Date() + .toISOString() + .replace(/\.\d{3}Z$/, "") + .replace(/[^\d]/g, ""); let releasePlan = assembleReleasePlan( changesets, @@ -71,6 +78,13 @@ export default async function version( releaseConfig, preState, options.snapshot + ? { + tag: options.snapshot === true ? undefined : options.snapshot, + commit, + timestamp, + datetime + } + : undefined ); let [...touchedFiles] = await applyReleasePlan( diff --git a/packages/cli/src/commands/version/version.test.ts b/packages/cli/src/commands/version/version.test.ts index cf58af328..2cbab1e2e 100644 --- a/packages/cli/src/commands/version/version.test.ts +++ b/packages/cli/src/commands/version/version.test.ts @@ -13,6 +13,16 @@ import pre from "../pre"; import version from "./index"; import humanId from "human-id"; +global.Date = class MockDate extends Date { + constructor() { + super("2021-12-13T00:07:30.879Z"); + } + + static now() { + return new MockDate().getTime(); + } +} as any; + const f = fixtures(__dirname); let changelogPath = path.resolve(__dirname, "../../changelog"); @@ -43,6 +53,9 @@ git.commit.mockImplementation(() => Promise.resolve(true)); git.getCommitsThatAddFiles.mockImplementation(changesetIds => Promise.resolve(changesetIds.map(() => "g1th4sh")) ); +// @ts-ignore +git.getCurrentCommitId.mockImplementation(() => Promise.resolve("abcdef")); + // @ts-ignore git.tag.mockImplementation(() => Promise.resolve(true)); @@ -714,54 +727,119 @@ describe("snapshot release", () => { }); it("should not bump version of an ignored package when its dependency gets updated", async () => { - const originalDate = Date; - // eslint-disable-next-line no-global-assign - Date = class Date { - toISOString() { - return "2021-12-13T00:07:30.879Z"; + const cwd = await f.copy("simple-project"); + await writeChangeset( + { + releases: [{ name: "pkg-b", type: "major" }], + summary: "a very useful summary" + }, + cwd + ); + + await version( + cwd, + { + snapshot: true + }, + { + ...modifiedDefaultConfig, + ignore: ["pkg-a"] } - } as any; - try { - const cwd = await f.copy("simple-project"); - await writeChangeset( - { - releases: [{ name: "pkg-b", type: "major" }], - summary: "a very useful summary" - }, - cwd - ); + ); - await version( - cwd, - { - snapshot: true + expect((await getPackages(cwd)).packages.map(x => x.packageJson)) + .toMatchInlineSnapshot(` + Array [ + Object { + "dependencies": Object { + "pkg-b": "0.0.0-20211213000730", + }, + "name": "pkg-a", + "version": "1.0.0", }, - { - ...modifiedDefaultConfig, - ignore: ["pkg-a"] - } + Object { + "name": "pkg-b", + "version": "0.0.0-20211213000730", + }, + ] + `); + }); + + describe("snapshotPreidTemplate", () => { + it('should throw an error when "{tag}" and empty snapshot is used', async () => { + let cwd = f.copy("simple-project"); + await writeChangesets([simpleChangeset2], cwd); + jest.spyOn(fs, "writeFile"); + + expect( + version( + cwd, + { snapshot: true }, + { + ...modifiedDefaultConfig, + commit: false, + ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { + ...modifiedDefaultConfig.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH, + snapshotPreidTemplate: `{tag}.{commit}` + } + } + ) + ).rejects.toThrow( + 'Failed to compose snapshot version: "{tag}" placeholder is used without specifying a tag name' ); + }); - expect((await getPackages(cwd)).packages.map(x => x.packageJson)) - .toMatchInlineSnapshot(` - Array [ - Object { - "dependencies": Object { - "pkg-b": "0.0.0-20211213000730", - }, - "name": "pkg-a", - "version": "1.0.0", - }, - Object { - "name": "pkg-b", - "version": "0.0.0-20211213000730", - }, - ] - `); - } finally { - // eslint-disable-next-line no-global-assign - Date = originalDate; - } + it.each([ + // Template-based + ["{tag}", "test", "0.0.0-test"], + ["{commit}", "test", "0.0.0-abcdef"], + ["{timestamp}", "test", "0.0.0-1639354050879"], + ["{datetime}", "test", "0.0.0-20211213000730"], + // Mixing template and static string + [ + "{tag}.{timestamp}.{commit}", + "alpha", + "0.0.0-alpha.1639354050879.abcdef" + ], + ["{datetime}-{tag}", "alpha", "0.0.0-20211213000730-alpha"], + // Legacy support + ["", "test", "0.0.0-test-20211213000730"], + [undefined as any, "canary", "0.0.0-canary-20211213000730"], + [null as any, "alpha", "0.0.0-alpha-20211213000730"] + ])( + "should customize release correctly based on snapshotPreidTemplate template: %p (tag: '%p')", + async (snapshotTemplate, snapshotValue, expectedResult) => { + let cwd = f.copy("simple-project"); + await writeChangesets([simpleChangeset2], cwd); + const spy = jest.spyOn(fs, "writeFile"); + await version( + cwd, + { snapshot: snapshotValue }, + { + ...modifiedDefaultConfig, + commit: false, + ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { + ...modifiedDefaultConfig.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH, + snapshotPreidTemplate: snapshotTemplate as string + } + } + ); + + expect(getPkgJSON("pkg-a", spy.mock.calls)).toEqual( + expect.objectContaining({ + name: "pkg-a", + version: expectedResult + }) + ); + + expect(getPkgJSON("pkg-b", spy.mock.calls)).toEqual( + expect.objectContaining({ + name: "pkg-b", + version: expectedResult + }) + ); + } + ); }); describe("useCalculatedVersionForSnapshots: true", () => { @@ -841,58 +919,46 @@ describe("snapshot release", () => { }); it("should not bump version of an ignored package when its dependency gets updated", async () => { - const originalDate = Date; - // eslint-disable-next-line no-global-assign - Date = class Date { - toISOString() { - return "2021-12-13T00:07:30.879Z"; - } - } as any; - try { - const cwd = await f.copy("simple-project"); - await writeChangeset( - { - releases: [{ name: "pkg-b", type: "major" }], - summary: "a very useful summary" - }, - cwd - ); + const cwd = await f.copy("simple-project"); + await writeChangeset( + { + releases: [{ name: "pkg-b", type: "major" }], + summary: "a very useful summary" + }, + cwd + ); - await version( - cwd, - { - snapshot: true - }, - { - ...modifiedDefaultConfig, - ignore: ["pkg-a"], - ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { - ...modifiedDefaultConfig.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH, - useCalculatedVersionForSnapshots: true - } + await version( + cwd, + { + snapshot: true + }, + { + ...modifiedDefaultConfig, + ignore: ["pkg-a"], + ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { + ...modifiedDefaultConfig.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH, + useCalculatedVersionForSnapshots: true } - ); + } + ); - expect((await getPackages(cwd)).packages.map(x => x.packageJson)) - .toMatchInlineSnapshot(` - Array [ - Object { - "dependencies": Object { - "pkg-b": "2.0.0-20211213000730", - }, - "name": "pkg-a", - "version": "1.0.0", - }, - Object { - "name": "pkg-b", - "version": "2.0.0-20211213000730", + expect((await getPackages(cwd)).packages.map(x => x.packageJson)) + .toMatchInlineSnapshot(` + Array [ + Object { + "dependencies": Object { + "pkg-b": "2.0.0-20211213000730", }, - ] - `); - } finally { - // eslint-disable-next-line no-global-assign - Date = originalDate; - } + "name": "pkg-a", + "version": "1.0.0", + }, + Object { + "name": "pkg-b", + "version": "2.0.0-20211213000730", + }, + ] + `); }); }); }); diff --git a/packages/config/src/index.test.ts b/packages/config/src/index.test.ts index dfcc64838..ffcc68831 100644 --- a/packages/config/src/index.test.ts +++ b/packages/config/src/index.test.ts @@ -48,7 +48,8 @@ test("read reads the config", async () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } }); }); @@ -65,7 +66,8 @@ let defaults = { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null }, bumpVersionsWithWorkspaceProtocolOnly: false } as const; diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index fc8fed2d5..8bc89d5d9 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -319,7 +319,8 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { const { onlyUpdatePeerDependentsWhenOutOfRange, updateInternalDependents, - useCalculatedVersionForSnapshots + useCalculatedVersionForSnapshots, + snapshotPreidTemplate } = json.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH; if ( onlyUpdatePeerDependentsWhenOutOfRange !== undefined && @@ -357,7 +358,20 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { )} when the only valid values are undefined or a boolean` ); } + if ( + snapshotPreidTemplate !== undefined && + typeof snapshotPreidTemplate !== "string" + ) { + messages.push( + `The \`snapshotPreidTemplate\` option is set as ${JSON.stringify( + snapshotPreidTemplate, + null, + 2 + )} when the only valid values are undefined, or a template string.` + ); + } } + if (messages.length) { throw new ValidationError( `Some errors occurred when validating the changesets config:\n` + @@ -411,6 +425,10 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { json.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH ?.updateInternalDependents ?? "out-of-range", + snapshotPreidTemplate: + json.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH + ?.snapshotPreidTemplate ?? null, + useCalculatedVersionForSnapshots: json.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH === undefined || json.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 9492550a6..ad2ce52b7 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -96,6 +96,7 @@ export type ExperimentalOptions = { onlyUpdatePeerDependentsWhenOutOfRange?: boolean; updateInternalDependents?: "always" | "out-of-range"; useCalculatedVersionForSnapshots?: boolean; + snapshotPreidTemplate?: string | null; }; export type NewChangesetWithCommit = NewChangeset & { commit?: string }; From ff191b89f9f75098e8bbdfd96039952502501cf8 Mon Sep 17 00:00:00 2001 From: Dotan Simha Date: Tue, 5 Jul 2022 13:44:27 +0300 Subject: [PATCH 03/24] added changeset --- .changeset/strong-geckos-divide.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .changeset/strong-geckos-divide.md diff --git a/.changeset/strong-geckos-divide.md b/.changeset/strong-geckos-divide.md new file mode 100644 index 000000000..b1df84674 --- /dev/null +++ b/.changeset/strong-geckos-divide.md @@ -0,0 +1,28 @@ +--- +"@changesets/assemble-release-plan": minor +"@changesets/cli": minor +"@changesets/config": minor +"@changesets/types": minor +--- + +Added a new config option: `snapshotPreidTemplate` for customizing the way snapshot release numbers are being composed. + +### Available placeholders + +You can use the following placeholders for customizing the snapshot release version: + +- `{tag}` - name of the tag, as specified in `--snapshot something` +- `{commit}` - the Git commit ID +- `{timestamp}` - Unix timestamp of the time of the release +- `{datetime}` - date and time of the release (14 characters, for example: `20211213000730`) + +> Note: if you are using `--snapshot` with empty tag name, you cannot use `{tag}` as placeholder - this will result in error. + +### Integration with `useCalculatedVersionForSnapshots` + +You can still use and pass `useCalculatedVersionForSnapshots: boolean` if you wish to have the snapshot releases to based on the planned release of changesets, instead of `0.0.0`. + +### Legacy mode + +If you are not specifying `snapshotPreidTemplate`, the defualt behaviour will fallback to use the following template: `{tag}-{datetime}`, and in cases where tag is empty (`--snapshot` with no tag name), it will use `{datetime}` only. + From 198bbe105d1282a3569873896e27a66bc75d590f Mon Sep 17 00:00:00 2001 From: Dotan Simha Date: Tue, 5 Jul 2022 15:08:07 +0300 Subject: [PATCH 04/24] fix lint --- .changeset/strong-geckos-divide.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.changeset/strong-geckos-divide.md b/.changeset/strong-geckos-divide.md index b1df84674..7284fdbe3 100644 --- a/.changeset/strong-geckos-divide.md +++ b/.changeset/strong-geckos-divide.md @@ -5,7 +5,7 @@ "@changesets/types": minor --- -Added a new config option: `snapshotPreidTemplate` for customizing the way snapshot release numbers are being composed. +Added a new config option: `snapshotPreidTemplate` for customizing the way snapshot release numbers are being composed. ### Available placeholders @@ -13,7 +13,7 @@ You can use the following placeholders for customizing the snapshot release vers - `{tag}` - name of the tag, as specified in `--snapshot something` - `{commit}` - the Git commit ID -- `{timestamp}` - Unix timestamp of the time of the release +- `{timestamp}` - Unix timestamp of the time of the release - `{datetime}` - date and time of the release (14 characters, for example: `20211213000730`) > Note: if you are using `--snapshot` with empty tag name, you cannot use `{tag}` as placeholder - this will result in error. @@ -25,4 +25,3 @@ You can still use and pass `useCalculatedVersionForSnapshots: boolean` if you wi ### Legacy mode If you are not specifying `snapshotPreidTemplate`, the defualt behaviour will fallback to use the following template: `{tag}-{datetime}`, and in cases where tag is empty (`--snapshot` with no tag name), it will use `{datetime}` only. - From ae64c8fb40cb2dfbfd08fa0d18c5dccb98392371 Mon Sep 17 00:00:00 2001 From: Dotan Simha Date: Tue, 5 Jul 2022 15:14:44 +0300 Subject: [PATCH 05/24] fix ts build issues --- packages/apply-release-plan/src/index.test.ts | 54 ++++++++++++------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/packages/apply-release-plan/src/index.test.ts b/packages/apply-release-plan/src/index.test.ts index af36aa2d1..dce2171af 100644 --- a/packages/apply-release-plan/src/index.test.ts +++ b/packages/apply-release-plan/src/index.test.ts @@ -52,7 +52,8 @@ class FakeReleasePlan { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null }, ...config }; @@ -90,7 +91,8 @@ async function testSetup( ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } }; } @@ -491,7 +493,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -554,7 +557,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -744,7 +748,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -829,7 +834,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -906,7 +912,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -983,7 +990,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -1063,7 +1071,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -1148,7 +1157,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -1225,7 +1235,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -1302,7 +1313,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -1383,7 +1395,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: true, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -1545,7 +1558,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -1650,7 +1664,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -1735,7 +1750,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -1824,7 +1840,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); @@ -1927,7 +1944,8 @@ describe("apply release plan", () => { ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", - useCalculatedVersionForSnapshots: false + useCalculatedVersionForSnapshots: false, + snapshotPreidTemplate: null } } ); From b777f5796c43f3bc41f25d1977dd44b56c162a3a Mon Sep 17 00:00:00 2001 From: Dotan Simha Date: Wed, 6 Jul 2022 09:25:52 +0300 Subject: [PATCH 06/24] moved experimental docs to a new file added docs for all existing experimental flags fixed typos --- .changeset/strong-geckos-divide.md | 18 -------- .vscode/settings.json | 10 ++++- README.md | 1 + docs/experimental-options.md | 50 +++++++++++++++++++++ packages/assemble-release-plan/src/index.ts | 2 +- 5 files changed, 60 insertions(+), 21 deletions(-) create mode 100644 docs/experimental-options.md diff --git a/.changeset/strong-geckos-divide.md b/.changeset/strong-geckos-divide.md index 7284fdbe3..5f87e58cd 100644 --- a/.changeset/strong-geckos-divide.md +++ b/.changeset/strong-geckos-divide.md @@ -7,21 +7,3 @@ Added a new config option: `snapshotPreidTemplate` for customizing the way snapshot release numbers are being composed. -### Available placeholders - -You can use the following placeholders for customizing the snapshot release version: - -- `{tag}` - name of the tag, as specified in `--snapshot something` -- `{commit}` - the Git commit ID -- `{timestamp}` - Unix timestamp of the time of the release -- `{datetime}` - date and time of the release (14 characters, for example: `20211213000730`) - -> Note: if you are using `--snapshot` with empty tag name, you cannot use `{tag}` as placeholder - this will result in error. - -### Integration with `useCalculatedVersionForSnapshots` - -You can still use and pass `useCalculatedVersionForSnapshots: boolean` if you wish to have the snapshot releases to based on the planned release of changesets, instead of `0.0.0`. - -### Legacy mode - -If you are not specifying `snapshotPreidTemplate`, the defualt behaviour will fallback to use the following template: `{tag}-{datetime}`, and in cases where tag is empty (`--snapshot` with no tag name), it will use `{datetime}` only. diff --git a/.vscode/settings.json b/.vscode/settings.json index 55712c19f..22012885b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,9 @@ { - "typescript.tsdk": "node_modules/typescript/lib" -} \ No newline at end of file + "typescript.tsdk": "node_modules/typescript/lib", + "grammarly.selectors": [ + { + "language": "markdown", + "scheme": "file" + } + ] +} diff --git a/README.md b/README.md index ad8139c75..648d46b4a 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ To make releasing easier, you can use [this changesets github action](https://gi - [Prereleases](./docs/prereleases.md) - [Problems publishing in monorepos](./docs/problems-publishing-in-monorepos.md) - [Snapshot releases](./docs/snapshot-releases.md) +- [Experimental Options](./docs/experimental-options.md) ## Cool Projects already using Changesets for versioning and changelogs diff --git a/docs/experimental-options.md b/docs/experimental-options.md new file mode 100644 index 000000000..53d5befa9 --- /dev/null +++ b/docs/experimental-options.md @@ -0,0 +1,50 @@ +# Experimental Options + +All experimental options are configured in `config.json` under `___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH` flag. + +> Please use these experimental flags with caution, and please pay attention to release notes - these config flags might change in patch versions. + +## `updateInternalDependents` (type: `'out-of-range' | 'always'`) + +Default value: `out-of-range`. + +The config flag can be used to add dependent packages to the release (if they are not already a part of it) with patch bumps. + +## `onlyUpdatePeerDependentsWhenOutOfRange` (type: `boolean`) + +Default value: `false` + +When set to `true`, Changesets will only bump peer dependents when `peerDependencies` are leaving the range. + +## `useCalculatedVersionForSnapshots` (type: `boolean`) + +Default value: `false` + +When `changesets version --snapshot` is used, the default behavior is to use `0.0.0` as the base version for the snapshot release. + +Setting `useCalculatedVersionForSnapshots: true` will change the default behavior and will the planned version, based on the changesets files. + +## `snapshotPreidTemplate` (type: `string | undefined`) + +Default value: `undefined` (see note below) + +Configures the suffix for the snapshot releases, using a template with placeholders. + +### Available placeholders + +You can use the following placeholders for customizing the snapshot release version: + +- `{tag}` - the name of the snapshot tag, as specified in `--snapshot something` +- `{commit}` - the Git commit ID +- `{timestamp}` - Unix timestamp of the time of the release +- `{datetime}` - date and time of the release (14 characters, for example, `20211213000730`) + +> Note: if you are using `--snapshot` with empty tag name, you cannot use `{tag}` as placeholder - this will result in error. + +### Integration with `useCalculatedVersionForSnapshots` + +You can still use and pass `useCalculatedVersionForSnapshots: boolean` if you wish to have the snapshot releases based on the planned release of changesets, instead of `0.0.0`. + +### Default behavior + +If you are not specifying `snapshotPreidTemplate`, the default behavior will fall back to using the following template: `{tag}-{datetime}`, and in cases where the tag is empty (`--snapshot` with no tag name), it will use `{datetime}` only. diff --git a/packages/assemble-release-plan/src/index.ts b/packages/assemble-release-plan/src/index.ts index f337152a5..0e7b24696 100644 --- a/packages/assemble-release-plan/src/index.ts +++ b/packages/assemble-release-plan/src/index.ts @@ -94,7 +94,7 @@ function assembleReleasePlan( preState: PreState | undefined, // snapshot: undefined -> not using snaphot // snapshot: { tag: undefined } -> --snapshot (empty tag) - // snapsgot: { tag: "canary" } -> --snapshot canary + // snapshot: { tag: "canary" } -> --snapshot canary snapshot?: { tag: string | undefined; commit: string; From 4703ca3d94179502d88a4c93203d4dab5addda95 Mon Sep 17 00:00:00 2001 From: Dotan Simha Date: Wed, 6 Jul 2022 09:27:42 +0300 Subject: [PATCH 07/24] use regex for replacing placeholders --- packages/assemble-release-plan/src/index.ts | 8 ++++---- packages/cli/src/commands/version/version.test.ts | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/assemble-release-plan/src/index.ts b/packages/assemble-release-plan/src/index.ts index 0e7b24696..753bbe7d9 100644 --- a/packages/assemble-release-plan/src/index.ts +++ b/packages/assemble-release-plan/src/index.ts @@ -58,10 +58,10 @@ function getSnapshotVersion( return [baseVersion, legacySuffix].join("-"); } else { const composedSuffix = snapshotParameters.preidTemplate - .replace("{timestamp}", snapshotParameters.timestamp) - .replace("{datetime}", snapshotParameters.datetime) - .replace("{commit}", snapshotParameters.commit) - .replace("{tag}", () => { + .replace(/\{timestamp\}/g, snapshotParameters.timestamp) + .replace(/\{datetime\}/g, snapshotParameters.datetime) + .replace(/\{commit\}/g, snapshotParameters.commit) + .replace(/\{tag\}/g, () => { if (snapshotParameters.tag === undefined) { throw new Error( 'Failed to compose snapshot version: "{tag}" placeholder is used without specifying a tag name' diff --git a/packages/cli/src/commands/version/version.test.ts b/packages/cli/src/commands/version/version.test.ts index 2cbab1e2e..a7f186e60 100644 --- a/packages/cli/src/commands/version/version.test.ts +++ b/packages/cli/src/commands/version/version.test.ts @@ -792,6 +792,7 @@ describe("snapshot release", () => { it.each([ // Template-based ["{tag}", "test", "0.0.0-test"], + ["{tag}-{tag}", "test", "0.0.0-test-test"], ["{commit}", "test", "0.0.0-abcdef"], ["{timestamp}", "test", "0.0.0-1639354050879"], ["{datetime}", "test", "0.0.0-20211213000730"], From ec232f493c395d15c77c9945d9a7eabcbe1a598d Mon Sep 17 00:00:00 2001 From: Dotan Simha Date: Wed, 6 Jul 2022 09:32:54 +0300 Subject: [PATCH 08/24] improve Date mocks in tests --- .../cli/src/commands/version/version.test.ts | 234 ++++++++++-------- 1 file changed, 130 insertions(+), 104 deletions(-) diff --git a/packages/cli/src/commands/version/version.test.ts b/packages/cli/src/commands/version/version.test.ts index a7f186e60..e87bd4b21 100644 --- a/packages/cli/src/commands/version/version.test.ts +++ b/packages/cli/src/commands/version/version.test.ts @@ -13,15 +13,25 @@ import pre from "../pre"; import version from "./index"; import humanId from "human-id"; -global.Date = class MockDate extends Date { - constructor() { - super("2021-12-13T00:07:30.879Z"); - } +function mockGlobalDate(fixedDate: string = "2021-12-13T00:07:30.879Z") { + const originalDate = global.Date; + + class MockedDate extends Date { + constructor() { + super(fixedDate); + } - static now() { - return new MockDate().getTime(); + static now() { + return new MockedDate().getTime(); + } } -} as any; + + global.Date = MockedDate as any; + + return () => { + global.Date = originalDate; + }; +} const f = fixtures(__dirname); @@ -727,42 +737,48 @@ describe("snapshot release", () => { }); it("should not bump version of an ignored package when its dependency gets updated", async () => { - const cwd = await f.copy("simple-project"); - await writeChangeset( - { - releases: [{ name: "pkg-b", type: "major" }], - summary: "a very useful summary" - }, - cwd - ); - - await version( - cwd, - { - snapshot: true - }, - { - ...modifiedDefaultConfig, - ignore: ["pkg-a"] - } - ); + const clearMock = mockGlobalDate(); - expect((await getPackages(cwd)).packages.map(x => x.packageJson)) - .toMatchInlineSnapshot(` - Array [ - Object { - "dependencies": Object { - "pkg-b": "0.0.0-20211213000730", - }, - "name": "pkg-a", - "version": "1.0.0", + try { + const cwd = await f.copy("simple-project"); + await writeChangeset( + { + releases: [{ name: "pkg-b", type: "major" }], + summary: "a very useful summary" }, - Object { - "name": "pkg-b", - "version": "0.0.0-20211213000730", + cwd + ); + + await version( + cwd, + { + snapshot: true }, - ] - `); + { + ...modifiedDefaultConfig, + ignore: ["pkg-a"] + } + ); + + expect((await getPackages(cwd)).packages.map(x => x.packageJson)) + .toMatchInlineSnapshot(` + Array [ + Object { + "dependencies": Object { + "pkg-b": "0.0.0-20211213000730", + }, + "name": "pkg-a", + "version": "1.0.0", + }, + Object { + "name": "pkg-b", + "version": "0.0.0-20211213000730", + }, + ] + `); + } finally { + clearMock(); + } }); describe("snapshotPreidTemplate", () => { @@ -810,35 +826,40 @@ describe("snapshot release", () => { ])( "should customize release correctly based on snapshotPreidTemplate template: %p (tag: '%p')", async (snapshotTemplate, snapshotValue, expectedResult) => { - let cwd = f.copy("simple-project"); - await writeChangesets([simpleChangeset2], cwd); - const spy = jest.spyOn(fs, "writeFile"); - await version( - cwd, - { snapshot: snapshotValue }, - { - ...modifiedDefaultConfig, - commit: false, - ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { - ...modifiedDefaultConfig.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH, - snapshotPreidTemplate: snapshotTemplate as string + const clearMock = mockGlobalDate(); + try { + let cwd = f.copy("simple-project"); + await writeChangesets([simpleChangeset2], cwd); + const spy = jest.spyOn(fs, "writeFile"); + await version( + cwd, + { snapshot: snapshotValue }, + { + ...modifiedDefaultConfig, + commit: false, + ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { + ...modifiedDefaultConfig.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH, + snapshotPreidTemplate: snapshotTemplate as string + } } - } - ); - - expect(getPkgJSON("pkg-a", spy.mock.calls)).toEqual( - expect.objectContaining({ - name: "pkg-a", - version: expectedResult - }) - ); - - expect(getPkgJSON("pkg-b", spy.mock.calls)).toEqual( - expect.objectContaining({ - name: "pkg-b", - version: expectedResult - }) - ); + ); + + expect(getPkgJSON("pkg-a", spy.mock.calls)).toEqual( + expect.objectContaining({ + name: "pkg-a", + version: expectedResult + }) + ); + + expect(getPkgJSON("pkg-b", spy.mock.calls)).toEqual( + expect.objectContaining({ + name: "pkg-b", + version: expectedResult + }) + ); + } finally { + clearMock(); + } } ); }); @@ -920,46 +941,51 @@ describe("snapshot release", () => { }); it("should not bump version of an ignored package when its dependency gets updated", async () => { - const cwd = await f.copy("simple-project"); - await writeChangeset( - { - releases: [{ name: "pkg-b", type: "major" }], - summary: "a very useful summary" - }, - cwd - ); + const clearMock = mockGlobalDate(); + try { + const cwd = await f.copy("simple-project"); + await writeChangeset( + { + releases: [{ name: "pkg-b", type: "major" }], + summary: "a very useful summary" + }, + cwd + ); - await version( - cwd, - { - snapshot: true - }, - { - ...modifiedDefaultConfig, - ignore: ["pkg-a"], - ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { - ...modifiedDefaultConfig.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH, - useCalculatedVersionForSnapshots: true + await version( + cwd, + { + snapshot: true + }, + { + ...modifiedDefaultConfig, + ignore: ["pkg-a"], + ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { + ...modifiedDefaultConfig.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH, + useCalculatedVersionForSnapshots: true + } } - } - ); + ); - expect((await getPackages(cwd)).packages.map(x => x.packageJson)) - .toMatchInlineSnapshot(` - Array [ - Object { - "dependencies": Object { - "pkg-b": "2.0.0-20211213000730", + expect((await getPackages(cwd)).packages.map(x => x.packageJson)) + .toMatchInlineSnapshot(` + Array [ + Object { + "dependencies": Object { + "pkg-b": "2.0.0-20211213000730", + }, + "name": "pkg-a", + "version": "1.0.0", }, - "name": "pkg-a", - "version": "1.0.0", - }, - Object { - "name": "pkg-b", - "version": "2.0.0-20211213000730", - }, - ] - `); + Object { + "name": "pkg-b", + "version": "2.0.0-20211213000730", + }, + ] + `); + } finally { + clearMock(); + } }); }); }); From 5692abbf9ce4850034cdb1e5ca86c8ef354de848 Mon Sep 17 00:00:00 2001 From: Dotan Simha Date: Wed, 6 Jul 2022 09:44:47 +0300 Subject: [PATCH 09/24] prevent `--snapshot name` without `{tag}` placeholder --- packages/assemble-release-plan/src/index.ts | 9 ++++++ .../cli/src/commands/version/version.test.ts | 29 +++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/packages/assemble-release-plan/src/index.ts b/packages/assemble-release-plan/src/index.ts index 753bbe7d9..321da108e 100644 --- a/packages/assemble-release-plan/src/index.ts +++ b/packages/assemble-release-plan/src/index.ts @@ -57,6 +57,15 @@ function getSnapshotVersion( return [baseVersion, legacySuffix].join("-"); } else { + if ( + !snapshotParameters.preidTemplate.includes("{tag}") && + snapshotParameters.tag !== undefined + ) { + throw new Error( + `Failed to compose snapshot version: "{tag}" placeholder is missing, but "--snapshot ${snapshotParameters.tag}" is set. Please make sure to use it to avoid versioning issues.` + ); + } + const composedSuffix = snapshotParameters.preidTemplate .replace(/\{timestamp\}/g, snapshotParameters.timestamp) .replace(/\{datetime\}/g, snapshotParameters.datetime) diff --git a/packages/cli/src/commands/version/version.test.ts b/packages/cli/src/commands/version/version.test.ts index e87bd4b21..482583005 100644 --- a/packages/cli/src/commands/version/version.test.ts +++ b/packages/cli/src/commands/version/version.test.ts @@ -805,13 +805,36 @@ describe("snapshot release", () => { ); }); + it('should throw an error when "{tag}" is set and named snapshot is used', async () => { + let cwd = f.copy("simple-project"); + await writeChangesets([simpleChangeset2], cwd); + jest.spyOn(fs, "writeFile"); + + expect( + version( + cwd, + { snapshot: "test" }, + { + ...modifiedDefaultConfig, + commit: false, + ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { + ...modifiedDefaultConfig.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH, + snapshotPreidTemplate: `{commit}` + } + } + ) + ).rejects.toThrow( + 'Failed to compose snapshot version: "{tag}" placeholder is missing, but "--snapshot test" is set. Please make sure to use it to avoid versioning issues.' + ); + }); + it.each([ // Template-based ["{tag}", "test", "0.0.0-test"], ["{tag}-{tag}", "test", "0.0.0-test-test"], - ["{commit}", "test", "0.0.0-abcdef"], - ["{timestamp}", "test", "0.0.0-1639354050879"], - ["{datetime}", "test", "0.0.0-20211213000730"], + ["{commit}", true, "0.0.0-abcdef"], + ["{timestamp}", true, "0.0.0-1639354050879"], + ["{datetime}", true, "0.0.0-20211213000730"], // Mixing template and static string [ "{tag}.{timestamp}.{commit}", From 0a639c368d82c9e419c8c57b1269705f2fe828d8 Mon Sep 17 00:00:00 2001 From: Dotan Simha Date: Wed, 6 Jul 2022 09:46:32 +0300 Subject: [PATCH 10/24] fix lint --- .changeset/strong-geckos-divide.md | 1 - docs/experimental-options.md | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.changeset/strong-geckos-divide.md b/.changeset/strong-geckos-divide.md index 5f87e58cd..1bc87d0b9 100644 --- a/.changeset/strong-geckos-divide.md +++ b/.changeset/strong-geckos-divide.md @@ -6,4 +6,3 @@ --- Added a new config option: `snapshotPreidTemplate` for customizing the way snapshot release numbers are being composed. - diff --git a/docs/experimental-options.md b/docs/experimental-options.md index 53d5befa9..cfe78a713 100644 --- a/docs/experimental-options.md +++ b/docs/experimental-options.md @@ -1,8 +1,8 @@ # Experimental Options -All experimental options are configured in `config.json` under `___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH` flag. +All experimental options are configured in `config.json` under `___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH` flag. -> Please use these experimental flags with caution, and please pay attention to release notes - these config flags might change in patch versions. +> Please use these experimental flags with caution, and please pay attention to release notes - these config flags might change in patch versions. ## `updateInternalDependents` (type: `'out-of-range' | 'always'`) @@ -16,11 +16,11 @@ Default value: `false` When set to `true`, Changesets will only bump peer dependents when `peerDependencies` are leaving the range. -## `useCalculatedVersionForSnapshots` (type: `boolean`) +## `useCalculatedVersionForSnapshots` (type: `boolean`) Default value: `false` -When `changesets version --snapshot` is used, the default behavior is to use `0.0.0` as the base version for the snapshot release. +When `changesets version --snapshot` is used, the default behavior is to use `0.0.0` as the base version for the snapshot release. Setting `useCalculatedVersionForSnapshots: true` will change the default behavior and will the planned version, based on the changesets files. From 255d1229dfc3bfce694c0458d869faa3dc9e6764 Mon Sep 17 00:00:00 2001 From: Dotan Simha Date: Thu, 7 Jul 2022 08:05:04 +0300 Subject: [PATCH 11/24] Allow `--snapshot-preid-template` in cli --- .changeset/quick-squids-dance.md | 5 +++++ packages/cli/src/index.ts | 5 ++++- packages/cli/src/run.ts | 5 +++++ packages/cli/src/types.ts | 1 + 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 .changeset/quick-squids-dance.md diff --git a/.changeset/quick-squids-dance.md b/.changeset/quick-squids-dance.md new file mode 100644 index 000000000..7e310e933 --- /dev/null +++ b/.changeset/quick-squids-dance.md @@ -0,0 +1,5 @@ +--- +"@changesets/cli": minor +--- + +Added a new config flag for `changesets version --snapshot` mode: `--snapshot-preid-template` diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index f11778b3c..9b83ec9cf 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -11,7 +11,7 @@ const { input, flags } = meow( Commands init add [--empty] [--open] - version [--ignore] [--snapshot ] + version [--ignore] [--snapshot ] [--snapshot-preid-template