diff --git a/README.md b/README.md index db1f0a6..035f34f 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,9 @@ linear-release complete # Completes the release with the specified version linear-release complete --release-version="1.2.0" + +# Sets a custom name when completing the release +linear-release complete --name="Release 1.2.0" ``` ### `update` @@ -131,6 +134,9 @@ linear-release update --stage="in review" # Updates the release with the specified version linear-release update --stage="in review" --release-version="1.2.0" + +# Sets a custom name when updating the release +linear-release update --stage="in review" --name="Release 1.2.0" ``` ## Configuration @@ -143,16 +149,16 @@ linear-release update --stage="in review" --release-version="1.2.0" ### CLI Options -| Option | Commands | Description | -| ------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `--name` | `sync` | Custom release name. Whenever `sync` is called with `--name`, the value is applied to the targeted release — both newly created releases and existing ones get the provided name. Ignored (with warning) for `complete` and `update`. | -| `--release-version` | `sync`, `complete`, `update` | Release version identifier. For `sync`, defaults to short commit hash. For `complete` and `update`, if omitted, targets the most recent started release. | -| `--stage` | `update` | Target deployment stage (required for `update`) | -| `--include-paths` | `sync` | Filter commits by changed file paths | -| `--json` | `sync`, `complete`, `update` | Output result as JSON | -| `--quiet` | `sync`, `complete`, `update` | Only print errors | -| `--verbose` | `sync`, `complete`, `update` | Print detailed progress including debug diagnostics | -| `--timeout` | `sync`, `complete`, `update` | Max duration in seconds before aborting (default: 60) | +| Option | Commands | Description | +| ------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `--name` | `sync`, `complete`, `update` | Custom release name. For `sync`, the value is applied to the targeted release — both newly created releases and existing ones get the provided name. For `complete` and `update`, sets the name on the targeted release. | +| `--release-version` | `sync`, `complete`, `update` | Release version identifier. For `sync`, defaults to short commit hash. For `complete` and `update`, if omitted, targets the most recent started release. | +| `--stage` | `update` | Target deployment stage (required for `update`) | +| `--include-paths` | `sync` | Filter commits by changed file paths | +| `--json` | `sync`, `complete`, `update` | Output result as JSON | +| `--quiet` | `sync`, `complete`, `update` | Only print errors | +| `--verbose` | `sync`, `complete`, `update` | Print detailed progress including debug diagnostics | +| `--timeout` | `sync`, `complete`, `update` | Max duration in seconds before aborting (default: 60) | ### Command Targeting @@ -216,7 +222,6 @@ Path patterns can also be configured in your pipeline settings in Linear. If bot - **Unexpected release was updated/completed**: pass `--release-version` explicitly so the command does not target the latest started/planned release. - **No release created by `sync`**: if no commits match the computed range (or path filters), `sync` returns `{"release":null}`. - **Stage update fails**: verify stage name exactly. If stage names normalize to the same value, use the exact stage name to avoid ambiguity. -- **`--name` seems ignored**: `--name` only applies to `sync`; `complete` and `update` ignore it and print a warning. - **Operation timed out**: the CLI aborts after 60 seconds by default. For large repositories or slow networks, increase the limit with `--timeout=120`. ## License diff --git a/src/args.test.ts b/src/args.test.ts index 904b154..21163b1 100644 --- a/src/args.test.ts +++ b/src/args.test.ts @@ -85,14 +85,14 @@ describe("parseCLIArgs", () => { expect(() => parseCLIArgs(["--unknown-flag"])).toThrow(); }); - it("returns warning when --name is used with update", () => { + it("returns no warning when --name is used with update", () => { const result = parseCLIArgs(["update", "--name", "Release 1.2.0"]); - expect(getCLIWarnings(result)).toEqual(['--name is ignored for "update" command; it only applies to "sync"']); + expect(getCLIWarnings(result)).toEqual([]); }); - it("returns warning when --name is used with complete", () => { + it("returns no warning when --name is used with complete", () => { const result = parseCLIArgs(["complete", "--name", "Release 1.2.0"]); - expect(getCLIWarnings(result)).toEqual(['--name is ignored for "complete" command; it only applies to "sync"']); + expect(getCLIWarnings(result)).toEqual([]); }); it("returns no warning when --name is used with sync", () => { diff --git a/src/args.ts b/src/args.ts index 9c369e8..86ff11a 100644 --- a/src/args.ts +++ b/src/args.ts @@ -64,12 +64,6 @@ export function parseCLIArgs(argv: string[]): ParsedCLIArgs { }; } -export function getCLIWarnings(args: ParsedCLIArgs): string[] { - const warnings: string[] = []; - - if (args.releaseName && args.command !== "sync") { - warnings.push(`--name is ignored for "${args.command}" command; it only applies to "sync"`); - } - - return warnings; +export function getCLIWarnings(_args: ParsedCLIArgs): string[] { + return []; } diff --git a/src/index.ts b/src/index.ts index ac1fed7..a73b294 100644 --- a/src/index.ts +++ b/src/index.ts @@ -38,7 +38,7 @@ Commands: update Update the deployment stage of a release Options: - --name= Custom release name (sync only) + --name= Custom release name --release-version= Release version identifier --stage= Deployment stage (required for update) --include-paths= Filter commits by file paths (comma-separated globs) @@ -87,9 +87,7 @@ if (jsonOutput) { const logEnvironmentSummary = () => { if (releaseName) { - if (command === "sync") { - info(`Using custom release name: ${releaseName}`); - } + info(`Using custom release name: ${releaseName}`); } if (releaseVersion) { info(`Using custom release version: ${releaseVersion}`); @@ -246,6 +244,7 @@ async function completeCommand(): Promise<{ const commitSha = currentCommit.commit; const result = await completeRelease({ + name: releaseName, version: releaseVersion, commitSha, }); @@ -283,6 +282,7 @@ async function updateCommand(): Promise<{ result = await updateReleaseByPipeline({ stage: stageName, version: releaseVersion, + name: releaseName, }); } catch (error) { const message = error instanceof Error ? error.message : "Unknown error"; @@ -430,11 +430,15 @@ async function syncRelease( return response.data.releaseSyncByAccessKey.release; } -async function completeRelease(options: { version?: string | null; commitSha?: string | null }): Promise<{ +async function completeRelease(options: { + name?: string | null; + version?: string | null; + commitSha?: string | null; +}): Promise<{ success: boolean; release: { id: string; name: string; version?: string; url?: string } | null; }> { - const { version, commitSha } = options; + const { name, version, commitSha } = options; const response = await apiRequest( ` @@ -452,6 +456,7 @@ async function completeRelease(options: { version?: string | null; commitSha?: s `, { input: { + name, version, commitSha, }, @@ -461,7 +466,11 @@ async function completeRelease(options: { version?: string | null; commitSha?: s return response.data.releaseCompleteByAccessKey; } -async function updateReleaseByPipeline(options: { stage?: string; version?: string | null }): Promise<{ +async function updateReleaseByPipeline(options: { + stage?: string; + version?: string | null; + name?: string | null; +}): Promise<{ success: boolean; release: { id: string; @@ -471,11 +480,12 @@ async function updateReleaseByPipeline(options: { stage?: string; version?: stri stageName: string; } | null; }> { - const { stage, version } = options; + const { stage, version, name } = options; const versionInput = version ? `, version: "${version}"` : ""; const stageInput = stage ? `, stage: "${stage}"` : ""; + const nameInput = name ? `, name: "${name}"` : ""; - const inputParts = [versionInput, stageInput] + const inputParts = [versionInput, stageInput, nameInput] .filter(Boolean) .map((s) => s.slice(2)) .join(", ");