From b18a1466e4b5bd3549c32029e9a9b0cac92ac37a Mon Sep 17 00:00:00 2001 From: wotan-allfather Date: Fri, 6 Feb 2026 08:48:16 +0000 Subject: [PATCH 1/6] feat(cli): add --since flag to add command Add support for the --since flag to the add command, allowing users to specify which branch, tag, or git ref to use when detecting changed packages. This is useful for gitflow workflows where multiple target branches exist and the baseBranch config doesn't cover all use cases. - Add since parameter to add command function - Pass since to getVersionableChangedPackages - Update help message and documentation - Add test for --since flag functionality Closes #477 --- .changeset/add-since-flag.md | 11 +++++ docs/command-line-options.md | 8 +++- .../cli/src/commands/add/__tests__/add.ts | 40 ++++++++++++++++++- packages/cli/src/commands/add/index.ts | 6 ++- packages/cli/src/index.ts | 2 +- packages/cli/src/run.ts | 6 +-- 6 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 .changeset/add-since-flag.md diff --git a/.changeset/add-since-flag.md b/.changeset/add-since-flag.md new file mode 100644 index 000000000..40a82cd95 --- /dev/null +++ b/.changeset/add-since-flag.md @@ -0,0 +1,11 @@ +--- +"@changesets/cli": minor +--- + +Add `--since` flag to `add` command + +The `add` command now supports a `--since` flag that allows you to specify which branch, tag, or git ref to use when detecting changed packages. This is useful for gitflow workflows where you have multiple target branches and the `baseBranch` config option doesn't cover all use cases. + +Example: `changeset add --since=develop` + +If not provided, the command falls back to the `baseBranch` value in your `.changeset/config.json`. diff --git a/docs/command-line-options.md b/docs/command-line-options.md index c6d9590d0..ae01d89f4 100644 --- a/docs/command-line-options.md +++ b/docs/command-line-options.md @@ -3,7 +3,7 @@ The command line for changesets is the main way of interacting with it. There are 4 main commands. If you are looking for how we recommend you setup and manage changesets with the commands, check out our [intro to using changesets](./intro-to-using-changesets.md) - init -- add [--empty][--open] +- add [--empty][--open][--since] - version [--ignore, --snapshot] - publish [--otp=code, --tag] - status [--since=master --verbose --output=JSON_FILE.json] @@ -66,6 +66,12 @@ If you set the commit option in the config, the command will add the updated cha - `--open` - opens the created changeset in an external editor +- `--since` - uses the provided branch, tag, or git ref (such as `main` or a git commit hash) to detect which packages have changed when populating the list of changed packages in the CLI. This is useful in gitflow workflows where you have multiple target branches and `baseBranch` in the config doesn't cover all use cases. If not provided, the command falls back to the `baseBranch` value in your `.changeset/config.json`. + +``` +changeset --since=develop +``` + ## version ``` diff --git a/packages/cli/src/commands/add/__tests__/add.ts b/packages/cli/src/commands/add/__tests__/add.ts index 1664ae3ce..9e2455c56 100644 --- a/packages/cli/src/commands/add/__tests__/add.ts +++ b/packages/cli/src/commands/add/__tests__/add.ts @@ -23,9 +23,12 @@ writeChangeset.mockImplementation(() => Promise.resolve("abcdefg")); // @ts-ignore git.commit.mockImplementation(() => Promise.resolve(true)); +// Keep track of expected ref for tests +let expectedRef = "master"; + // @ts-ignore git.getChangedPackagesSinceRef.mockImplementation(({ ref }) => { - expect(ref).toBe("master"); + expect(ref).toBe(expectedRef); return []; }); @@ -260,6 +263,41 @@ describe("Add command", () => { ); }); + it("should use the since flag when detecting changed packages", async () => { + const cwd = await testdir({ + "package.json": JSON.stringify({ + private: true, + workspaces: ["packages/*"], + }), + "packages/pkg-a/package.json": JSON.stringify({ + name: "pkg-a", + version: "1.0.0", + }), + "packages/pkg-b/package.json": JSON.stringify({ + name: "pkg-b", + version: "1.0.0", + }), + }); + + // Override the expected ref for this test + expectedRef = "develop"; + + mockUserResponses({ releases: { "pkg-a": "patch" } }); + await addChangeset(cwd, { empty: false, since: "develop" }, defaultConfig); + + // Reset for other tests + expectedRef = "master"; + + // @ts-ignore + const call = writeChangeset.mock.calls[0][0]; + expect(call).toEqual( + expect.objectContaining({ + summary: "summary message mock", + releases: [{ name: "pkg-a", type: "patch" }], + }) + ); + }); + it("should not include ignored packages in the prompt", async () => { const cwd = await testdir({ "package.json": JSON.stringify({ diff --git a/packages/cli/src/commands/add/index.ts b/packages/cli/src/commands/add/index.ts index 5f0cb88af..fab7c1f3d 100644 --- a/packages/cli/src/commands/add/index.ts +++ b/packages/cli/src/commands/add/index.ts @@ -18,7 +18,7 @@ import printConfirmationMessage from "./messages"; export default async function add( cwd: string, - { empty, open }: { empty?: boolean; open?: boolean }, + { empty, open, since }: { empty?: boolean; open?: boolean; since?: string }, config: Config ): Promise { const packages = await getPackages(cwd); @@ -59,13 +59,15 @@ export default async function add( changedPackagesNames = ( await getVersionableChangedPackages(config, { cwd, + ref: since, }) ).map((pkg) => pkg.packageJson.name); } catch (e: any) { // NOTE: Getting the changed packages is best effort as it's only being used for easier selection // in the CLI. So if any error happens while we try to do so, we only log a warning and continue + const branch = since ?? config.baseBranch; warn( - `Failed to find changed packages from the "${config.baseBranch}" base branch due to error below` + `Failed to find changed packages from the "${branch}" ${since ? "ref" : "base branch"} due to error below` ); warn(e); } diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index de627c493..959f6e066 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -52,7 +52,7 @@ if (parsed.help && args.length === 1) { $ changeset [command] Commands init - add [--empty] [--open] + add [--empty] [--open] [--since ] version [--ignore] [--snapshot ] [--snapshot-prerelease-template