From 626cfdfc386ce610fa40d452be705862370cb9eb Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 7 Nov 2021 10:54:44 +0800 Subject: [PATCH 01/31] Tag private packages when their version changes --- .changeset/fast-jars-thank.md | 5 ++ .changeset/khaki-kangaroos-tie.md | 5 ++ .../publish/__tests__/releaseCommand.test.ts | 13 ++-- packages/cli/src/commands/publish/index.ts | 40 ++++++++++--- .../src/commands/publish/publishPackages.ts | 59 +++++++++++++++++-- packages/git/src/index.test.ts | 18 ++++++ packages/git/src/index.ts | 9 +++ 7 files changed, 130 insertions(+), 19 deletions(-) create mode 100644 .changeset/fast-jars-thank.md create mode 100644 .changeset/khaki-kangaroos-tie.md diff --git a/.changeset/fast-jars-thank.md b/.changeset/fast-jars-thank.md new file mode 100644 index 000000000..7dc8763e6 --- /dev/null +++ b/.changeset/fast-jars-thank.md @@ -0,0 +1,5 @@ +--- +"@changesets/cli": minor +--- + +Private packages will now be tagged in the same way public packages do when they are published to npm diff --git a/.changeset/khaki-kangaroos-tie.md b/.changeset/khaki-kangaroos-tie.md new file mode 100644 index 000000000..55e5cfa74 --- /dev/null +++ b/.changeset/khaki-kangaroos-tie.md @@ -0,0 +1,5 @@ +--- +"@changesets/git": minor +--- + +Add tagExists git helper diff --git a/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts b/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts index 4e4aecad0..f8291af7a 100644 --- a/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts +++ b/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts @@ -22,10 +22,15 @@ git.tag.mockImplementation(() => Promise.resolve(true)); // @ts-ignore publishPackages.mockImplementation(() => - Promise.resolve([ - { name: "pkg-a", newVersion: "1.1.0", published: true }, - { name: "pkg-b", newVersion: "1.0.1", published: true }, - ]) + Promise.resolve({ + publishedPackages: [ + { name: "pkg-a", newVersion: "1.1.0", published: true }, + { name: "pkg-b", newVersion: "1.0.1", published: true }, + ], + untaggedPrivatePackages: [ + { name: "project-a", newVersion: "2.0.5", published: true }, + ] + }) ); describe("running release", () => { diff --git a/packages/cli/src/commands/publish/index.ts b/packages/cli/src/commands/publish/index.ts index 377d5e47c..a823aa862 100644 --- a/packages/cli/src/commands/publish/index.ts +++ b/packages/cli/src/commands/publish/index.ts @@ -66,36 +66,58 @@ export default async function run( tag: releaseTag, }); - const successful = response.filter((p) => p.published); - const unsuccessful = response.filter((p) => !p.published); + const successfulNpmPublishes = response.publishedPackages.filter( + (p) => p.published + ); + const unsuccessfulNpmPublishes = response.publishedPackages.filter( + (p) => !p.published + ); + const untaggedPrivatePackages = response.untaggedPrivatePackages; - if (successful.length > 0) { + if (successfulNpmPublishes.length > 0) { success("packages published successfully:"); - logReleases(successful); + logReleases(successfulNpmPublishes); if (gitTag) { // We create the tags after the push above so that we know that HEAD won't change and that pushing // won't suffer from a race condition if another merge happens in the mean time (pushing tags won't // fail if we are behind the base branch). - log(`Creating git tag${successful.length > 1 ? "s" : ""}...`); + log(`Creating git tag${successfulNpmPublishes.length > 1 ? "s" : ""}...`); if (tool !== "root") { - for (const pkg of successful) { + for (const pkg of successfulNpmPublishes) { const tag = `${pkg.name}@${pkg.newVersion}`; log("New tag: ", tag); await git.tag(tag, cwd); } } else { - const tag = `v${successful[0].newVersion}`; + const tag = `v${successfulNpmPublishes[0].newVersion}`; log("New tag: ", tag); await git.tag(tag, cwd); } } } - if (unsuccessful.length > 0) { + if (untaggedPrivatePackages.length > 0) { + success("found untagged projects:"); + logReleases(untaggedPrivatePackages); + + if (tool !== "root") { + for (const pkg of untaggedPrivatePackages) { + const tag = `${pkg.name}@${pkg.newVersion}`; + log("New tag: ", tag); + await git.tag(tag, cwd); + } + } else { + const tag = `v${untaggedPrivatePackages[0].newVersion}`; + log("New tag: ", tag); + await git.tag(tag, cwd); + } + } + + if (unsuccessfulNpmPublishes.length > 0) { error("packages failed to publish:"); - logReleases(unsuccessful); + logReleases(unsuccessfulNpmPublishes); throw new ExitError(1); } } diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index 02fce7625..68ae2a472 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -1,6 +1,7 @@ import { join } from "path"; import semver from "semver"; import chalk from "chalk"; +import * as git from "@changesets/git"; import { AccessType } from "@changesets/types"; import { Package } from "@manypkg/get-packages"; import { info, warn } from "@changesets/logger"; @@ -85,9 +86,13 @@ export default async function publishPackages({ otp?: string; preState: PreState | undefined; tag?: string; -}) { +}): Promise<{ + publishedPackages: PublishedResult[]; + untaggedPrivatePackages: PublishedResult[]; +}> { const packagesByName = new Map(packages.map((x) => [x.packageJson.name, x])); const publicPackages = packages.filter((pkg) => !pkg.packageJson.private); + const privatePackages = packages.filter(pkg => pkg.packageJson.private); const twoFactorState: TwoFactorState = getTwoFactorState({ otp, publicPackages, @@ -97,11 +102,7 @@ export default async function publishPackages({ preState ); - if (unpublishedPackagesInfo.length === 0) { - warn("No unpublished packages to publish"); - } - - return Promise.all( + const npmPackagePublish = Promise.all( unpublishedPackagesInfo.map((pkgInfo) => { let pkg = packagesByName.get(pkgInfo.name)!; return publishAPackage( @@ -112,6 +113,52 @@ export default async function publishPackages({ ); }) ); + + const untaggedPrivatePackageReleases = getUntaggedPrivatePackages( + privatePackages + ); + + const result: { + publishedPackages: PublishedResult[]; + untaggedPrivatePackages: PublishedResult[]; + } = { + publishedPackages: await npmPackagePublish, + untaggedPrivatePackages: await untaggedPrivatePackageReleases + }; + + if ( + result.publishedPackages.length === 0 && + result.untaggedPrivatePackages.length === 0 + ) { + warn("No unpublished projects to publish"); + } + + return result; +} + +async function getUntaggedPrivatePackages(privatePackages: Package[]) { + const packageWithTags = await Promise.all( + privatePackages.map(async privatePkg => { + const tagName = `${privatePkg.packageJson.name}@${privatePkg.packageJson.version}`; + const isMissingTag = !(await git.tagExists(tagName)); + + return { pkg: privatePkg, isMissingTag }; + }) + ); + + const untagged: PublishedResult[] = []; + + for (const packageWithTag of packageWithTags) { + if (packageWithTag.isMissingTag) { + untagged.push({ + name: packageWithTag.pkg.packageJson.name, + newVersion: packageWithTag.pkg.packageJson.version, + published: false + }); + } + } + + return untagged; } async function publishAPackage( diff --git a/packages/git/src/index.test.ts b/packages/git/src/index.test.ts index 09ac3ea39..aa1893732 100644 --- a/packages/git/src/index.test.ts +++ b/packages/git/src/index.test.ts @@ -13,6 +13,7 @@ import { getChangedPackagesSinceRef, getChangedChangesetFilesSinceRef, getAllTags, + tagExists } from "./"; const f = fixtures(__dirname); @@ -226,6 +227,23 @@ describe("git", () => { }); }); + describe("tagExists", () => { + beforeEach(async () => { + await add("packages/pkg-a/package.json", cwd); + await commit("added packageA package.json", cwd); + }); + + it("returns false when no tag exists", async () => { + expect(await tagExists("tag_name")).toBe(false); + }); + + it("should create a tag for the current head", async () => { + await tag("tag_message", cwd); + + expect(await tagExists("tag_name")).toBe(false); + }); + }); + describe("getCommitsThatAddFiles", () => { it("should commit a file and get the hash of that commit", async () => { await add("packages/pkg-b/package.json", cwd); diff --git a/packages/git/src/index.ts b/packages/git/src/index.ts index 875f61b04..84e9d2573 100644 --- a/packages/git/src/index.ts +++ b/packages/git/src/index.ts @@ -281,6 +281,15 @@ export async function getChangedPackagesSinceRef({ ); } +async function tagExists(tagStr: string) { + const gitCmd = await spawn("git", ["tag", "-l", tagStr]); + const output = gitCmd.stdout.toString().trim(); + const tagExists = !!output; + return tagExists; + } + + tagExists, + export async function getCurrentCommitId({ cwd, }: { From 5686490df386ae1036e3a71b9e4b2bcd6ee238fe Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 7 Nov 2021 11:01:20 +0800 Subject: [PATCH 02/31] Fixed formatting --- packages/git/src/index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/git/src/index.ts b/packages/git/src/index.ts index 84e9d2573..37efe554a 100644 --- a/packages/git/src/index.ts +++ b/packages/git/src/index.ts @@ -282,11 +282,11 @@ export async function getChangedPackagesSinceRef({ } async function tagExists(tagStr: string) { - const gitCmd = await spawn("git", ["tag", "-l", tagStr]); - const output = gitCmd.stdout.toString().trim(); - const tagExists = !!output; - return tagExists; - } + const gitCmd = await spawn("git", ["tag", "-l", tagStr]); + const output = gitCmd.stdout.toString().trim(); + const tagExists = !!output; + return tagExists; +} tagExists, From 6d37ea52a03a1cde88160f18da2dbc406c89cba8 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Tue, 8 Feb 2022 17:31:28 +0800 Subject: [PATCH 03/31] Export tagExists function --- packages/git/src/index.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/git/src/index.ts b/packages/git/src/index.ts index 37efe554a..bb228558d 100644 --- a/packages/git/src/index.ts +++ b/packages/git/src/index.ts @@ -281,15 +281,13 @@ export async function getChangedPackagesSinceRef({ ); } -async function tagExists(tagStr: string) { +export async function tagExists(tagStr: string) { const gitCmd = await spawn("git", ["tag", "-l", tagStr]); const output = gitCmd.stdout.toString().trim(); const tagExists = !!output; return tagExists; } - tagExists, - export async function getCurrentCommitId({ cwd, }: { From 8e5354afd8aeab28a5529e6efc3c42ce2b84b5ec Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 22 May 2022 10:22:31 +0800 Subject: [PATCH 04/31] Implement config option to opt into the private packages versioning feature --- packages/cli/src/commands/publish/index.ts | 1 + packages/cli/src/commands/publish/publishPackages.ts | 12 ++++++++---- packages/config/src/index.ts | 4 ++++ packages/types/src/index.ts | 4 ++++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/commands/publish/index.ts b/packages/cli/src/commands/publish/index.ts index a823aa862..a59bea98c 100644 --- a/packages/cli/src/commands/publish/index.ts +++ b/packages/cli/src/commands/publish/index.ts @@ -64,6 +64,7 @@ export default async function run( otp, preState, tag: releaseTag, + trackPrivatePackages: config.enablePrivatePackageTracking }); const successfulNpmPublishes = response.publishedPackages.filter( diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index 68ae2a472..783c7350f 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -80,19 +80,23 @@ export default async function publishPackages({ otp, preState, tag, + trackPrivatePackages }: { packages: Package[]; access: AccessType; otp?: string; preState: PreState | undefined; tag?: string; + trackPrivatePackages: boolean; }): Promise<{ publishedPackages: PublishedResult[]; untaggedPrivatePackages: PublishedResult[]; }> { const packagesByName = new Map(packages.map((x) => [x.packageJson.name, x])); const publicPackages = packages.filter((pkg) => !pkg.packageJson.private); - const privatePackages = packages.filter(pkg => pkg.packageJson.private); + const privatePackages = packages.filter( + pkg => pkg.packageJson.private && pkg.packageJson.version + ); const twoFactorState: TwoFactorState = getTwoFactorState({ otp, publicPackages, @@ -114,9 +118,9 @@ export default async function publishPackages({ }) ); - const untaggedPrivatePackageReleases = getUntaggedPrivatePackages( - privatePackages - ); + const untaggedPrivatePackageReleases = trackPrivatePackages + ? getUntaggedPrivatePackages(privatePackages) + : Promise.resolve([]); const result: { publishedPackages: PublishedResult[]; diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 08cca2cb7..e5b588b08 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -462,7 +462,11 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { json.___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH ?.updateInternalDependents ?? "out-of-range", }, + + // TODO default this to being enabled in the next major version + enablePrivatePackageTracking: json.enablePrivatePackageTracking === true }; + return config; }; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 3a48b8224..e345c37dc 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -68,6 +68,8 @@ export type Config = { linked: Linked; access: AccessType; baseBranch: string; + /** Opt in to tracking non-npm / private packages */ + enablePrivatePackageTracking: boolean; /** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */ updateInternalDependencies: "patch" | "minor"; ignore: ReadonlyArray; @@ -90,6 +92,8 @@ export type WrittenConfig = { linked?: Linked; access?: AccessType; baseBranch?: string; + /** Opt in to tracking non-npm / private packages */ + enablePrivatePackageTracking?: boolean; /** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */ updateInternalDependencies?: "patch" | "minor"; ignore?: ReadonlyArray; From 53742d5a5c3a5d5133efee6432827c1abbfd3d9f Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 22 May 2022 10:22:39 +0800 Subject: [PATCH 05/31] Added doco on tracking private packages --- docs/versioning-apps.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 docs/versioning-apps.md diff --git a/docs/versioning-apps.md b/docs/versioning-apps.md new file mode 100644 index 000000000..7c1c487c4 --- /dev/null +++ b/docs/versioning-apps.md @@ -0,0 +1,23 @@ +# Managing applications or non-npm packages + +Changesets can also be used to manage application versions or non-npm packages (ie dotnet NuGet packages, ruby gems, etc). + +The only requirement is that the project has a package.json file to manage the versions and dependencies within the repo. + +To enable this feature set `enablePrivatePackageTracking` to `true` in your `.changesets/config.json` file. This will become + +## Setting up a package + +To enable a project to be tracked by changesets, it needs a minimal package.json with at least `name`, `private` and `version`. + +``` json +{ + "name": "my-project", + "private": true, + "version": "0.0.1" +} +``` + +## Tracking releases + +This feature relies on git tags to track releases, ensure you fetch tags before you publish. \ No newline at end of file From 60a1930fb14d3eae39314f77b9e8d0aabb64b2f4 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 22 May 2022 10:35:15 +0800 Subject: [PATCH 06/31] Fixed tests compilation --- packages/apply-release-plan/src/index.test.ts | 18 ++++++++++++++++++ packages/config/src/index.test.ts | 1 + 2 files changed, 19 insertions(+) diff --git a/packages/apply-release-plan/src/index.test.ts b/packages/apply-release-plan/src/index.test.ts index a0facff7c..1a48a959b 100644 --- a/packages/apply-release-plan/src/index.test.ts +++ b/packages/apply-release-plan/src/index.test.ts @@ -49,6 +49,7 @@ class FakeReleasePlan { baseBranch: "main", updateInternalDependencies: "patch", ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -90,6 +91,7 @@ async function testSetup( baseBranch: "main", updateInternalDependencies: "patch", ignore: [], + enablePrivatePackageTracking: true, snapshot: { useCalculatedVersion: false, prereleaseTemplate: null, @@ -493,6 +495,7 @@ describe("apply release plan", () => { access: "restricted", baseBranch: "main", updateInternalDependencies: "patch", + enablePrivatePackageTracking: true, ignore: [], ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, @@ -559,6 +562,7 @@ describe("apply release plan", () => { access: "restricted", baseBranch: "main", updateInternalDependencies: "patch", + enablePrivatePackageTracking: true, ignore: [], ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, @@ -753,6 +757,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -841,6 +846,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -921,6 +927,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1001,6 +1008,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1084,6 +1092,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1172,6 +1181,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1252,6 +1262,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1332,6 +1343,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1416,6 +1428,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "patch", ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: true, updateInternalDependents: "out-of-range", @@ -1596,6 +1609,7 @@ describe("apply release plan", () => { ], updateInternalDependencies: "patch", ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1704,6 +1718,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "patch", ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1792,6 +1807,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "minor", ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1884,6 +1900,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "minor", ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1990,6 +2007,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "minor", ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", diff --git a/packages/config/src/index.test.ts b/packages/config/src/index.test.ts index 85b1f8e79..78d9da7dd 100644 --- a/packages/config/src/index.test.ts +++ b/packages/config/src/index.test.ts @@ -65,6 +65,7 @@ let defaults = { baseBranch: "master", updateInternalDependencies: "patch", ignore: [], + enablePrivatePackageTracking: true, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", From 9d22a27b15bded1580eed470fa04ab38f82db790 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 22 May 2022 10:36:00 +0800 Subject: [PATCH 07/31] Filter package list based on tracking private packages config Fixes #620 --- .../cli/src/commands/add/createChangeset.ts | 42 +++++++++++++++++-- packages/cli/src/commands/add/index.ts | 2 +- .../publish/__tests__/publishPackages.test.ts | 1 + 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/commands/add/createChangeset.ts b/packages/cli/src/commands/add/createChangeset.ts index f5898b8f2..e6b9ec85b 100644 --- a/packages/cli/src/commands/add/createChangeset.ts +++ b/packages/cli/src/commands/add/createChangeset.ts @@ -36,7 +36,8 @@ async function confirmMajorRelease(pkgJSON: PackageJSON) { async function getPackagesToRelease( changedPackages: Array, - allPackages: Array + allPackages: Array, + trackPrivatePackages: boolean ) { function askInitialReleaseQuestion(defaultChoiceList: Array) { return cli.askCheckboxPlus( @@ -60,6 +61,20 @@ async function getPackagesToRelease( ); } + const pkgJsonsByName = getPkgJsonByName(allPackages); + + // filter out packages which changesets is not tracking + allPackages = allPackages.filter( + pkg => !isValidChangesetPackage(pkg.packageJson, trackPrivatePackages) + ); + changedPackages = changedPackages.filter( + pkgName => + !isValidChangesetPackage( + pkgJsonsByName.get(pkgName)!, + trackPrivatePackages + ) + ); + if (allPackages.length > 1) { const unchangedPackagesNames = allPackages .map(({ packageJson }) => packageJson.name) @@ -94,6 +109,25 @@ async function getPackagesToRelease( return [allPackages[0].packageJson.name]; } +function getPkgJsonByName(packages: Package[]) { + return new Map( + packages.map(({ packageJson }) => [packageJson.name, packageJson]) + ); +} + +function isValidChangesetPackage( + packageJson: PackageJSON, + trackPrivatePackages: boolean +) { + const hasVersionField = !!packageJson.version; + + if (trackPrivatePackages) { + return hasVersionField; + } + + return !packageJson.private && hasVersionField; +} + function formatPkgNameAndVersion(pkgName: string, version: string) { return `${bold(pkgName)}@${bold(version)}`; } @@ -106,14 +140,16 @@ function getPkgJsonByName(packages: Package[]) { export default async function createChangeset( changedPackages: Array, - allPackages: Package[] + allPackages: Package[], + trackPrivatePackages: boolean ): Promise<{ confirmed: boolean; summary: string; releases: Array }> { const releases: Array = []; if (allPackages.length > 1) { const packagesToRelease = await getPackagesToRelease( changedPackages, - allPackages + allPackages, + trackPrivatePackages ); let pkgJsonsByName = getPkgJsonByName(allPackages); diff --git a/packages/cli/src/commands/add/index.ts b/packages/cli/src/commands/add/index.ts index c15b90f2e..f0d6df3af 100644 --- a/packages/cli/src/commands/add/index.ts +++ b/packages/cli/src/commands/add/index.ts @@ -48,7 +48,7 @@ export default async function add( .filter((pkg) => isListablePackage(config, pkg.packageJson)) .map((pkg) => pkg.packageJson.name); - newChangeset = await createChangeset(changedPackagesName, packages); + newChangeset = await createChangeset(changedPackagesName, packages, config.enablePrivateTracking); printConfirmationMessage(newChangeset, packages.length > 1); if (!newChangeset.confirmed) { diff --git a/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts b/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts index 29ca9eb41..3a91db339 100644 --- a/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts +++ b/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts @@ -41,6 +41,7 @@ describe("publishPackages", () => { packages: (await getPackages(cwd)).packages, access: "public", preState: undefined, + trackPrivatePackages: true }); expect(npmUtils.getTokenIsRequired).not.toHaveBeenCalled(); }); From e571a0e106c711a31d43e67b47dbb93c0228bb87 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 22 May 2022 10:38:49 +0800 Subject: [PATCH 08/31] Fixed lint issue --- docs/versioning-apps.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/versioning-apps.md b/docs/versioning-apps.md index 7c1c487c4..0dc6327fe 100644 --- a/docs/versioning-apps.md +++ b/docs/versioning-apps.md @@ -4,13 +4,13 @@ Changesets can also be used to manage application versions or non-npm packages ( The only requirement is that the project has a package.json file to manage the versions and dependencies within the repo. -To enable this feature set `enablePrivatePackageTracking` to `true` in your `.changesets/config.json` file. This will become +To enable this feature set `enablePrivatePackageTracking` to `true` in your `.changesets/config.json` file. This will become ## Setting up a package To enable a project to be tracked by changesets, it needs a minimal package.json with at least `name`, `private` and `version`. -``` json +```json { "name": "my-project", "private": true, @@ -20,4 +20,4 @@ To enable a project to be tracked by changesets, it needs a minimal package.json ## Tracking releases -This feature relies on git tags to track releases, ensure you fetch tags before you publish. \ No newline at end of file +This feature relies on git tags to track releases, ensure you fetch tags before you publish. From d2f4d895edf7bc39b6a10a00b41730d38acdb442 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 22 May 2022 10:47:21 +0800 Subject: [PATCH 09/31] Fixed tests --- packages/cli/src/commands/add/createChangeset.ts | 4 ++-- packages/config/src/index.test.ts | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/commands/add/createChangeset.ts b/packages/cli/src/commands/add/createChangeset.ts index e6b9ec85b..77d3e55df 100644 --- a/packages/cli/src/commands/add/createChangeset.ts +++ b/packages/cli/src/commands/add/createChangeset.ts @@ -64,8 +64,8 @@ async function getPackagesToRelease( const pkgJsonsByName = getPkgJsonByName(allPackages); // filter out packages which changesets is not tracking - allPackages = allPackages.filter( - pkg => !isValidChangesetPackage(pkg.packageJson, trackPrivatePackages) + allPackages = allPackages.filter(pkg => + isValidChangesetPackage(pkg.packageJson, trackPrivatePackages) ); changedPackages = changedPackages.filter( pkgName => diff --git a/packages/config/src/index.test.ts b/packages/config/src/index.test.ts index 78d9da7dd..ac3dc7a98 100644 --- a/packages/config/src/index.test.ts +++ b/packages/config/src/index.test.ts @@ -45,6 +45,7 @@ test("read reads the config", async () => { updateInternalDependencies: "patch", ignore: [], bumpVersionsWithWorkspaceProtocolOnly: false, + enablePrivatePackageTracking: false, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -65,7 +66,7 @@ let defaults = { baseBranch: "master", updateInternalDependencies: "patch", ignore: [], - enablePrivatePackageTracking: true, + enablePrivatePackageTracking: false, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", From 013e96924605292be0658c9dfc8e52a0e94d2c94 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 22 May 2022 13:36:55 +0800 Subject: [PATCH 10/31] Update docs again --- README.md | 1 + docs/versioning-apps.md | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c82537068..4ba10bfd0 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) +- [Versioning applications and other non-npm packages](./docs/versioning-apps.md) - [Experimental Options](./docs/experimental-options.md) ## Cool Projects already using Changesets for versioning and changelogs diff --git a/docs/versioning-apps.md b/docs/versioning-apps.md index 0dc6327fe..21423a352 100644 --- a/docs/versioning-apps.md +++ b/docs/versioning-apps.md @@ -1,10 +1,16 @@ # Managing applications or non-npm packages -Changesets can also be used to manage application versions or non-npm packages (ie dotnet NuGet packages, ruby gems, etc). +Changesets can also be used to manage application versions or non-npm packages (ie dotnet NuGet packages, ruby gems, docker images etc). The only requirement is that the project has a package.json file to manage the versions and dependencies within the repo. -To enable this feature set `enablePrivatePackageTracking` to `true` in your `.changesets/config.json` file. This will become +To enable this feature set `enablePrivatePackageTracking` to `true` in your `.changesets/config.json` file. + +> **Note** +> Changesets only versions NPM package.json files, you can trigger releases for other package formats by creating workflows which trigger on tags/releases being created by changesets. + +> **Note** +> This feature relies on git tags to track releases, ensure you fetch tags before you publish. ## Setting up a package @@ -17,7 +23,3 @@ To enable a project to be tracked by changesets, it needs a minimal package.json "version": "0.0.1" } ``` - -## Tracking releases - -This feature relies on git tags to track releases, ensure you fetch tags before you publish. From 864472455ce9ed7abe8318411bc6c5dcf934e48b Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Mon, 23 May 2022 15:27:17 +0800 Subject: [PATCH 11/31] Remove requirement of being logged into NPM if there are no unpublished packages When only publishing private packages (apps?) we shouldn't need users to be logged into NPM --- .../cli/src/commands/publish/publishPackages.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index 783c7350f..f30f79a17 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -97,15 +97,22 @@ export default async function publishPackages({ const privatePackages = packages.filter( pkg => pkg.packageJson.private && pkg.packageJson.version ); - const twoFactorState: TwoFactorState = getTwoFactorState({ - otp, - publicPackages, - }); const unpublishedPackagesInfo = await getUnpublishedPackages( publicPackages, preState ); + const twoFactorState: TwoFactorState = + unpublishedPackagesInfo.length > 0 + ? getTwoFactorState({ + otp, + publicPackages + }) + : { + token: null, + isRequired: Promise.resolve(false) + }; + const npmPackagePublish = Promise.all( unpublishedPackagesInfo.map((pkgInfo) => { let pkg = packagesByName.get(pkgInfo.name)!; From f3c7ded24b939cab38d4c96c6e9f83d8f2c15a75 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Thu, 9 Jun 2022 10:21:03 +0800 Subject: [PATCH 12/31] Update .changeset/khaki-kangaroos-tie.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mateusz Burzyński --- .changeset/khaki-kangaroos-tie.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/khaki-kangaroos-tie.md b/.changeset/khaki-kangaroos-tie.md index 55e5cfa74..142c279c2 100644 --- a/.changeset/khaki-kangaroos-tie.md +++ b/.changeset/khaki-kangaroos-tie.md @@ -2,4 +2,4 @@ "@changesets/git": minor --- -Add tagExists git helper +Add `tagExists` git helper From 86171cb0b038c19a8f44622699695a7fc74bc12d Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Thu, 9 Jun 2022 10:22:40 +0800 Subject: [PATCH 13/31] Update packages/config/src/index.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mateusz Burzyński --- packages/config/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index e5b588b08..c73c849c8 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -463,7 +463,7 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { ?.updateInternalDependents ?? "out-of-range", }, - // TODO default this to being enabled in the next major version + // TODO consider enabling this by default in the next major version enablePrivatePackageTracking: json.enablePrivatePackageTracking === true }; From 44f2bd693453cdd34f3c04d12be644268023ef01 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Thu, 9 Jun 2022 10:26:35 +0800 Subject: [PATCH 14/31] Update packages/git/src/index.test.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mateusz Burzyński --- packages/git/src/index.test.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/git/src/index.test.ts b/packages/git/src/index.test.ts index aa1893732..1116ef087 100644 --- a/packages/git/src/index.test.ts +++ b/packages/git/src/index.test.ts @@ -228,16 +228,15 @@ describe("git", () => { }); describe("tagExists", () => { - beforeEach(async () => { + it("returns false when no tag exists", async () => { await add("packages/pkg-a/package.json", cwd); await commit("added packageA package.json", cwd); - }); - - it("returns false when no tag exists", async () => { expect(await tagExists("tag_name")).toBe(false); }); it("should create a tag for the current head", async () => { + await add("packages/pkg-a/package.json", cwd); + await commit("added packageA package.json", cwd); await tag("tag_message", cwd); expect(await tagExists("tag_name")).toBe(false); From bae290b6b54c690b060e87322c04ce10f85ab54c Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Mon, 20 Jun 2022 15:14:18 +0800 Subject: [PATCH 15/31] Use remote tag check instead of local --- .changeset/khaki-kangaroos-tie.md | 2 +- .../cli/src/commands/publish/publishPackages.ts | 2 +- packages/git/src/index.ts | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.changeset/khaki-kangaroos-tie.md b/.changeset/khaki-kangaroos-tie.md index 142c279c2..eb5dbebff 100644 --- a/.changeset/khaki-kangaroos-tie.md +++ b/.changeset/khaki-kangaroos-tie.md @@ -2,4 +2,4 @@ "@changesets/git": minor --- -Add `tagExists` git helper +Add `tagExists` & `remoteTagExists` git helpers diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index f30f79a17..7b3db66e5 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -151,7 +151,7 @@ async function getUntaggedPrivatePackages(privatePackages: Package[]) { const packageWithTags = await Promise.all( privatePackages.map(async privatePkg => { const tagName = `${privatePkg.packageJson.name}@${privatePkg.packageJson.version}`; - const isMissingTag = !(await git.tagExists(tagName)); + const isMissingTag = !(await git.remoteTagExists(tagName)); return { pkg: privatePkg, isMissingTag }; }) diff --git a/packages/git/src/index.ts b/packages/git/src/index.ts index bb228558d..81a10ced0 100644 --- a/packages/git/src/index.ts +++ b/packages/git/src/index.ts @@ -297,3 +297,16 @@ export async function getCurrentCommitId({ .toString() .trim(); } + +export async function remoteTagExists(tagStr: string) { + const gitCmd = await spawn("git", [ + "ls-remote", + "--tags", + "origin", + "-l", + tagStr + ]); + const output = gitCmd.stdout.toString().trim(); + const tagExists = !!output; + return tagExists; +} From 49614eb41fcefe7b6fc2affbaf1a8706a541c0fc Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Mon, 20 Jun 2022 16:52:35 +0800 Subject: [PATCH 16/31] Updated config to work against a privatePackages flag Allows opting into tagging private package versions & also opting out of versioning private packages entirely --- .changeset/fast-jars-thank.md | 6 ++- docs/versioning-apps.md | 5 +-- packages/apply-release-plan/src/index.test.ts | 37 ++++++++++--------- .../cli/src/commands/add/createChangeset.ts | 24 ++++++------ packages/cli/src/commands/add/index.ts | 4 +- .../publish/__tests__/publishPackages.test.ts | 2 +- packages/cli/src/commands/publish/index.ts | 11 +++++- .../src/commands/publish/publishPackages.ts | 8 ++-- packages/config/src/index.test.ts | 4 +- packages/config/src/index.ts | 8 +++- packages/types/src/index.ts | 13 +++++-- 11 files changed, 72 insertions(+), 50 deletions(-) diff --git a/.changeset/fast-jars-thank.md b/.changeset/fast-jars-thank.md index 7dc8763e6..29fa524e3 100644 --- a/.changeset/fast-jars-thank.md +++ b/.changeset/fast-jars-thank.md @@ -2,4 +2,8 @@ "@changesets/cli": minor --- -Private packages will now be tagged in the same way public packages do when they are published to npm +Private packages can now be tagged in the same way public packages do when they are published to npm. + +To enable set `privatePackages: 'version-and-tag'` in your config.json. + +You can also now opt private packages out of versioning entirely by setting `privatePackages: 'ignore'`. \ No newline at end of file diff --git a/docs/versioning-apps.md b/docs/versioning-apps.md index 21423a352..5786b9de1 100644 --- a/docs/versioning-apps.md +++ b/docs/versioning-apps.md @@ -4,14 +4,11 @@ Changesets can also be used to manage application versions or non-npm packages ( The only requirement is that the project has a package.json file to manage the versions and dependencies within the repo. -To enable this feature set `enablePrivatePackageTracking` to `true` in your `.changesets/config.json` file. +To enable this feature set `privatePackages` to `version-and-tag` in your `.changesets/config.json` file. By default changesets will only update the changelog and version > **Note** > Changesets only versions NPM package.json files, you can trigger releases for other package formats by creating workflows which trigger on tags/releases being created by changesets. -> **Note** -> This feature relies on git tags to track releases, ensure you fetch tags before you publish. - ## Setting up a package To enable a project to be tracked by changesets, it needs a minimal package.json with at least `name`, `private` and `version`. diff --git a/packages/apply-release-plan/src/index.test.ts b/packages/apply-release-plan/src/index.test.ts index 1a48a959b..529744497 100644 --- a/packages/apply-release-plan/src/index.test.ts +++ b/packages/apply-release-plan/src/index.test.ts @@ -4,6 +4,7 @@ import { Config, NewChangeset, ComprehensiveRelease, + PrivatePackages } from "@changesets/types"; import * as git from "@changesets/git"; import fs from "fs-extra"; @@ -49,7 +50,7 @@ class FakeReleasePlan { baseBranch: "main", updateInternalDependencies: "patch", ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -91,7 +92,7 @@ async function testSetup( baseBranch: "main", updateInternalDependencies: "patch", ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, snapshot: { useCalculatedVersion: false, prereleaseTemplate: null, @@ -495,7 +496,7 @@ describe("apply release plan", () => { access: "restricted", baseBranch: "main", updateInternalDependencies: "patch", - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ignore: [], ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, @@ -562,7 +563,7 @@ describe("apply release plan", () => { access: "restricted", baseBranch: "main", updateInternalDependencies: "patch", - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ignore: [], ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, @@ -757,7 +758,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -846,7 +847,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -927,7 +928,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1008,7 +1009,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1092,7 +1093,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1181,7 +1182,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1262,7 +1263,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1343,7 +1344,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1428,7 +1429,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "patch", ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: true, updateInternalDependents: "out-of-range", @@ -1609,7 +1610,7 @@ describe("apply release plan", () => { ], updateInternalDependencies: "patch", ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1718,7 +1719,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "patch", ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1807,7 +1808,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "minor", ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1900,7 +1901,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "minor", ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -2007,7 +2008,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "minor", ignore: [], - enablePrivatePackageTracking: true, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", diff --git a/packages/cli/src/commands/add/createChangeset.ts b/packages/cli/src/commands/add/createChangeset.ts index 77d3e55df..a70f09d10 100644 --- a/packages/cli/src/commands/add/createChangeset.ts +++ b/packages/cli/src/commands/add/createChangeset.ts @@ -37,7 +37,7 @@ async function confirmMajorRelease(pkgJSON: PackageJSON) { async function getPackagesToRelease( changedPackages: Array, allPackages: Array, - trackPrivatePackages: boolean + ignorePrivatePackages: boolean ) { function askInitialReleaseQuestion(defaultChoiceList: Array) { return cli.askCheckboxPlus( @@ -61,17 +61,17 @@ async function getPackagesToRelease( ); } - const pkgJsonsByName = getPkgJsonByName(allPackages); + const pkgJsonsByName = getPkgJsonsByName(allPackages); // filter out packages which changesets is not tracking allPackages = allPackages.filter(pkg => - isValidChangesetPackage(pkg.packageJson, trackPrivatePackages) + isValidChangesetPackage(pkg.packageJson, ignorePrivatePackages) ); changedPackages = changedPackages.filter( pkgName => !isValidChangesetPackage( pkgJsonsByName.get(pkgName)!, - trackPrivatePackages + ignorePrivatePackages ) ); @@ -109,7 +109,7 @@ async function getPackagesToRelease( return [allPackages[0].packageJson.name]; } -function getPkgJsonByName(packages: Package[]) { +function getPkgJsonsByName(packages: Package[]) { return new Map( packages.map(({ packageJson }) => [packageJson.name, packageJson]) ); @@ -117,15 +117,15 @@ function getPkgJsonByName(packages: Package[]) { function isValidChangesetPackage( packageJson: PackageJSON, - trackPrivatePackages: boolean + ignorePrivatePackages: boolean ) { const hasVersionField = !!packageJson.version; - if (trackPrivatePackages) { - return hasVersionField; + if (ignorePrivatePackages && packageJson.private) { + return false; } - return !packageJson.private && hasVersionField; + return hasVersionField; } function formatPkgNameAndVersion(pkgName: string, version: string) { @@ -141,7 +141,7 @@ function getPkgJsonByName(packages: Package[]) { export default async function createChangeset( changedPackages: Array, allPackages: Package[], - trackPrivatePackages: boolean + ignorePrivatePackages: boolean ): Promise<{ confirmed: boolean; summary: string; releases: Array }> { const releases: Array = []; @@ -149,10 +149,10 @@ export default async function createChangeset( const packagesToRelease = await getPackagesToRelease( changedPackages, allPackages, - trackPrivatePackages + ignorePrivatePackages ); - let pkgJsonsByName = getPkgJsonByName(allPackages); + let pkgJsonsByName = getPkgJsonsByName(allPackages); let pkgsLeftToGetBumpTypeFor = new Set(packagesToRelease); diff --git a/packages/cli/src/commands/add/index.ts b/packages/cli/src/commands/add/index.ts index f0d6df3af..d5d5a6985 100644 --- a/packages/cli/src/commands/add/index.ts +++ b/packages/cli/src/commands/add/index.ts @@ -5,7 +5,7 @@ import { spawn } from "child_process"; import * as cli from "../../utils/cli-utilities"; import * as git from "@changesets/git"; import { info, log, warn } from "@changesets/logger"; -import { Config } from "@changesets/types"; +import { Config, PrivatePackages } from "@changesets/types"; import { getPackages } from "@manypkg/get-packages"; import writeChangeset from "@changesets/write"; @@ -48,7 +48,7 @@ export default async function add( .filter((pkg) => isListablePackage(config, pkg.packageJson)) .map((pkg) => pkg.packageJson.name); - newChangeset = await createChangeset(changedPackagesName, packages, config.enablePrivateTracking); + newChangeset = await createChangeset(changedPackagesName, packages, config.privatePackages === PrivatePackages.Ignore); printConfirmationMessage(newChangeset, packages.length > 1); if (!newChangeset.confirmed) { diff --git a/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts b/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts index 3a91db339..cd0969ccf 100644 --- a/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts +++ b/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts @@ -41,7 +41,7 @@ describe("publishPackages", () => { packages: (await getPackages(cwd)).packages, access: "public", preState: undefined, - trackPrivatePackages: true + tagPrivatePackages: true }); expect(npmUtils.getTokenIsRequired).not.toHaveBeenCalled(); }); diff --git a/packages/cli/src/commands/publish/index.ts b/packages/cli/src/commands/publish/index.ts index a59bea98c..1d88817fe 100644 --- a/packages/cli/src/commands/publish/index.ts +++ b/packages/cli/src/commands/publish/index.ts @@ -3,7 +3,7 @@ import { ExitError } from "@changesets/errors"; import { error, log, success, warn } from "@changesets/logger"; import * as git from "@changesets/git"; import { readPreState } from "@changesets/pre"; -import { Config, PreState } from "@changesets/types"; +import { Config, PreState, PrivatePackages } from "@changesets/types"; import { getPackages } from "@manypkg/get-packages"; import chalk from "chalk"; @@ -64,7 +64,10 @@ export default async function run( otp, preState, tag: releaseTag, - trackPrivatePackages: config.enablePrivatePackageTracking + tagPrivatePackages: isFlagEnabled( + config.privatePackages, + PrivatePackages.Tag + ) }); const successfulNpmPublishes = response.publishedPackages.filter( @@ -122,3 +125,7 @@ export default async function run( throw new ExitError(1); } } + +function isFlagEnabled(value: number, tag: number): boolean { + return (value & tag) === tag; +} diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index 7b3db66e5..5390acc06 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -80,17 +80,17 @@ export default async function publishPackages({ otp, preState, tag, - trackPrivatePackages + tagPrivatePackages }: { packages: Package[]; access: AccessType; otp?: string; preState: PreState | undefined; tag?: string; - trackPrivatePackages: boolean; + tagPrivatePackages: boolean; }): Promise<{ publishedPackages: PublishedResult[]; - untaggedPrivatePackages: PublishedResult[]; + untaggedPrivatePackages: Omit[]; }> { const packagesByName = new Map(packages.map((x) => [x.packageJson.name, x])); const publicPackages = packages.filter((pkg) => !pkg.packageJson.private); @@ -125,7 +125,7 @@ export default async function publishPackages({ }) ); - const untaggedPrivatePackageReleases = trackPrivatePackages + const untaggedPrivatePackageReleases = tagPrivatePackages ? getUntaggedPrivatePackages(privatePackages) : Promise.resolve([]); diff --git a/packages/config/src/index.test.ts b/packages/config/src/index.test.ts index ac3dc7a98..8c5441884 100644 --- a/packages/config/src/index.test.ts +++ b/packages/config/src/index.test.ts @@ -2,7 +2,7 @@ import fixturez from "fixturez"; import { read, parse } from "./"; import jestInCase from "jest-in-case"; import * as logger from "@changesets/logger"; -import { Config, WrittenConfig } from "@changesets/types"; +import { Config, PrivatePackages, WrittenConfig } from "@changesets/types"; import { Packages } from "@manypkg/get-packages"; jest.mock("@changesets/logger"); @@ -66,7 +66,7 @@ let defaults = { baseBranch: "master", updateInternalDependencies: "patch", ignore: [], - enablePrivatePackageTracking: false, + privatePackages: PrivatePackages.VersionAndTag, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index c73c849c8..596d7ba4b 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -10,6 +10,7 @@ import { Fixed, Linked, PackageGroup, + PrivatePackages } from "@changesets/types"; import packageJson from "../package.json"; import { getDependentsGraph } from "@changesets/get-dependents-graph"; @@ -464,7 +465,12 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { }, // TODO consider enabling this by default in the next major version - enablePrivatePackageTracking: json.enablePrivatePackageTracking === true + privatePackages: + json.privatePackages === "version-without-tag" + ? PrivatePackages.Tag + : json.privatePackages === "version-and-tag" + ? PrivatePackages.VersionAndTag + : PrivatePackages.Ignore }; return config; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index e345c37dc..7f9ffcc6d 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -61,6 +61,13 @@ export type PackageGroup = ReadonlyArray; export type Fixed = ReadonlyArray; export type Linked = ReadonlyArray; +export const enum PrivatePackages { + Ignore, + Version = 1 << 1, + Tag = 1 << 2, + VersionAndTag = Version | Tag +} + export type Config = { changelog: false | readonly [string, any]; commit: false | readonly [string, any]; @@ -68,8 +75,8 @@ export type Config = { linked: Linked; access: AccessType; baseBranch: string; - /** Opt in to tracking non-npm / private packages */ - enablePrivatePackageTracking: boolean; + /** Features enabled for Private packages */ + privatePackages: PrivatePackages; /** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */ updateInternalDependencies: "patch" | "minor"; ignore: ReadonlyArray; @@ -93,7 +100,7 @@ export type WrittenConfig = { access?: AccessType; baseBranch?: string; /** Opt in to tracking non-npm / private packages */ - enablePrivatePackageTracking?: boolean; + privatePackages?: "ignore" | "version-without-tag" | "version-and-tag"; /** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */ updateInternalDependencies?: "patch" | "minor"; ignore?: ReadonlyArray; From c356ae3fed4f7143ad2e8f502a8312df3b0c1756 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Mon, 20 Jun 2022 16:59:00 +0800 Subject: [PATCH 17/31] Fixed lint error --- .changeset/fast-jars-thank.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/fast-jars-thank.md b/.changeset/fast-jars-thank.md index 29fa524e3..8960f8dcb 100644 --- a/.changeset/fast-jars-thank.md +++ b/.changeset/fast-jars-thank.md @@ -2,8 +2,8 @@ "@changesets/cli": minor --- -Private packages can now be tagged in the same way public packages do when they are published to npm. +Private packages can now be tagged in the same way public packages do when they are published to npm. To enable set `privatePackages: 'version-and-tag'` in your config.json. -You can also now opt private packages out of versioning entirely by setting `privatePackages: 'ignore'`. \ No newline at end of file +You can also now opt private packages out of versioning entirely by setting `privatePackages: 'ignore'`. From 656d28f48c53b73aabdd5855beaa6c4fcb88d287 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Fri, 24 Jun 2022 14:36:05 +0800 Subject: [PATCH 18/31] Fixed tests --- packages/apply-release-plan/src/index.test.ts | 36 +++++++++---------- packages/config/src/index.test.ts | 4 +-- packages/config/src/index.ts | 7 ++-- packages/types/src/index.ts | 18 ++++++---- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/packages/apply-release-plan/src/index.test.ts b/packages/apply-release-plan/src/index.test.ts index 529744497..7dee4025b 100644 --- a/packages/apply-release-plan/src/index.test.ts +++ b/packages/apply-release-plan/src/index.test.ts @@ -50,7 +50,7 @@ class FakeReleasePlan { baseBranch: "main", updateInternalDependencies: "patch", ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -92,7 +92,7 @@ async function testSetup( baseBranch: "main", updateInternalDependencies: "patch", ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, snapshot: { useCalculatedVersion: false, prereleaseTemplate: null, @@ -496,7 +496,7 @@ describe("apply release plan", () => { access: "restricted", baseBranch: "main", updateInternalDependencies: "patch", - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ignore: [], ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, @@ -563,7 +563,7 @@ describe("apply release plan", () => { access: "restricted", baseBranch: "main", updateInternalDependencies: "patch", - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ignore: [], ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, @@ -758,7 +758,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -847,7 +847,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -928,7 +928,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1009,7 +1009,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1093,7 +1093,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1182,7 +1182,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1263,7 +1263,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1344,7 +1344,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1429,7 +1429,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "patch", ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: true, updateInternalDependents: "out-of-range", @@ -1610,7 +1610,7 @@ describe("apply release plan", () => { ], updateInternalDependencies: "patch", ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1719,7 +1719,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "patch", ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1808,7 +1808,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "minor", ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1901,7 +1901,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "minor", ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -2008,7 +2008,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "minor", ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", diff --git a/packages/config/src/index.test.ts b/packages/config/src/index.test.ts index 8c5441884..cf90b430a 100644 --- a/packages/config/src/index.test.ts +++ b/packages/config/src/index.test.ts @@ -45,7 +45,7 @@ test("read reads the config", async () => { updateInternalDependencies: "patch", ignore: [], bumpVersionsWithWorkspaceProtocolOnly: false, - enablePrivatePackageTracking: false, + privatePackages: 1, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -66,7 +66,7 @@ let defaults = { baseBranch: "master", updateInternalDependencies: "patch", ignore: [], - privatePackages: PrivatePackages.VersionAndTag, + privatePackages: PrivatePackages.Version, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 596d7ba4b..82ace06db 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -466,11 +466,12 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { // TODO consider enabling this by default in the next major version privatePackages: - json.privatePackages === "version-without-tag" - ? PrivatePackages.Tag + json.privatePackages === "ignore" + ? PrivatePackages.Ignore : json.privatePackages === "version-and-tag" ? PrivatePackages.VersionAndTag - : PrivatePackages.Ignore + : // Default value + PrivatePackages.Version }; return config; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 7f9ffcc6d..34d5c1230 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -61,12 +61,16 @@ export type PackageGroup = ReadonlyArray; export type Fixed = ReadonlyArray; export type Linked = ReadonlyArray; -export const enum PrivatePackages { - Ignore, - Version = 1 << 1, - Tag = 1 << 2, - VersionAndTag = Version | Tag -} +/** + * bitwise flag for private packages + * Check if the flag is enabled with `(flags & PrivatePackages.Version) === PrivatePackages.Version` + */ +export const PrivatePackages = { + Ignore: 0, + Version: 1, + Tag: 2, + VersionAndTag: 3 +} as const; export type Config = { changelog: false | readonly [string, any]; @@ -76,7 +80,7 @@ export type Config = { access: AccessType; baseBranch: string; /** Features enabled for Private packages */ - privatePackages: PrivatePackages; + privatePackages: typeof PrivatePackages[keyof typeof PrivatePackages]; /** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */ updateInternalDependencies: "patch" | "minor"; ignore: ReadonlyArray; From 24f0a78a53750d38ecbf337c3c2daf6bd8e0361f Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Thu, 11 Aug 2022 19:56:41 +0800 Subject: [PATCH 19/31] Fixed linting errors --- packages/cli/src/commands/add/createChangeset.ts | 6 ------ packages/cli/src/commands/add/index.ts | 6 +++++- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/cli/src/commands/add/createChangeset.ts b/packages/cli/src/commands/add/createChangeset.ts index a70f09d10..7d76bc0ab 100644 --- a/packages/cli/src/commands/add/createChangeset.ts +++ b/packages/cli/src/commands/add/createChangeset.ts @@ -132,12 +132,6 @@ function formatPkgNameAndVersion(pkgName: string, version: string) { return `${bold(pkgName)}@${bold(version)}`; } -function getPkgJsonByName(packages: Package[]) { - return new Map( - packages.map(({ packageJson }) => [packageJson.name, packageJson]) - ); -} - export default async function createChangeset( changedPackages: Array, allPackages: Package[], diff --git a/packages/cli/src/commands/add/index.ts b/packages/cli/src/commands/add/index.ts index d5d5a6985..9cfc17f18 100644 --- a/packages/cli/src/commands/add/index.ts +++ b/packages/cli/src/commands/add/index.ts @@ -48,7 +48,11 @@ export default async function add( .filter((pkg) => isListablePackage(config, pkg.packageJson)) .map((pkg) => pkg.packageJson.name); - newChangeset = await createChangeset(changedPackagesName, packages, config.privatePackages === PrivatePackages.Ignore); + newChangeset = await createChangeset( + changedPackagesName, + packages, + config.privatePackages === PrivatePackages.Ignore + ); printConfirmationMessage(newChangeset, packages.length > 1); if (!newChangeset.confirmed) { From f17508ad9c4179f5bf18e0bc71752192d6cdd94d Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 25 Sep 2022 10:13:15 +0800 Subject: [PATCH 20/31] Update packages/cli/src/commands/publish/publishPackages.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mateusz Burzyński --- packages/cli/src/commands/publish/publishPackages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index 5390acc06..60a6adeca 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -151,7 +151,7 @@ async function getUntaggedPrivatePackages(privatePackages: Package[]) { const packageWithTags = await Promise.all( privatePackages.map(async privatePkg => { const tagName = `${privatePkg.packageJson.name}@${privatePkg.packageJson.version}`; - const isMissingTag = !(await git.remoteTagExists(tagName)); + const isMissingTag = !(await git.tagExists(tagName) || await git.remoteTagExists(tagName)); return { pkg: privatePkg, isMissingTag }; }) From 3886e90ca24cf7a95384f49b516a18d206a117b9 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 25 Sep 2022 10:16:20 +0800 Subject: [PATCH 21/31] Update packages/cli/src/commands/add/createChangeset.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mateusz Burzyński --- packages/cli/src/commands/add/createChangeset.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/commands/add/createChangeset.ts b/packages/cli/src/commands/add/createChangeset.ts index 7d76bc0ab..723324c86 100644 --- a/packages/cli/src/commands/add/createChangeset.ts +++ b/packages/cli/src/commands/add/createChangeset.ts @@ -115,7 +115,7 @@ function getPkgJsonsByName(packages: Package[]) { ); } -function isValidChangesetPackage( +function canPackageBeVersioned( packageJson: PackageJSON, ignorePrivatePackages: boolean ) { From c062b16317d963ec03f64f2315d8df44249f6a9f Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Mon, 26 Sep 2022 09:13:07 +0800 Subject: [PATCH 22/31] Fixed duplication of logic when filtering listable packages --- .../cli/src/commands/add/createChangeset.ts | 22 +++---------------- packages/cli/src/commands/add/index.ts | 9 +------- .../cli/src/commands/add/isListablePackage.ts | 17 ++++++++++++++ 3 files changed, 21 insertions(+), 27 deletions(-) create mode 100644 packages/cli/src/commands/add/isListablePackage.ts diff --git a/packages/cli/src/commands/add/createChangeset.ts b/packages/cli/src/commands/add/createChangeset.ts index 723324c86..91e8ce0d0 100644 --- a/packages/cli/src/commands/add/createChangeset.ts +++ b/packages/cli/src/commands/add/createChangeset.ts @@ -7,6 +7,7 @@ import { error, log } from "@changesets/logger"; import { Release, PackageJSON } from "@changesets/types"; import { Package } from "@manypkg/get-packages"; import { ExitError } from "@changesets/errors"; +import { isListablePackage } from "./isListablePackage"; const { green, yellow, red, bold, blue, cyan } = chalk; @@ -65,14 +66,10 @@ async function getPackagesToRelease( // filter out packages which changesets is not tracking allPackages = allPackages.filter(pkg => - isValidChangesetPackage(pkg.packageJson, ignorePrivatePackages) + isListablePackage(config, pkg.packageJson) ); changedPackages = changedPackages.filter( - pkgName => - !isValidChangesetPackage( - pkgJsonsByName.get(pkgName)!, - ignorePrivatePackages - ) + pkgName => !isListablePackage(config, pkgJsonsByName.get(pkgName)!) ); if (allPackages.length > 1) { @@ -115,19 +112,6 @@ function getPkgJsonsByName(packages: Package[]) { ); } -function canPackageBeVersioned( - packageJson: PackageJSON, - ignorePrivatePackages: boolean -) { - const hasVersionField = !!packageJson.version; - - if (ignorePrivatePackages && packageJson.private) { - return false; - } - - return hasVersionField; -} - function formatPkgNameAndVersion(pkgName: string, version: string) { return `${bold(pkgName)}@${bold(version)}`; } diff --git a/packages/cli/src/commands/add/index.ts b/packages/cli/src/commands/add/index.ts index 9cfc17f18..5cd81b4a0 100644 --- a/packages/cli/src/commands/add/index.ts +++ b/packages/cli/src/commands/add/index.ts @@ -13,14 +13,7 @@ import { getCommitFunctions } from "../../commit/getCommitFunctions"; import createChangeset from "./createChangeset"; import printConfirmationMessage from "./messages"; import { ExternalEditor } from "external-editor"; -import { PackageJSON } from "@changesets/types"; - -function isListablePackage(config: Config, packageJson: PackageJSON) { - return ( - !config.ignore.includes(packageJson.name) && - (packageJson.version || !packageJson.private) - ); -} +import { isListablePackage } from "./isListablePackage"; export default async function add( cwd: string, diff --git a/packages/cli/src/commands/add/isListablePackage.ts b/packages/cli/src/commands/add/isListablePackage.ts new file mode 100644 index 000000000..16d17c177 --- /dev/null +++ b/packages/cli/src/commands/add/isListablePackage.ts @@ -0,0 +1,17 @@ +import { Config } from "@changesets/types"; +import { PackageJSON } from "@changesets/types"; + +export function isListablePackage(config: Config, packageJson: PackageJSON) { + const packageIgnoredInConfig = config.ignore.includes(packageJson.name); + + if (packageIgnoredInConfig) { + return false; + } + + if (!config.privatePackages && packageJson.private) { + return false; + } + + const hasVersionField = !!packageJson.version; + return hasVersionField; +} From f0ece838b53d310b3c48be8ed7ef468865ae1fb2 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Mon, 26 Sep 2022 09:14:26 +0800 Subject: [PATCH 23/31] Removed flags enum and simplified config --- packages/apply-release-plan/src/index.test.ts | 39 +++++++++---------- .../cli/src/commands/add/createChangeset.ts | 8 ++-- packages/cli/src/commands/add/index.ts | 8 +--- packages/cli/src/commands/publish/index.ts | 11 +----- .../src/commands/publish/publishPackages.ts | 4 +- packages/config/src/index.test.ts | 13 ++++--- packages/config/src/index.ts | 16 ++++---- packages/types/src/index.ts | 21 +++++----- 8 files changed, 54 insertions(+), 66 deletions(-) diff --git a/packages/apply-release-plan/src/index.test.ts b/packages/apply-release-plan/src/index.test.ts index 7dee4025b..1b18d4ac8 100644 --- a/packages/apply-release-plan/src/index.test.ts +++ b/packages/apply-release-plan/src/index.test.ts @@ -3,8 +3,7 @@ import { ReleasePlan, Config, NewChangeset, - ComprehensiveRelease, - PrivatePackages + ComprehensiveRelease } from "@changesets/types"; import * as git from "@changesets/git"; import fs from "fs-extra"; @@ -50,7 +49,7 @@ class FakeReleasePlan { baseBranch: "main", updateInternalDependencies: "patch", ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -92,7 +91,7 @@ async function testSetup( baseBranch: "main", updateInternalDependencies: "patch", ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, snapshot: { useCalculatedVersion: false, prereleaseTemplate: null, @@ -496,7 +495,7 @@ describe("apply release plan", () => { access: "restricted", baseBranch: "main", updateInternalDependencies: "patch", - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ignore: [], ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, @@ -563,7 +562,7 @@ describe("apply release plan", () => { access: "restricted", baseBranch: "main", updateInternalDependencies: "patch", - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ignore: [], ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, @@ -758,7 +757,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -847,7 +846,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -928,7 +927,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1009,7 +1008,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1093,7 +1092,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1182,7 +1181,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1263,7 +1262,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1344,7 +1343,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies, ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1429,7 +1428,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "patch", ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: true, updateInternalDependents: "out-of-range", @@ -1610,7 +1609,7 @@ describe("apply release plan", () => { ], updateInternalDependencies: "patch", ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1719,7 +1718,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "patch", ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1808,7 +1807,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "minor", ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -1901,7 +1900,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "minor", ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -2008,7 +2007,7 @@ describe("apply release plan", () => { baseBranch: "main", updateInternalDependencies: "minor", ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", diff --git a/packages/cli/src/commands/add/createChangeset.ts b/packages/cli/src/commands/add/createChangeset.ts index 91e8ce0d0..e5011eb1b 100644 --- a/packages/cli/src/commands/add/createChangeset.ts +++ b/packages/cli/src/commands/add/createChangeset.ts @@ -4,7 +4,7 @@ import semver from "semver"; import * as cli from "../../utils/cli-utilities"; import { error, log } from "@changesets/logger"; -import { Release, PackageJSON } from "@changesets/types"; +import { Release, PackageJSON, Config } from "@changesets/types"; import { Package } from "@manypkg/get-packages"; import { ExitError } from "@changesets/errors"; import { isListablePackage } from "./isListablePackage"; @@ -38,7 +38,7 @@ async function confirmMajorRelease(pkgJSON: PackageJSON) { async function getPackagesToRelease( changedPackages: Array, allPackages: Array, - ignorePrivatePackages: boolean + config: Config ) { function askInitialReleaseQuestion(defaultChoiceList: Array) { return cli.askCheckboxPlus( @@ -119,7 +119,7 @@ function formatPkgNameAndVersion(pkgName: string, version: string) { export default async function createChangeset( changedPackages: Array, allPackages: Package[], - ignorePrivatePackages: boolean + config: Config ): Promise<{ confirmed: boolean; summary: string; releases: Array }> { const releases: Array = []; @@ -127,7 +127,7 @@ export default async function createChangeset( const packagesToRelease = await getPackagesToRelease( changedPackages, allPackages, - ignorePrivatePackages + config ); let pkgJsonsByName = getPkgJsonsByName(allPackages); diff --git a/packages/cli/src/commands/add/index.ts b/packages/cli/src/commands/add/index.ts index 5cd81b4a0..269ddac46 100644 --- a/packages/cli/src/commands/add/index.ts +++ b/packages/cli/src/commands/add/index.ts @@ -5,7 +5,7 @@ import { spawn } from "child_process"; import * as cli from "../../utils/cli-utilities"; import * as git from "@changesets/git"; import { info, log, warn } from "@changesets/logger"; -import { Config, PrivatePackages } from "@changesets/types"; +import { Config } from "@changesets/types"; import { getPackages } from "@manypkg/get-packages"; import writeChangeset from "@changesets/write"; @@ -41,11 +41,7 @@ export default async function add( .filter((pkg) => isListablePackage(config, pkg.packageJson)) .map((pkg) => pkg.packageJson.name); - newChangeset = await createChangeset( - changedPackagesName, - packages, - config.privatePackages === PrivatePackages.Ignore - ); + newChangeset = await createChangeset(changedPackagesName, packages, config); printConfirmationMessage(newChangeset, packages.length > 1); if (!newChangeset.confirmed) { diff --git a/packages/cli/src/commands/publish/index.ts b/packages/cli/src/commands/publish/index.ts index 1d88817fe..7089cefce 100644 --- a/packages/cli/src/commands/publish/index.ts +++ b/packages/cli/src/commands/publish/index.ts @@ -3,7 +3,7 @@ import { ExitError } from "@changesets/errors"; import { error, log, success, warn } from "@changesets/logger"; import * as git from "@changesets/git"; import { readPreState } from "@changesets/pre"; -import { Config, PreState, PrivatePackages } from "@changesets/types"; +import { Config, PreState } from "@changesets/types"; import { getPackages } from "@manypkg/get-packages"; import chalk from "chalk"; @@ -64,10 +64,7 @@ export default async function run( otp, preState, tag: releaseTag, - tagPrivatePackages: isFlagEnabled( - config.privatePackages, - PrivatePackages.Tag - ) + tagPrivatePackages: config.privatePackages && config.privatePackages.tag }); const successfulNpmPublishes = response.publishedPackages.filter( @@ -125,7 +122,3 @@ export default async function run( throw new ExitError(1); } } - -function isFlagEnabled(value: number, tag: number): boolean { - return (value & tag) === tag; -} diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index 60a6adeca..9c9966122 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -151,7 +151,9 @@ async function getUntaggedPrivatePackages(privatePackages: Package[]) { const packageWithTags = await Promise.all( privatePackages.map(async privatePkg => { const tagName = `${privatePkg.packageJson.name}@${privatePkg.packageJson.version}`; - const isMissingTag = !(await git.tagExists(tagName) || await git.remoteTagExists(tagName)); + const isMissingTag = !( + (await git.tagExists(tagName)) || (await git.remoteTagExists(tagName)) + ); return { pkg: privatePkg, isMissingTag }; }) diff --git a/packages/config/src/index.test.ts b/packages/config/src/index.test.ts index cf90b430a..02bb4d049 100644 --- a/packages/config/src/index.test.ts +++ b/packages/config/src/index.test.ts @@ -2,7 +2,7 @@ import fixturez from "fixturez"; import { read, parse } from "./"; import jestInCase from "jest-in-case"; import * as logger from "@changesets/logger"; -import { Config, PrivatePackages, WrittenConfig } from "@changesets/types"; +import { Config, WrittenConfig } from "@changesets/types"; import { Packages } from "@manypkg/get-packages"; jest.mock("@changesets/logger"); @@ -45,7 +45,10 @@ test("read reads the config", async () => { updateInternalDependencies: "patch", ignore: [], bumpVersionsWithWorkspaceProtocolOnly: false, - privatePackages: 1, + privatePackages: { + tag: false, + version: true + }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -57,7 +60,7 @@ test("read reads the config", async () => { }); }); -let defaults = { +let defaults: Config = { fixed: [], linked: [], changelog: ["@changesets/cli/changelog", null], @@ -66,7 +69,7 @@ let defaults = { baseBranch: "master", updateInternalDependencies: "patch", ignore: [], - privatePackages: PrivatePackages.Version, + privatePackages: { version: true, tag: false }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, updateInternalDependents: "out-of-range", @@ -76,7 +79,7 @@ let defaults = { prereleaseTemplate: null, }, bumpVersionsWithWorkspaceProtocolOnly: false, -} as const; +}; let correctCases: Record = { defaults: { diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 82ace06db..1f71b4af5 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -9,8 +9,7 @@ import { WrittenConfig, Fixed, Linked, - PackageGroup, - PrivatePackages + PackageGroup } from "@changesets/types"; import packageJson from "../package.json"; import { getDependentsGraph } from "@changesets/get-dependents-graph"; @@ -465,13 +464,12 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { }, // TODO consider enabling this by default in the next major version - privatePackages: - json.privatePackages === "ignore" - ? PrivatePackages.Ignore - : json.privatePackages === "version-and-tag" - ? PrivatePackages.VersionAndTag - : // Default value - PrivatePackages.Version + privatePackages: json.privatePackages + ? { + version: json.privatePackages.version ?? true, + tag: json.privatePackages.tag ?? false + } + : { version: true, tag: false } }; return config; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 34d5c1230..e92d50e9e 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -61,16 +61,10 @@ export type PackageGroup = ReadonlyArray; export type Fixed = ReadonlyArray; export type Linked = ReadonlyArray; -/** - * bitwise flag for private packages - * Check if the flag is enabled with `(flags & PrivatePackages.Version) === PrivatePackages.Version` - */ -export const PrivatePackages = { - Ignore: 0, - Version: 1, - Tag: 2, - VersionAndTag: 3 -} as const; +export interface PrivatePackages { + version: boolean; + tag: boolean; +} export type Config = { changelog: false | readonly [string, any]; @@ -80,7 +74,7 @@ export type Config = { access: AccessType; baseBranch: string; /** Features enabled for Private packages */ - privatePackages: typeof PrivatePackages[keyof typeof PrivatePackages]; + privatePackages: false | PrivatePackages; /** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */ updateInternalDependencies: "patch" | "minor"; ignore: ReadonlyArray; @@ -104,7 +98,10 @@ export type WrittenConfig = { access?: AccessType; baseBranch?: string; /** Opt in to tracking non-npm / private packages */ - privatePackages?: "ignore" | "version-without-tag" | "version-and-tag"; + privatePackages?: { + version?: boolean; + tag?: boolean; + }; /** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */ updateInternalDependencies?: "patch" | "minor"; ignore?: ReadonlyArray; From 4dd972e0213fc53aba79182ab8c25c85a3c6f55a Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Mon, 26 Sep 2022 09:25:35 +0800 Subject: [PATCH 24/31] Added cwd to tagExists and fixed tests --- .../publish/__tests__/publishPackages.test.ts | 1 + packages/cli/src/commands/publish/index.ts | 1 + packages/cli/src/commands/publish/publishPackages.ts | 12 +++++++++--- packages/git/src/index.test.ts | 7 ++++--- packages/git/src/index.ts | 4 ++-- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts b/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts index cd0969ccf..8aa00e08a 100644 --- a/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts +++ b/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts @@ -38,6 +38,7 @@ describe("publishPackages", () => { describe("when isCI", () => { it("does not call out to npm to see if otp is required", async () => { await publishPackages({ + cwd, packages: (await getPackages(cwd)).packages, access: "public", preState: undefined, diff --git a/packages/cli/src/commands/publish/index.ts b/packages/cli/src/commands/publish/index.ts index 7089cefce..d83ace6d8 100644 --- a/packages/cli/src/commands/publish/index.ts +++ b/packages/cli/src/commands/publish/index.ts @@ -58,6 +58,7 @@ export default async function run( const { packages, tool } = await getPackages(cwd); const response = await publishPackages({ + cwd, packages, // if not public, we won't pass the access, and it works as normal access: config.access, diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index 9c9966122..9d43c3a07 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -75,6 +75,7 @@ const getTwoFactorState = ({ }; export default async function publishPackages({ + cwd, packages, access, otp, @@ -82,6 +83,7 @@ export default async function publishPackages({ tag, tagPrivatePackages }: { + cwd: string; packages: Package[]; access: AccessType; otp?: string; @@ -126,7 +128,7 @@ export default async function publishPackages({ ); const untaggedPrivatePackageReleases = tagPrivatePackages - ? getUntaggedPrivatePackages(privatePackages) + ? getUntaggedPrivatePackages(privatePackages, cwd) : Promise.resolve([]); const result: { @@ -147,12 +149,16 @@ export default async function publishPackages({ return result; } -async function getUntaggedPrivatePackages(privatePackages: Package[]) { +async function getUntaggedPrivatePackages( + privatePackages: Package[], + cwd: string +) { const packageWithTags = await Promise.all( privatePackages.map(async privatePkg => { const tagName = `${privatePkg.packageJson.name}@${privatePkg.packageJson.version}`; const isMissingTag = !( - (await git.tagExists(tagName)) || (await git.remoteTagExists(tagName)) + (await git.tagExists(tagName, cwd)) || + (await git.remoteTagExists(tagName)) ); return { pkg: privatePkg, isMissingTag }; diff --git a/packages/git/src/index.test.ts b/packages/git/src/index.test.ts index 1116ef087..c78f2a8c2 100644 --- a/packages/git/src/index.test.ts +++ b/packages/git/src/index.test.ts @@ -231,15 +231,16 @@ describe("git", () => { it("returns false when no tag exists", async () => { await add("packages/pkg-a/package.json", cwd); await commit("added packageA package.json", cwd); - expect(await tagExists("tag_name")).toBe(false); + + expect(await tagExists("tag_which_doesn't_exist", cwd)).toBe(false); }); - it("should create a tag for the current head", async () => { + it("returns true when tag exists", async () => { await add("packages/pkg-a/package.json", cwd); await commit("added packageA package.json", cwd); await tag("tag_message", cwd); - expect(await tagExists("tag_name")).toBe(false); + expect(await tagExists("tag_message", cwd)).toBe(true); }); }); diff --git a/packages/git/src/index.ts b/packages/git/src/index.ts index 81a10ced0..2e4c8322b 100644 --- a/packages/git/src/index.ts +++ b/packages/git/src/index.ts @@ -281,8 +281,8 @@ export async function getChangedPackagesSinceRef({ ); } -export async function tagExists(tagStr: string) { - const gitCmd = await spawn("git", ["tag", "-l", tagStr]); +export async function tagExists(tagStr: string, cwd: string) { + const gitCmd = await spawn("git", ["tag", "-l", tagStr], { cwd }); const output = gitCmd.stdout.toString().trim(); const tagExists = !!output; return tagExists; From 60472900af11c1fbffb5129f72507be0c86c2e3d Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Mon, 26 Sep 2022 09:36:21 +0800 Subject: [PATCH 25/31] Hoist tagging private packages out of publish package --- .../publish/__tests__/publishPackages.test.ts | 4 +- .../publish/__tests__/releaseCommand.test.ts | 15 ++-- .../publish/getUntaggedPrivatePackages.ts | 34 +++++++++ packages/cli/src/commands/publish/index.ts | 39 ++++++---- .../src/commands/publish/publishPackages.ts | 71 ++----------------- 5 files changed, 68 insertions(+), 95 deletions(-) create mode 100644 packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts diff --git a/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts b/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts index 8aa00e08a..a35155563 100644 --- a/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts +++ b/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts @@ -38,11 +38,9 @@ describe("publishPackages", () => { describe("when isCI", () => { it("does not call out to npm to see if otp is required", async () => { await publishPackages({ - cwd, packages: (await getPackages(cwd)).packages, access: "public", - preState: undefined, - tagPrivatePackages: true + preState: undefined }); expect(npmUtils.getTokenIsRequired).not.toHaveBeenCalled(); }); diff --git a/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts b/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts index f8291af7a..611627aa3 100644 --- a/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts +++ b/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts @@ -22,15 +22,10 @@ git.tag.mockImplementation(() => Promise.resolve(true)); // @ts-ignore publishPackages.mockImplementation(() => - Promise.resolve({ - publishedPackages: [ - { name: "pkg-a", newVersion: "1.1.0", published: true }, - { name: "pkg-b", newVersion: "1.0.1", published: true }, - ], - untaggedPrivatePackages: [ - { name: "project-a", newVersion: "2.0.5", published: true }, - ] - }) + Promise.resolve([ + { name: "pkg-a", newVersion: "1.1.0", published: true }, + { name: "pkg-b", newVersion: "1.0.1", published: true } + ]) ); describe("running release", () => { @@ -38,7 +33,7 @@ describe("running release", () => { let cwd: string; beforeEach(async () => { - cwd = await f.copy("simple-project"); + cwd = f.copy("simple-project"); }); describe("When there is no changeset commits", () => { diff --git a/packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts b/packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts new file mode 100644 index 000000000..001e967cb --- /dev/null +++ b/packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts @@ -0,0 +1,34 @@ +import * as git from "@changesets/git"; +import { Package } from "@manypkg/get-packages"; +import { PublishedResult } from "./publishPackages"; + +export async function getUntaggedPrivatePackages( + privatePackages: Package[], + cwd: string +) { + const packageWithTags = await Promise.all( + privatePackages.map(async privatePkg => { + const tagName = `${privatePkg.packageJson.name}@${privatePkg.packageJson.version}`; + const isMissingTag = !( + (await git.tagExists(tagName, cwd)) || + (await git.remoteTagExists(tagName)) + ); + + return { pkg: privatePkg, isMissingTag }; + }) + ); + + const untagged: PublishedResult[] = []; + + for (const packageWithTag of packageWithTags) { + if (packageWithTag.isMissingTag) { + untagged.push({ + name: packageWithTag.pkg.packageJson.name, + newVersion: packageWithTag.pkg.packageJson.version, + published: false + }); + } + } + + return untagged; +} diff --git a/packages/cli/src/commands/publish/index.ts b/packages/cli/src/commands/publish/index.ts index d83ace6d8..86a3b341f 100644 --- a/packages/cli/src/commands/publish/index.ts +++ b/packages/cli/src/commands/publish/index.ts @@ -6,6 +6,7 @@ import { readPreState } from "@changesets/pre"; import { Config, PreState } from "@changesets/types"; import { getPackages } from "@manypkg/get-packages"; import chalk from "chalk"; +import { getUntaggedPrivatePackages } from "./getUntaggedPrivatePackages"; function logReleases(pkgs: Array<{ name: string; newVersion: string }>) { const mappedPkgs = pkgs.map((p) => `${p.name}@${p.newVersion}`).join("\n"); @@ -57,24 +58,32 @@ export default async function run( const { packages, tool } = await getPackages(cwd); - const response = await publishPackages({ - cwd, + const tagPrivatePackages = + config.privatePackages && config.privatePackages.tag; + const publishedPackages = await publishPackages({ packages, // if not public, we won't pass the access, and it works as normal access: config.access, otp, preState, - tag: releaseTag, - tagPrivatePackages: config.privatePackages && config.privatePackages.tag + tag: releaseTag }); - - const successfulNpmPublishes = response.publishedPackages.filter( - (p) => p.published - ); - const unsuccessfulNpmPublishes = response.publishedPackages.filter( - (p) => !p.published + const privatePackages = packages.filter( + pkg => pkg.packageJson.private && pkg.packageJson.version ); - const untaggedPrivatePackages = response.untaggedPrivatePackages; + const untaggedPrivatePackageReleases = tagPrivatePackages + ? await getUntaggedPrivatePackages(privatePackages, cwd) + : []; + + if ( + publishedPackages.length === 0 && + untaggedPrivatePackageReleases.length === 0 + ) { + warn("No unpublished projects to publish"); + } + + const successfulNpmPublishes = publishedPackages.filter(p => p.published); + const unsuccessfulNpmPublishes = publishedPackages.filter(p => !p.published); if (successfulNpmPublishes.length > 0) { success("packages published successfully:"); @@ -99,18 +108,18 @@ export default async function run( } } - if (untaggedPrivatePackages.length > 0) { + if (untaggedPrivatePackageReleases.length > 0) { success("found untagged projects:"); - logReleases(untaggedPrivatePackages); + logReleases(untaggedPrivatePackageReleases); if (tool !== "root") { - for (const pkg of untaggedPrivatePackages) { + for (const pkg of untaggedPrivatePackageReleases) { const tag = `${pkg.name}@${pkg.newVersion}`; log("New tag: ", tag); await git.tag(tag, cwd); } } else { - const tag = `v${untaggedPrivatePackages[0].newVersion}`; + const tag = `v${untaggedPrivatePackageReleases[0].newVersion}`; log("New tag: ", tag); await git.tag(tag, cwd); } diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index 9d43c3a07..3a7a9e6ee 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -1,7 +1,6 @@ import { join } from "path"; import semver from "semver"; import chalk from "chalk"; -import * as git from "@changesets/git"; import { AccessType } from "@changesets/types"; import { Package } from "@manypkg/get-packages"; import { info, warn } from "@changesets/logger"; @@ -19,7 +18,7 @@ type PkgInfo = { publishedVersions: string[]; }; -type PublishedResult = { +export type PublishedResult = { name: string; newVersion: string; published: boolean; @@ -75,30 +74,20 @@ const getTwoFactorState = ({ }; export default async function publishPackages({ - cwd, packages, access, otp, preState, - tag, - tagPrivatePackages + tag }: { - cwd: string; packages: Package[]; access: AccessType; otp?: string; preState: PreState | undefined; tag?: string; - tagPrivatePackages: boolean; -}): Promise<{ - publishedPackages: PublishedResult[]; - untaggedPrivatePackages: Omit[]; -}> { +}) { const packagesByName = new Map(packages.map((x) => [x.packageJson.name, x])); const publicPackages = packages.filter((pkg) => !pkg.packageJson.private); - const privatePackages = packages.filter( - pkg => pkg.packageJson.private && pkg.packageJson.version - ); const unpublishedPackagesInfo = await getUnpublishedPackages( publicPackages, preState @@ -115,7 +104,7 @@ export default async function publishPackages({ isRequired: Promise.resolve(false) }; - const npmPackagePublish = Promise.all( + return Promise.all( unpublishedPackagesInfo.map((pkgInfo) => { let pkg = packagesByName.get(pkgInfo.name)!; return publishAPackage( @@ -126,58 +115,6 @@ export default async function publishPackages({ ); }) ); - - const untaggedPrivatePackageReleases = tagPrivatePackages - ? getUntaggedPrivatePackages(privatePackages, cwd) - : Promise.resolve([]); - - const result: { - publishedPackages: PublishedResult[]; - untaggedPrivatePackages: PublishedResult[]; - } = { - publishedPackages: await npmPackagePublish, - untaggedPrivatePackages: await untaggedPrivatePackageReleases - }; - - if ( - result.publishedPackages.length === 0 && - result.untaggedPrivatePackages.length === 0 - ) { - warn("No unpublished projects to publish"); - } - - return result; -} - -async function getUntaggedPrivatePackages( - privatePackages: Package[], - cwd: string -) { - const packageWithTags = await Promise.all( - privatePackages.map(async privatePkg => { - const tagName = `${privatePkg.packageJson.name}@${privatePkg.packageJson.version}`; - const isMissingTag = !( - (await git.tagExists(tagName, cwd)) || - (await git.remoteTagExists(tagName)) - ); - - return { pkg: privatePkg, isMissingTag }; - }) - ); - - const untagged: PublishedResult[] = []; - - for (const packageWithTag of packageWithTags) { - if (packageWithTag.isMissingTag) { - untagged.push({ - name: packageWithTag.pkg.packageJson.name, - newVersion: packageWithTag.pkg.packageJson.version, - published: false - }); - } - } - - return untagged; } async function publishAPackage( From 2f158d546f73d634f5d9d13fd3888d204a9a08f1 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Thu, 29 Sep 2022 12:14:49 +0800 Subject: [PATCH 26/31] Addressed feedback --- .changeset/fast-jars-thank.md | 4 +- docs/versioning-apps.md | 2 +- .../cli/src/commands/add/__tests__/add.ts | 14 +++--- .../cli/src/commands/add/createChangeset.ts | 22 ++------- packages/cli/src/commands/add/index.ts | 2 +- .../publish/getUntaggedPrivatePackages.ts | 10 ++-- packages/cli/src/commands/publish/index.ts | 47 +++++++++---------- .../src/commands/publish/publishPackages.ts | 18 ++++--- packages/config/schema.json | 14 ++++++ 9 files changed, 68 insertions(+), 65 deletions(-) diff --git a/.changeset/fast-jars-thank.md b/.changeset/fast-jars-thank.md index 8960f8dcb..d2700b194 100644 --- a/.changeset/fast-jars-thank.md +++ b/.changeset/fast-jars-thank.md @@ -4,6 +4,6 @@ Private packages can now be tagged in the same way public packages do when they are published to npm. -To enable set `privatePackages: 'version-and-tag'` in your config.json. +To enable set `privatePackages: { version: true, tag: true }` in your config.json. -You can also now opt private packages out of versioning entirely by setting `privatePackages: 'ignore'`. +You can also now opt private packages out of versioning entirely by setting `privatePackages: false`. diff --git a/docs/versioning-apps.md b/docs/versioning-apps.md index 5786b9de1..6a3e08950 100644 --- a/docs/versioning-apps.md +++ b/docs/versioning-apps.md @@ -4,7 +4,7 @@ Changesets can also be used to manage application versions or non-npm packages ( The only requirement is that the project has a package.json file to manage the versions and dependencies within the repo. -To enable this feature set `privatePackages` to `version-and-tag` in your `.changesets/config.json` file. By default changesets will only update the changelog and version +To enable this feature set `privatePackages` to `{ version: true, tag: true }` in your `.changesets/config.json` file. By default changesets will only update the changelog and version (ie `{ version: true, tag: false }`). > **Note** > Changesets only versions NPM package.json files, you can trigger releases for other package formats by creating workflows which trigger on tags/releases being created by changesets. diff --git a/packages/cli/src/commands/add/__tests__/add.ts b/packages/cli/src/commands/add/__tests__/add.ts index 78f8d8138..833e2ce30 100644 --- a/packages/cli/src/commands/add/__tests__/add.ts +++ b/packages/cli/src/commands/add/__tests__/add.ts @@ -116,7 +116,7 @@ describe("Changesets", () => { "should read summary", // @ts-ignore async ({ consoleSummaries, editorSummaries, expectedSummary }) => { - const cwd = await f.copy("simple-project"); + const cwd = f.copy("simple-project"); mockUserResponses({ releases: { "pkg-a": "patch" }, @@ -137,7 +137,7 @@ describe("Changesets", () => { ); it("should generate a changeset in a single package repo", async () => { - const cwd = await f.copy("single-package"); + const cwd = f.copy("single-package"); const summary = "summary message mock"; @@ -175,7 +175,7 @@ describe("Changesets", () => { }); it("should commit when the commit flag is passed in", async () => { - const cwd = await f.copy("simple-project-custom-config"); + const cwd = f.copy("simple-project-custom-config"); mockUserResponses({ releases: { "pkg-a": "patch" } }); await addChangeset( @@ -191,7 +191,7 @@ describe("Changesets", () => { }); it("should create empty changeset when empty flag is passed in", async () => { - const cwd = await f.copy("simple-project"); + const cwd = f.copy("simple-project"); await addChangeset(cwd, { empty: true }, defaultConfig); @@ -204,8 +204,9 @@ describe("Changesets", () => { }) ); }); + it("should not include ignored packages in the prompt", async () => { - const cwd = await f.copy("internal-dependencies"); + const cwd = f.copy("internal-dependencies"); mockUserResponses({ releases: { "pkg-a": "patch" } }); await addChangeset( @@ -218,8 +219,9 @@ describe("Changesets", () => { const { choices } = askCheckboxPlus.mock.calls[0][1][0]; expect(choices).toEqual(["pkg-a", "pkg-c"]); }); + it("should not include private packages without a version in the prompt", async () => { - const cwd = await f.copy("private-package-without-version-field"); + const cwd = f.copy("private-package-without-version-field"); mockUserResponses({ releases: { "pkg-a": "patch" } }); await addChangeset(cwd, { empty: false }, defaultConfig); diff --git a/packages/cli/src/commands/add/createChangeset.ts b/packages/cli/src/commands/add/createChangeset.ts index e5011eb1b..c6bb0bfd9 100644 --- a/packages/cli/src/commands/add/createChangeset.ts +++ b/packages/cli/src/commands/add/createChangeset.ts @@ -4,10 +4,9 @@ import semver from "semver"; import * as cli from "../../utils/cli-utilities"; import { error, log } from "@changesets/logger"; -import { Release, PackageJSON, Config } from "@changesets/types"; +import { Release, PackageJSON } from "@changesets/types"; import { Package } from "@manypkg/get-packages"; import { ExitError } from "@changesets/errors"; -import { isListablePackage } from "./isListablePackage"; const { green, yellow, red, bold, blue, cyan } = chalk; @@ -37,8 +36,7 @@ async function confirmMajorRelease(pkgJSON: PackageJSON) { async function getPackagesToRelease( changedPackages: Array, - allPackages: Array, - config: Config + allPackages: Array ) { function askInitialReleaseQuestion(defaultChoiceList: Array) { return cli.askCheckboxPlus( @@ -62,16 +60,6 @@ async function getPackagesToRelease( ); } - const pkgJsonsByName = getPkgJsonsByName(allPackages); - - // filter out packages which changesets is not tracking - allPackages = allPackages.filter(pkg => - isListablePackage(config, pkg.packageJson) - ); - changedPackages = changedPackages.filter( - pkgName => !isListablePackage(config, pkgJsonsByName.get(pkgName)!) - ); - if (allPackages.length > 1) { const unchangedPackagesNames = allPackages .map(({ packageJson }) => packageJson.name) @@ -118,16 +106,14 @@ function formatPkgNameAndVersion(pkgName: string, version: string) { export default async function createChangeset( changedPackages: Array, - allPackages: Package[], - config: Config + allPackages: Package[] ): Promise<{ confirmed: boolean; summary: string; releases: Array }> { const releases: Array = []; if (allPackages.length > 1) { const packagesToRelease = await getPackagesToRelease( changedPackages, - allPackages, - config + allPackages ); let pkgJsonsByName = getPkgJsonsByName(allPackages); diff --git a/packages/cli/src/commands/add/index.ts b/packages/cli/src/commands/add/index.ts index 269ddac46..9352aa483 100644 --- a/packages/cli/src/commands/add/index.ts +++ b/packages/cli/src/commands/add/index.ts @@ -41,7 +41,7 @@ export default async function add( .filter((pkg) => isListablePackage(config, pkg.packageJson)) .map((pkg) => pkg.packageJson.name); - newChangeset = await createChangeset(changedPackagesName, packages, config); + newChangeset = await createChangeset(changedPackagesName, packages); printConfirmationMessage(newChangeset, packages.length > 1); if (!newChangeset.confirmed) { diff --git a/packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts b/packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts index 001e967cb..b81526e28 100644 --- a/packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts +++ b/packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts @@ -1,14 +1,18 @@ import * as git from "@changesets/git"; -import { Package } from "@manypkg/get-packages"; +import { Package, Tool } from "@manypkg/get-packages"; import { PublishedResult } from "./publishPackages"; export async function getUntaggedPrivatePackages( privatePackages: Package[], - cwd: string + cwd: string, + tool: Tool ) { const packageWithTags = await Promise.all( privatePackages.map(async privatePkg => { - const tagName = `${privatePkg.packageJson.name}@${privatePkg.packageJson.version}`; + const tagName = + tool === "root" + ? `v${privatePkg.packageJson.version}` + : `${privatePkg.packageJson.name}@${privatePkg.packageJson.version}`; const isMissingTag = !( (await git.tagExists(tagName, cwd)) || (await git.remoteTagExists(tagName)) diff --git a/packages/cli/src/commands/publish/index.ts b/packages/cli/src/commands/publish/index.ts index 86a3b341f..129a4cca2 100644 --- a/packages/cli/src/commands/publish/index.ts +++ b/packages/cli/src/commands/publish/index.ts @@ -1,4 +1,4 @@ -import publishPackages from "./publishPackages"; +import publishPackages, { PublishedResult } from "./publishPackages"; import { ExitError } from "@changesets/errors"; import { error, log, success, warn } from "@changesets/logger"; import * as git from "@changesets/git"; @@ -72,7 +72,7 @@ export default async function run( pkg => pkg.packageJson.private && pkg.packageJson.version ); const untaggedPrivatePackageReleases = tagPrivatePackages - ? await getUntaggedPrivatePackages(privatePackages, cwd) + ? await getUntaggedPrivatePackages(privatePackages, cwd, tool) : []; if ( @@ -94,17 +94,8 @@ export default async function run( // won't suffer from a race condition if another merge happens in the mean time (pushing tags won't // fail if we are behind the base branch). log(`Creating git tag${successfulNpmPublishes.length > 1 ? "s" : ""}...`); - if (tool !== "root") { - for (const pkg of successfulNpmPublishes) { - const tag = `${pkg.name}@${pkg.newVersion}`; - log("New tag: ", tag); - await git.tag(tag, cwd); - } - } else { - const tag = `v${successfulNpmPublishes[0].newVersion}`; - log("New tag: ", tag); - await git.tag(tag, cwd); - } + + await tagPublish(tool, successfulNpmPublishes, cwd); } } @@ -112,17 +103,7 @@ export default async function run( success("found untagged projects:"); logReleases(untaggedPrivatePackageReleases); - if (tool !== "root") { - for (const pkg of untaggedPrivatePackageReleases) { - const tag = `${pkg.name}@${pkg.newVersion}`; - log("New tag: ", tag); - await git.tag(tag, cwd); - } - } else { - const tag = `v${untaggedPrivatePackageReleases[0].newVersion}`; - log("New tag: ", tag); - await git.tag(tag, cwd); - } + await tagPublish(tool, untaggedPrivatePackageReleases, cwd); } if (unsuccessfulNpmPublishes.length > 0) { @@ -132,3 +113,21 @@ export default async function run( throw new ExitError(1); } } + +async function tagPublish( + tool: string, + packageReleases: PublishedResult[], + cwd: string +) { + if (tool !== "root") { + for (const pkg of packageReleases) { + const tag = `${pkg.name}@${pkg.newVersion}`; + log("New tag: ", tag); + await git.tag(tag, cwd); + } + } else { + const tag = `v${packageReleases[0].newVersion}`; + log("New tag: ", tag); + await git.tag(tag, cwd); + } +} diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index 3a7a9e6ee..33c740cc2 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -93,16 +93,14 @@ export default async function publishPackages({ preState ); - const twoFactorState: TwoFactorState = - unpublishedPackagesInfo.length > 0 - ? getTwoFactorState({ - otp, - publicPackages - }) - : { - token: null, - isRequired: Promise.resolve(false) - }; + if (unpublishedPackagesInfo.length === 0) { + return []; + } + + const twoFactorState: TwoFactorState = getTwoFactorState({ + otp, + publicPackages + }); return Promise.all( unpublishedPackagesInfo.map((pkgInfo) => { diff --git a/packages/config/schema.json b/packages/config/schema.json index f973d07a7..e24c3fe5e 100644 --- a/packages/config/schema.json +++ b/packages/config/schema.json @@ -75,6 +75,20 @@ "description": "Determines whether Changesets should commit the results of the add and version command.", "default": false }, + "privatePackages": { + "anyOf": [ + { + "type": "object", + "properties": { + "tag": { "type": "boolean" }, + "version": { "type": "boolean" } + } + }, + { + "type": "boolean" + } + ] + }, "access": { "enum": ["restricted", "public"], "type": "string", From 3e9f3b981d47ded4491a81a49a8bcfced3589493 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Thu, 29 Sep 2022 13:06:37 +0800 Subject: [PATCH 27/31] Fix linting issues after rebase --- packages/apply-release-plan/src/index.test.ts | 2 +- .../commands/publish/__tests__/publishPackages.test.ts | 2 +- .../commands/publish/__tests__/releaseCommand.test.ts | 2 +- .../src/commands/publish/getUntaggedPrivatePackages.ts | 4 ++-- packages/cli/src/commands/publish/index.ts | 10 ++++++---- packages/cli/src/commands/publish/publishPackages.ts | 4 ++-- packages/config/src/index.test.ts | 2 +- packages/config/src/index.ts | 6 +++--- packages/git/src/index.test.ts | 2 +- packages/git/src/index.ts | 2 +- 10 files changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/apply-release-plan/src/index.test.ts b/packages/apply-release-plan/src/index.test.ts index 1b18d4ac8..c73cc3f2d 100644 --- a/packages/apply-release-plan/src/index.test.ts +++ b/packages/apply-release-plan/src/index.test.ts @@ -3,7 +3,7 @@ import { ReleasePlan, Config, NewChangeset, - ComprehensiveRelease + ComprehensiveRelease, } from "@changesets/types"; import * as git from "@changesets/git"; import fs from "fs-extra"; diff --git a/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts b/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts index a35155563..29ca9eb41 100644 --- a/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts +++ b/packages/cli/src/commands/publish/__tests__/publishPackages.test.ts @@ -40,7 +40,7 @@ describe("publishPackages", () => { await publishPackages({ packages: (await getPackages(cwd)).packages, access: "public", - preState: undefined + preState: undefined, }); expect(npmUtils.getTokenIsRequired).not.toHaveBeenCalled(); }); diff --git a/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts b/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts index 611627aa3..5c5427046 100644 --- a/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts +++ b/packages/cli/src/commands/publish/__tests__/releaseCommand.test.ts @@ -24,7 +24,7 @@ git.tag.mockImplementation(() => Promise.resolve(true)); publishPackages.mockImplementation(() => Promise.resolve([ { name: "pkg-a", newVersion: "1.1.0", published: true }, - { name: "pkg-b", newVersion: "1.0.1", published: true } + { name: "pkg-b", newVersion: "1.0.1", published: true }, ]) ); diff --git a/packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts b/packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts index b81526e28..ed60c7b7c 100644 --- a/packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts +++ b/packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts @@ -8,7 +8,7 @@ export async function getUntaggedPrivatePackages( tool: Tool ) { const packageWithTags = await Promise.all( - privatePackages.map(async privatePkg => { + privatePackages.map(async (privatePkg) => { const tagName = tool === "root" ? `v${privatePkg.packageJson.version}` @@ -29,7 +29,7 @@ export async function getUntaggedPrivatePackages( untagged.push({ name: packageWithTag.pkg.packageJson.name, newVersion: packageWithTag.pkg.packageJson.version, - published: false + published: false, }); } } diff --git a/packages/cli/src/commands/publish/index.ts b/packages/cli/src/commands/publish/index.ts index 129a4cca2..d57f6edf9 100644 --- a/packages/cli/src/commands/publish/index.ts +++ b/packages/cli/src/commands/publish/index.ts @@ -66,10 +66,10 @@ export default async function run( access: config.access, otp, preState, - tag: releaseTag + tag: releaseTag, }); const privatePackages = packages.filter( - pkg => pkg.packageJson.private && pkg.packageJson.version + (pkg) => pkg.packageJson.private && pkg.packageJson.version ); const untaggedPrivatePackageReleases = tagPrivatePackages ? await getUntaggedPrivatePackages(privatePackages, cwd, tool) @@ -82,8 +82,10 @@ export default async function run( warn("No unpublished projects to publish"); } - const successfulNpmPublishes = publishedPackages.filter(p => p.published); - const unsuccessfulNpmPublishes = publishedPackages.filter(p => !p.published); + const successfulNpmPublishes = publishedPackages.filter((p) => p.published); + const unsuccessfulNpmPublishes = publishedPackages.filter( + (p) => !p.published + ); if (successfulNpmPublishes.length > 0) { success("packages published successfully:"); diff --git a/packages/cli/src/commands/publish/publishPackages.ts b/packages/cli/src/commands/publish/publishPackages.ts index 33c740cc2..c48ab2f4a 100644 --- a/packages/cli/src/commands/publish/publishPackages.ts +++ b/packages/cli/src/commands/publish/publishPackages.ts @@ -78,7 +78,7 @@ export default async function publishPackages({ access, otp, preState, - tag + tag, }: { packages: Package[]; access: AccessType; @@ -99,7 +99,7 @@ export default async function publishPackages({ const twoFactorState: TwoFactorState = getTwoFactorState({ otp, - publicPackages + publicPackages, }); return Promise.all( diff --git a/packages/config/src/index.test.ts b/packages/config/src/index.test.ts index 02bb4d049..70275097d 100644 --- a/packages/config/src/index.test.ts +++ b/packages/config/src/index.test.ts @@ -47,7 +47,7 @@ test("read reads the config", async () => { bumpVersionsWithWorkspaceProtocolOnly: false, privatePackages: { tag: false, - version: true + version: true, }, ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: { onlyUpdatePeerDependentsWhenOutOfRange: false, diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 1f71b4af5..9afd09d20 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -9,7 +9,7 @@ import { WrittenConfig, Fixed, Linked, - PackageGroup + PackageGroup, } from "@changesets/types"; import packageJson from "../package.json"; import { getDependentsGraph } from "@changesets/get-dependents-graph"; @@ -467,9 +467,9 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { privatePackages: json.privatePackages ? { version: json.privatePackages.version ?? true, - tag: json.privatePackages.tag ?? false + tag: json.privatePackages.tag ?? false, } - : { version: true, tag: false } + : { version: true, tag: false }, }; return config; diff --git a/packages/git/src/index.test.ts b/packages/git/src/index.test.ts index c78f2a8c2..30049ae89 100644 --- a/packages/git/src/index.test.ts +++ b/packages/git/src/index.test.ts @@ -13,7 +13,7 @@ import { getChangedPackagesSinceRef, getChangedChangesetFilesSinceRef, getAllTags, - tagExists + tagExists, } from "./"; const f = fixtures(__dirname); diff --git a/packages/git/src/index.ts b/packages/git/src/index.ts index 2e4c8322b..6f9eb0e7a 100644 --- a/packages/git/src/index.ts +++ b/packages/git/src/index.ts @@ -304,7 +304,7 @@ export async function remoteTagExists(tagStr: string) { "--tags", "origin", "-l", - tagStr + tagStr, ]); const output = gitCmd.stdout.toString().trim(); const tagExists = !!output; From ce2f1d20ed12bef5a2a387bf90fe72a6bed5de4c Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Fri, 30 Sep 2022 08:37:32 +0800 Subject: [PATCH 28/31] Fixed up issues around config --- packages/config/schema.json | 2 +- packages/config/src/index.test.ts | 7 +++++++ packages/config/src/index.ts | 25 +++++++++++++++++++------ packages/types/src/index.ts | 2 +- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/packages/config/schema.json b/packages/config/schema.json index e24c3fe5e..e7eb04e8b 100644 --- a/packages/config/schema.json +++ b/packages/config/schema.json @@ -85,7 +85,7 @@ } }, { - "type": "boolean" + "const": false } ] }, diff --git a/packages/config/src/index.test.ts b/packages/config/src/index.test.ts index 70275097d..6b12f530c 100644 --- a/packages/config/src/index.test.ts +++ b/packages/config/src/index.test.ts @@ -645,4 +645,11 @@ The \`snapshot.useCalculatedVersion\` option is set as \\"not true\\" when the o The \`useCalculatedVersionForSnapshots\` option is set as \\"not true\\" when the only valid values are undefined or a boolean" `); }); + + test("privatePackages false disables versioning and tagging", () => { + expect(unsafeParse({ privatePackages: false }, defaultPackages)).toEqual({ + ...defaults, + privatePackages: { version: false, tag: false }, + }); + }); }); diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index 9afd09d20..b8720395e 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -464,14 +464,27 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { }, // TODO consider enabling this by default in the next major version - privatePackages: json.privatePackages - ? { - version: json.privatePackages.version ?? true, - tag: json.privatePackages.tag ?? false, - } - : { version: true, tag: false }, + privatePackages: + json.privatePackages === false + ? { tag: false, version: false } + : json.privatePackages + ? { + version: json.privatePackages.version ?? true, + tag: json.privatePackages.tag ?? false, + } + : { version: true, tag: false }, }; + if ( + config.privatePackages && + config.privatePackages.version === false && + config.privatePackages.tag === true + ) { + throw new ValidationError( + `The \`privatePackages.tag\` option is set to \`true\` but \`privatePackages.version\` is set to \`false\`. This is not allowed.` + ); + } + return config; }; diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index e92d50e9e..133e8c2a8 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -74,7 +74,7 @@ export type Config = { access: AccessType; baseBranch: string; /** Features enabled for Private packages */ - privatePackages: false | PrivatePackages; + privatePackages: PrivatePackages; /** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */ updateInternalDependencies: "patch" | "minor"; ignore: ReadonlyArray; From 99d233b88cb943117b5e782a9cf3d881a7c9df71 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sat, 1 Oct 2022 16:53:42 +0800 Subject: [PATCH 29/31] Fixed some minor config issues --- packages/config/src/index.ts | 1 - packages/types/src/index.ts | 10 ++++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/config/src/index.ts b/packages/config/src/index.ts index b8720395e..0f2468394 100644 --- a/packages/config/src/index.ts +++ b/packages/config/src/index.ts @@ -476,7 +476,6 @@ export let parse = (json: WrittenConfig, packages: Packages): Config => { }; if ( - config.privatePackages && config.privatePackages.version === false && config.privatePackages.tag === true ) { diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 133e8c2a8..13fdad1a0 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -98,10 +98,12 @@ export type WrittenConfig = { access?: AccessType; baseBranch?: string; /** Opt in to tracking non-npm / private packages */ - privatePackages?: { - version?: boolean; - tag?: boolean; - }; + privatePackages?: + | false + | { + version?: boolean; + tag?: boolean; + }; /** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */ updateInternalDependencies?: "patch" | "minor"; ignore?: ReadonlyArray; From 30b60045d3df5cdf9bb0c4fb10c5dc7d1411168b Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sat, 1 Oct 2022 17:59:22 +0800 Subject: [PATCH 30/31] Expanded scope of privatePackages changesets to include config and types packages --- .changeset/fast-jars-thank.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.changeset/fast-jars-thank.md b/.changeset/fast-jars-thank.md index d2700b194..59baf0646 100644 --- a/.changeset/fast-jars-thank.md +++ b/.changeset/fast-jars-thank.md @@ -1,5 +1,7 @@ --- "@changesets/cli": minor +"@changesets/config": minor +"@changesets/types": minor --- Private packages can now be tagged in the same way public packages do when they are published to npm. From 7bdce4a054589817e05e1047194a6edb32e856e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 1 Oct 2022 13:58:31 +0200 Subject: [PATCH 31/31] tweak changesets --- .changeset/fast-jars-thank.md | 2 -- .changeset/rich-horses-push.md | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 .changeset/rich-horses-push.md diff --git a/.changeset/fast-jars-thank.md b/.changeset/fast-jars-thank.md index 59baf0646..d2700b194 100644 --- a/.changeset/fast-jars-thank.md +++ b/.changeset/fast-jars-thank.md @@ -1,7 +1,5 @@ --- "@changesets/cli": minor -"@changesets/config": minor -"@changesets/types": minor --- Private packages can now be tagged in the same way public packages do when they are published to npm. diff --git a/.changeset/rich-horses-push.md b/.changeset/rich-horses-push.md new file mode 100644 index 000000000..09f611a7e --- /dev/null +++ b/.changeset/rich-horses-push.md @@ -0,0 +1,6 @@ +--- +"@changesets/config": minor +"@changesets/types": minor +--- + +Added support for the `privatePackages` property in the config.