CLI: include commit hash in --version output (#39712)

* CLI: include commit hash in --version output

* fix(version): harden commit SHA resolution and keep output consistent

* CLI: keep install checks compatible with commit-tagged version output

* fix(cli): include commit hash in root version fast path

* test(cli): allow null commit-hash mocks

* Installer: share version parser across install scripts

* Installer: avoid sourcing helpers from stdin cwd

* CLI: note commit-tagged version output

* CLI: anchor commit hash resolution to module root

* CLI: harden commit hash resolution

* CLI: fix commit hash lookup edge cases

* CLI: prefer live git metadata in dev builds

* CLI: keep git lookup inside package root

* Infra: tolerate invalid moduleUrl hints

* CLI: cache baked commit metadata fallbacks

* CLI: align changelog attribution with prep gate

* CLI: restore changelog contributor credit

---------

Co-authored-by: echoVic <echovic@163.com>
Co-authored-by: echoVic <echoVic@users.noreply.github.com>
This commit is contained in:
Altay
2026-03-08 19:10:48 +03:00
committed by GitHub
parent c942655451
commit ca5e352c53
19 changed files with 903 additions and 42 deletions

View File

@@ -5,6 +5,7 @@ import type { ProgramContext } from "./context.js";
const hasEmittedCliBannerMock = vi.fn(() => false);
const formatCliBannerLineMock = vi.fn(() => "BANNER-LINE");
const formatDocsLinkMock = vi.fn((_path: string, full: string) => `https://${full}`);
const resolveCommitHashMock = vi.fn<() => string | null>(() => "abc1234");
vi.mock("../../terminal/links.js", () => ({
formatDocsLink: formatDocsLinkMock,
@@ -26,6 +27,10 @@ vi.mock("../banner.js", () => ({
hasEmittedCliBanner: hasEmittedCliBannerMock,
}));
vi.mock("../../infra/git-commit.js", () => ({
resolveCommitHash: resolveCommitHashMock,
}));
vi.mock("../cli-name.js", () => ({
resolveCliName: () => "openclaw",
replaceCliName: (cmd: string) => cmd,
@@ -55,6 +60,7 @@ describe("configureProgramHelp", () => {
vi.clearAllMocks();
originalArgv = [...process.argv];
hasEmittedCliBannerMock.mockReturnValue(false);
resolveCommitHashMock.mockReturnValue("abc1234");
});
afterEach(() => {
@@ -116,7 +122,25 @@ describe("configureProgramHelp", () => {
const program = makeProgramWithCommands();
expect(() => configureProgramHelp(program, testProgramContext)).toThrow("exit:0");
expect(logSpy).toHaveBeenCalledWith("9.9.9-test");
expect(logSpy).toHaveBeenCalledWith("OpenClaw 9.9.9-test (abc1234)");
expect(exitSpy).toHaveBeenCalledWith(0);
logSpy.mockRestore();
exitSpy.mockRestore();
});
it("prints version and exits immediately without commit metadata", () => {
process.argv = ["node", "openclaw", "--version"];
resolveCommitHashMock.mockReturnValue(null);
const logSpy = vi.spyOn(console, "log").mockImplementation(() => {});
const exitSpy = vi.spyOn(process, "exit").mockImplementation(((code?: number) => {
throw new Error(`exit:${code ?? ""}`);
}) as typeof process.exit);
const program = makeProgramWithCommands();
expect(() => configureProgramHelp(program, testProgramContext)).toThrow("exit:0");
expect(logSpy).toHaveBeenCalledWith("OpenClaw 9.9.9-test");
expect(exitSpy).toHaveBeenCalledWith(0);
logSpy.mockRestore();