From 046da53ec02d9c927a5f35f1e584d399f7efa4e7 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Thu, 29 Sep 2022 12:14:49 +0800 Subject: [PATCH] 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 b12d4260e..b07888c20 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 1eafadb6d..31d3e6591 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( @@ -60,16 +58,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) @@ -116,16 +104,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 cc0040480..d02b9590f 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 4b1674994..3b173ff2a 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 94e60c838..17a736b78 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",