Skip to content

Commit

Permalink
Improvements to changesets (#220)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericanderson authored Apr 24, 2024
1 parent aef9ab7 commit f3e7536
Show file tree
Hide file tree
Showing 10 changed files with 383 additions and 76 deletions.
5 changes: 5 additions & 0 deletions .changeset/eleven-dolphins-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@osdk/tool.release": minor
---

Prevent publishing patch from main and minor/major from release
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
"check-mrl": "mrl check --verbose",
"ci:publish": "pnpm run prePublish && pnpm publish -r --report-summary",
"ci:publishSnapshot": "pnpm run prePublish && pnpm exec changeset version --snapshot && pnpm exec changeset publish --no-git-tag --snapshot --tag=next",
"ci:version": "pnpm exec changeset version && turbo run postVersioning && turbo codegen",
"dev": "npx tsx packages/watch/src/watch.mts",
"dev:typecheck": "npx tsx packages/watch/src/watch.mts",
"lint": "turbo run lint",
"postVersionCmd": "turbo run postVersioning && turbo codegen",
"prePublish": "turbo build && turbo lint",
"prepare": "husky install",
"test": "FORCE_COLOR=1 turbo run test",
Expand All @@ -20,6 +20,7 @@
"devDependencies": {
"@babel/core": "^7.24.4",
"@babel/preset-typescript": "^7.23.3",
"@changesets/changelog-git": "^0.2.0",
"@changesets/cli": "^2.26.2",
"@monorepolint/cli": "0.5.0-alpha.108",
"@monorepolint/config": "0.5.0-alpha.108",
Expand Down
6 changes: 6 additions & 0 deletions packages/tool.release/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,17 @@
"clean": "rm -rf lib dist types build tsconfig.tsbuildinfo",
"fix-lint": "eslint . --fix && dprint fmt --config $(find-up dprint.json)",
"lint": "eslint . && dprint check --config $(find-up dprint.json)",
"test": "vitest run --pool=forks",
"transpile": "tsup",
"typecheck": "tsc-absolute"
},
"dependencies": {
"@actions/exec": "^1.1.1",
"@changesets/apply-release-plan": "^7.0.0",
"@changesets/assemble-release-plan": "^6.0.0",
"@changesets/changelog-git": "^0.2.0",
"@changesets/config": "^3.0.0",
"@changesets/git": "^3.0.0",
"@changesets/pre": "^1.0.9",
"@changesets/read": "^0.5.3",
"@changesets/release-utils": "^0.2.0",
Expand Down
22 changes: 22 additions & 0 deletions packages/tool.release/src/FailedWithUserMessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2024 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export class FailedWithUserMessage extends Error {
constructor(message: string) {
super(message);
this.name = "FailedWithUserMessage";
}
}
23 changes: 8 additions & 15 deletions packages/tool.release/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ import { readChangesetState } from "@changesets/release-utils";
import { consola } from "consola";
import * as fs from "node:fs";
import yargs from "yargs";
import { setupUser } from "./gitUtils.js";
import { FailedWithUserMessage } from "./FailedWithUserMessage.js";
import { checkIfClean as isGitClean, setupUser } from "./gitUtils.js";
import { runPublish } from "./runPublish.js";
import type { GithubContext } from "./runVersion.js";
import { runVersion } from "./runVersion.js";
Expand Down Expand Up @@ -86,13 +87,6 @@ async function getContext(
};
}

class FailedWithUserMessage extends Error {
constructor(message: string) {
super(message);
this.name = "FailedWithUserMessage";
}
}

(async () => {
const args = await yargs(process.argv.slice(2))
.options({
Expand All @@ -101,14 +95,8 @@ class FailedWithUserMessage extends Error {
choices: ["version", "publish"],
default: "version",
},
versionCmd: {
type: "string",
conflicts: "publishCmd",
description: "Custom version command to run in version mode",
},
publishCmd: {
type: "string",
conflicts: "versionCmd",
description: "Publish command to run in publish mode",
},
title: { type: "string", description: "Custom pr title" },
Expand Down Expand Up @@ -156,6 +144,12 @@ class FailedWithUserMessage extends Error {
await setupUser();
}

if (!await isGitClean()) {
throw new FailedWithUserMessage(
"Your working directory is not clean. We are aborting for your protection.",
);
}

const context = await getContext(args);

const { changesets } = await readChangesetState();
Expand All @@ -176,7 +170,6 @@ class FailedWithUserMessage extends Error {
}

await runVersion({
versionCmd: args.versionCmd,
prTitle: args.title,
commitMessage: args.commitMessage,
branch: args.branch,
Expand Down
103 changes: 103 additions & 0 deletions packages/tool.release/src/mutateReleasePlan.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright 2024 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import type { ReleasePlan } from "@changesets/types";
import { describe, expect, it } from "vitest";
import { mutateReleasePlan } from "./mutateReleasePlan.js";

describe(mutateReleasePlan, () => {
describe("for main", () => {
it("promotes patches to minor", () => {
const plan: ReleasePlan = {
changesets: [
{
id: "5",
releases: [
{ name: "foo", type: "patch" },
],
summary: "foo summary",
},
],
preState: undefined,
releases: [
{
changesets: ["5"],
oldVersion: "2.1.3",
newVersion: "2.1.4",
name: "foo",
type: "patch",
},
],
};

mutateReleasePlan(plan, "main");

expect(plan).toEqual({
changesets: [
{
id: "5",
releases: [
{ name: "foo", type: "minor" },
],
summary: "foo summary",
},
],
preState: undefined,
releases: [
{
changesets: ["5"],
oldVersion: "2.1.3",
newVersion: "2.2.0",
name: "foo",
type: "minor",
},
],
});
});
});

describe("for patch", () => {
it("fails to demote minor and major to patch", () => {
const plan: ReleasePlan = {
changesets: [
{
id: "5",
releases: [
{ name: "foo", type: "minor" },
],
summary: "foo summary",
},
],
preState: undefined,
releases: [
{
changesets: ["5"],
oldVersion: "2.1.3",
newVersion: "2.1.4",
name: "foo",
type: "minor",
},
],
};

expect(() => {
mutateReleasePlan(plan, "patch");
}).toThrowErrorMatchingInlineSnapshot(
`[FailedWithUserMessage: Releasing requires converting a minor to a patch, but that may not be safe.]`,
);
});
});
});
46 changes: 46 additions & 0 deletions packages/tool.release/src/mutateReleasePlan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2024 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import type { ReleasePlan } from "@changesets/types";
import { inc } from "semver";
import { FailedWithUserMessage } from "./FailedWithUserMessage.js";

export function mutateReleasePlan(
releasePlan: ReleasePlan,
releaseType: "patch" | "main",
) {
for (const changeSet of releasePlan.changesets) {
for (const release of changeSet.releases) {
if (releaseType === "main" && release.type === "patch") {
release.type = "minor";
} else if (
releaseType === "patch" && (release.type !== "patch")
&& (release.type !== "none")
) {
throw new FailedWithUserMessage(
`Releasing requires converting a ${release.type} to a patch, but that may not be safe.`,
);
}
}
}

for (const q of releasePlan.releases) {
if (releaseType === "main" && q.type === "patch") {
q.type = "minor";
q.newVersion = inc(q.oldVersion, "minor")!;
}
}
}
Loading

0 comments on commit f3e7536

Please sign in to comment.