Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tag private packages when their version changes #662

Merged
merged 31 commits into from Oct 1, 2022
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
626cfdf
Tag private packages when their version changes
JakeGinnivan Nov 7, 2021
5686490
Fixed formatting
JakeGinnivan Nov 7, 2021
6d37ea5
Export tagExists function
JakeGinnivan Feb 8, 2022
8e5354a
Implement config option to opt into the private packages versioning f…
JakeGinnivan May 22, 2022
53742d5
Added doco on tracking private packages
JakeGinnivan May 22, 2022
60a1930
Fixed tests compilation
JakeGinnivan May 22, 2022
9d22a27
Filter package list based on tracking private packages config
JakeGinnivan May 22, 2022
e571a0e
Fixed lint issue
JakeGinnivan May 22, 2022
d2f4d89
Fixed tests
JakeGinnivan May 22, 2022
013e969
Update docs again
JakeGinnivan May 22, 2022
8644724
Remove requirement of being logged into NPM if there are no unpublish…
JakeGinnivan May 23, 2022
f3c7ded
Update .changeset/khaki-kangaroos-tie.md
JakeGinnivan Jun 9, 2022
86171cb
Update packages/config/src/index.ts
JakeGinnivan Jun 9, 2022
44f2bd6
Update packages/git/src/index.test.ts
JakeGinnivan Jun 9, 2022
bae290b
Use remote tag check instead of local
JakeGinnivan Jun 20, 2022
49614eb
Updated config to work against a privatePackages flag
JakeGinnivan Jun 20, 2022
c356ae3
Fixed lint error
JakeGinnivan Jun 20, 2022
656d28f
Fixed tests
JakeGinnivan Jun 24, 2022
24f0a78
Fixed linting errors
JakeGinnivan Aug 11, 2022
f17508a
Update packages/cli/src/commands/publish/publishPackages.ts
JakeGinnivan Sep 25, 2022
3886e90
Update packages/cli/src/commands/add/createChangeset.ts
JakeGinnivan Sep 25, 2022
c062b16
Fixed duplication of logic when filtering listable packages
JakeGinnivan Sep 26, 2022
f0ece83
Removed flags enum and simplified config
JakeGinnivan Sep 26, 2022
4dd972e
Added cwd to tagExists and fixed tests
JakeGinnivan Sep 26, 2022
6047290
Hoist tagging private packages out of publish package
JakeGinnivan Sep 26, 2022
2f158d5
Addressed feedback
JakeGinnivan Sep 29, 2022
3e9f3b9
Fix linting issues after rebase
JakeGinnivan Sep 29, 2022
ce2f1d2
Fixed up issues around config
JakeGinnivan Sep 30, 2022
99d233b
Fixed some minor config issues
JakeGinnivan Oct 1, 2022
30b6004
Expanded scope of privatePackages changesets to include config and ty…
JakeGinnivan Oct 1, 2022
7bdce4a
tweak changesets
Andarist Oct 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/fast-jars-thank.md
@@ -0,0 +1,9 @@
---
JakeGinnivan marked this conversation as resolved.
Show resolved Hide resolved
"@changesets/cli": minor
---

Private packages can now be tagged in the same way public packages do when they are published to npm.

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: false`.
5 changes: 5 additions & 0 deletions .changeset/khaki-kangaroos-tie.md
@@ -0,0 +1,5 @@
---
"@changesets/git": minor
---

Add `tagExists` & `remoteTagExists` git helpers
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -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
Expand Down
22 changes: 22 additions & 0 deletions docs/versioning-apps.md
@@ -0,0 +1,22 @@
# Managing applications or non-npm packages
JakeGinnivan marked this conversation as resolved.
Show resolved Hide resolved

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 `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.

## 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"
}
```
18 changes: 18 additions & 0 deletions packages/apply-release-plan/src/index.test.ts
Expand Up @@ -49,6 +49,7 @@ class FakeReleasePlan {
baseBranch: "main",
updateInternalDependencies: "patch",
ignore: [],
privatePackages: { version: true, tag: false },
JakeGinnivan marked this conversation as resolved.
Show resolved Hide resolved
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -90,6 +91,7 @@ async function testSetup(
baseBranch: "main",
updateInternalDependencies: "patch",
ignore: [],
privatePackages: { version: true, tag: false },
snapshot: {
useCalculatedVersion: false,
prereleaseTemplate: null,
Expand Down Expand Up @@ -493,6 +495,7 @@ describe("apply release plan", () => {
access: "restricted",
baseBranch: "main",
updateInternalDependencies: "patch",
privatePackages: { version: true, tag: false },
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
Expand Down Expand Up @@ -559,6 +562,7 @@ describe("apply release plan", () => {
access: "restricted",
baseBranch: "main",
updateInternalDependencies: "patch",
privatePackages: { version: true, tag: false },
ignore: [],
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
Expand Down Expand Up @@ -753,6 +757,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies,
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -841,6 +846,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies,
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -921,6 +927,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies,
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -1001,6 +1008,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies,
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -1084,6 +1092,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies,
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -1172,6 +1181,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies,
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -1252,6 +1262,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies,
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -1332,6 +1343,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies,
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -1416,6 +1428,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies: "patch",
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: true,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -1596,6 +1609,7 @@ describe("apply release plan", () => {
],
updateInternalDependencies: "patch",
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -1704,6 +1718,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies: "patch",
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -1792,6 +1807,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies: "minor",
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -1884,6 +1900,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies: "minor",
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down Expand Up @@ -1990,6 +2007,7 @@ describe("apply release plan", () => {
baseBranch: "main",
updateInternalDependencies: "minor",
ignore: [],
privatePackages: { version: true, tag: false },
___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: {
onlyUpdatePeerDependentsWhenOutOfRange: false,
updateInternalDependents: "out-of-range",
Expand Down
14 changes: 8 additions & 6 deletions packages/cli/src/commands/add/__tests__/add.ts
Expand Up @@ -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" },
Expand All @@ -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";

Expand Down Expand Up @@ -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(
Expand All @@ -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);

Expand All @@ -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(
Expand All @@ -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);
Expand Down
12 changes: 6 additions & 6 deletions packages/cli/src/commands/add/createChangeset.ts
Expand Up @@ -94,16 +94,16 @@ async function getPackagesToRelease(
return [allPackages[0].packageJson.name];
}

function formatPkgNameAndVersion(pkgName: string, version: string) {
return `${bold(pkgName)}@${bold(version)}`;
}

function getPkgJsonByName(packages: Package[]) {
function getPkgJsonsByName(packages: Package[]) {
return new Map(
packages.map(({ packageJson }) => [packageJson.name, packageJson])
);
}

function formatPkgNameAndVersion(pkgName: string, version: string) {
return `${bold(pkgName)}@${bold(version)}`;
}

export default async function createChangeset(
changedPackages: Array<string>,
allPackages: Package[]
Expand All @@ -116,7 +116,7 @@ export default async function createChangeset(
allPackages
);

let pkgJsonsByName = getPkgJsonByName(allPackages);
let pkgJsonsByName = getPkgJsonsByName(allPackages);

let pkgsLeftToGetBumpTypeFor = new Set(packagesToRelease);

Expand Down
9 changes: 1 addition & 8 deletions packages/cli/src/commands/add/index.ts
Expand Up @@ -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,
Expand Down
17 changes: 17 additions & 0 deletions packages/cli/src/commands/add/isListablePackage.ts
@@ -0,0 +1,17 @@
import { Config } from "@changesets/types";
import { PackageJSON } from "@changesets/types";
Copy link

Choose a reason for hiding this comment

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

import type { PackageJSON } from "@changesets/types";

I think both import can be type import


export function isListablePackage(config: Config, packageJson: PackageJSON) {
Andarist marked this conversation as resolved.
Show resolved Hide resolved
const packageIgnoredInConfig = config.ignore.includes(packageJson.name);

if (packageIgnoredInConfig) {
return false;
}

if (!config.privatePackages && packageJson.private) {
Copy link
Contributor

Choose a reason for hiding this comment

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

is something wrong here? because config.privatePackages is always Object

!config.privatePackages?.version && packageJson.private

or i misunderstand?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mino01x is it causing an issue? If it is then we need to write a test around it

Copy link
Contributor

Choose a reason for hiding this comment

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

#985 yes i have create a pr. you can help me to check it.

return false;
}

const hasVersionField = !!packageJson.version;
return hasVersionField;
}
Expand Up @@ -33,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", () => {
Expand Down
38 changes: 38 additions & 0 deletions packages/cli/src/commands/publish/getUntaggedPrivatePackages.ts
@@ -0,0 +1,38 @@
import * as git from "@changesets/git";
import { Package, Tool } from "@manypkg/get-packages";
import { PublishedResult } from "./publishPackages";

export async function getUntaggedPrivatePackages(
privatePackages: Package[],
cwd: string,
tool: Tool
) {
const packageWithTags = await Promise.all(
privatePackages.map(async (privatePkg) => {
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))
);

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;
}