diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d4e60f62..6ebc23ac 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -73,28 +73,30 @@ jobs: - name: Compile binaries (cross-compile all targets) run: | + VERSION=$(jq -r .version package.json) + # macOS ARM64 - bun build apps/hook/server/index.ts --compile --target=bun-darwin-arm64 --outfile plannotator-darwin-arm64 + bun build apps/hook/server/index.ts --compile --target=bun-darwin-arm64 --define "__CLI_VERSION__=\"$VERSION\"" --outfile plannotator-darwin-arm64 sha256sum plannotator-darwin-arm64 > plannotator-darwin-arm64.sha256 # macOS x64 - bun build apps/hook/server/index.ts --compile --target=bun-darwin-x64 --outfile plannotator-darwin-x64 + bun build apps/hook/server/index.ts --compile --target=bun-darwin-x64 --define "__CLI_VERSION__=\"$VERSION\"" --outfile plannotator-darwin-x64 sha256sum plannotator-darwin-x64 > plannotator-darwin-x64.sha256 # Linux x64 - bun build apps/hook/server/index.ts --compile --target=bun-linux-x64 --outfile plannotator-linux-x64 + bun build apps/hook/server/index.ts --compile --target=bun-linux-x64 --define "__CLI_VERSION__=\"$VERSION\"" --outfile plannotator-linux-x64 sha256sum plannotator-linux-x64 > plannotator-linux-x64.sha256 # Linux ARM64 - bun build apps/hook/server/index.ts --compile --target=bun-linux-arm64 --outfile plannotator-linux-arm64 + bun build apps/hook/server/index.ts --compile --target=bun-linux-arm64 --define "__CLI_VERSION__=\"$VERSION\"" --outfile plannotator-linux-arm64 sha256sum plannotator-linux-arm64 > plannotator-linux-arm64.sha256 # Windows x64 - bun build apps/hook/server/index.ts --compile --target=bun-windows-x64 --outfile plannotator-win32-x64.exe + bun build apps/hook/server/index.ts --compile --target=bun-windows-x64 --define "__CLI_VERSION__=\"$VERSION\"" --outfile plannotator-win32-x64.exe sha256sum plannotator-win32-x64.exe > plannotator-win32-x64.exe.sha256 # Windows ARM64 (native, via bun-windows-arm64 — stable since Bun v1.3.10) - bun build apps/hook/server/index.ts --compile --target=bun-windows-arm64 --outfile plannotator-win32-arm64.exe + bun build apps/hook/server/index.ts --compile --target=bun-windows-arm64 --define "__CLI_VERSION__=\"$VERSION\"" --outfile plannotator-win32-arm64.exe sha256sum plannotator-win32-arm64.exe > plannotator-win32-arm64.exe.sha256 # Paste service binaries diff --git a/apps/hook/server/cli.test.ts b/apps/hook/server/cli.test.ts index 9da4a9e3..ff8e5688 100644 --- a/apps/hook/server/cli.test.ts +++ b/apps/hook/server/cli.test.ts @@ -2,8 +2,10 @@ import { describe, expect, test } from "bun:test"; import { formatInteractiveNoArgClarification, formatTopLevelHelp, + formatVersion, isInteractiveNoArgInvocation, isTopLevelHelpInvocation, + isVersionInvocation, } from "./cli"; describe("CLI top-level help", () => { @@ -17,6 +19,7 @@ describe("CLI top-level help", () => { const output = formatTopLevelHelp(); expect(output).toContain("plannotator --help"); + expect(output).toContain("plannotator --version, -v"); expect(output).toContain("plannotator [--browser ]"); expect(output).toContain("plannotator review [--git] [PR_URL]"); expect(output).toContain("plannotator annotate "); @@ -24,6 +27,20 @@ describe("CLI top-level help", () => { }); }); +describe("CLI --version", () => { + test("recognizes --version and -v", () => { + expect(isVersionInvocation(["--version"])).toBe(true); + expect(isVersionInvocation(["-v"])).toBe(true); + expect(isVersionInvocation([])).toBe(false); + expect(isVersionInvocation(["review"])).toBe(false); + }); + + test("formats version string", () => { + const output = formatVersion(); + expect(output).toStartWith("plannotator "); + }); +}); + describe("interactive no-arg invocation", () => { test("detects bare interactive invocation only when stdin is a TTY", () => { expect(isInteractiveNoArgInvocation([], true)).toBe(true); diff --git a/apps/hook/server/cli.ts b/apps/hook/server/cli.ts index 67b06d86..a1843527 100644 --- a/apps/hook/server/cli.ts +++ b/apps/hook/server/cli.ts @@ -2,6 +2,16 @@ export function isTopLevelHelpInvocation(args: string[]): boolean { return args[0] === "--help"; } +export function isVersionInvocation(args: string[]): boolean { + return args[0] === "--version" || args[0] === "-v"; +} + +declare const __CLI_VERSION__: string; + +export function formatVersion(): string { + return `plannotator ${typeof __CLI_VERSION__ !== "undefined" ? __CLI_VERSION__ : "dev"}`; +} + export function isInteractiveNoArgInvocation( args: string[], stdinIsTTY: boolean | undefined, @@ -13,6 +23,7 @@ export function formatTopLevelHelp(): string { return [ "Usage:", " plannotator --help", + " plannotator --version, -v", " plannotator [--browser ]", " plannotator review [--git] [PR_URL]", " plannotator annotate [--no-jina] [--gate] [--json] [--hook]", diff --git a/apps/hook/server/index.ts b/apps/hook/server/index.ts index 045e1207..9287d2fe 100644 --- a/apps/hook/server/index.ts +++ b/apps/hook/server/index.ts @@ -44,6 +44,7 @@ * * Global flags: * --help - Show top-level usage information + * --version, -v - Print version and exit * --browser - Override which browser to open (e.g. "Google Chrome") * * Environment variables: @@ -104,8 +105,10 @@ import { findCopilotPlanContent, findCopilotSessionForCwd, getLastCopilotMessage import { formatInteractiveNoArgClarification, formatTopLevelHelp, + formatVersion, isInteractiveNoArgInvocation, isTopLevelHelpInvocation, + isVersionInvocation, } from "./cli"; import path from "path"; import { tmpdir } from "os"; @@ -202,6 +205,11 @@ function emitAnnotateOutcome(result: { if (result.feedback) console.log(result.feedback); } +if (isVersionInvocation(args)) { + console.log(formatVersion()); + process.exit(0); +} + if (isTopLevelHelpInvocation(args)) { console.log(formatTopLevelHelp()); process.exit(0);