fix(git): isolate catalog commands from parent hook environment
This commit is contained in:
1 parent
816e3875c2
commit
98b0009206
4 files changed
+51
-2
No files matched your search
@@ -9,6 +9,7 @@ import {
|
||||
recoverCatalogQueue,
|
||||
sqlValue,
|
||||
} from "./catalog-git-core";
|
||||
import { gitProcessEnvironment } from "./git-process-environment";
|
||||
|
||||
describe("catalog export", () => {
|
||||
it("recovers queue entries owned by a terminated local process", async () => {
|
||||
@@ -55,7 +56,11 @@ describe("catalog export", () => {
|
||||
const remote = path.join(root, "remote.git");
|
||||
const checkout = path.join(root, "checkout");
|
||||
const git = (cwd: string, ...args: string[]) =>
|
||||
execFileSync("git", args, { cwd, encoding: "utf8" }).trim();
|
||||
execFileSync("git", args, {
|
||||
cwd,
|
||||
encoding: "utf8",
|
||||
env: gitProcessEnvironment(),
|
||||
}).trim();
|
||||
git(root, "init", "--bare", remote);
|
||||
git(root, "clone", remote, checkout);
|
||||
git(checkout, "checkout", "-b", "Beta-3");
|
||||
|
||||
@@ -4,6 +4,7 @@ import { promises as fs } from "node:fs";
|
||||
import { hostname } from "node:os";
|
||||
import path from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
import { gitProcessEnvironment } from "./git-process-environment";
|
||||
|
||||
const exec = promisify(execFile);
|
||||
export const CATALOG_REMOTE =
|
||||
@@ -115,7 +116,11 @@ export async function publishCatalogFiles(options: {
|
||||
cwd: checkout,
|
||||
timeout: 120_000,
|
||||
maxBuffer: 16 * 1024 * 1024,
|
||||
env: { ...process.env, ...options.env, GIT_TERMINAL_PROMPT: "0" },
|
||||
env: {
|
||||
...gitProcessEnvironment(),
|
||||
...options.env,
|
||||
GIT_TERMINAL_PROMPT: "0",
|
||||
},
|
||||
});
|
||||
return stdout.trim();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { expect, it } from "vitest";
|
||||
import { gitProcessEnvironment } from "./git-process-environment";
|
||||
|
||||
it("does not pass parent repository paths into catalog Git commands", () => {
|
||||
const env = gitProcessEnvironment({
|
||||
NODE_ENV: "test",
|
||||
PATH: "tools",
|
||||
GIT_DIR: "parent",
|
||||
GIT_WORK_TREE: "parent",
|
||||
GIT_INDEX_FILE: "parent-index",
|
||||
GIT_COMMON_DIR: "common",
|
||||
GIT_AUTHOR_NAME: "Catalog",
|
||||
});
|
||||
expect(env.GIT_DIR).toBeUndefined();
|
||||
expect(env.GIT_WORK_TREE).toBeUndefined();
|
||||
expect(env.GIT_INDEX_FILE).toBeUndefined();
|
||||
expect(env.GIT_COMMON_DIR).toBeUndefined();
|
||||
expect(env.PATH).toBe("tools");
|
||||
expect(env.GIT_AUTHOR_NAME).toBe("Catalog");
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
/** Git hooks export paths belonging to their repository. Never reuse them for a different checkout. */
|
||||
export function gitProcessEnvironment(
|
||||
source: NodeJS.ProcessEnv = process.env,
|
||||
): NodeJS.ProcessEnv {
|
||||
const environment = { ...source };
|
||||
for (const name of [
|
||||
"GIT_DIR",
|
||||
"GIT_WORK_TREE",
|
||||
"GIT_INDEX_FILE",
|
||||
"GIT_COMMON_DIR",
|
||||
"GIT_OBJECT_DIRECTORY",
|
||||
"GIT_ALTERNATE_OBJECT_DIRECTORIES",
|
||||
"GIT_PREFIX",
|
||||
"GIT_IMPLICIT_WORK_TREE",
|
||||
"GIT_GRAFT_FILE",
|
||||
])
|
||||
delete environment[name];
|
||||
return environment;
|
||||
}
|
||||
Reference in new issue
Block a user