Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions bin/pushgate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ switch (command) {
process.stdout.write(`${HOOK_PROTOCOL}\n`);
break;
case "pre-push":
await drainStdin();
drainStdin();
break;
default:
fail(command ? `Unsupported Pushgate command: ${command}` : "Missing Pushgate command.");
Expand All @@ -28,15 +28,13 @@ function fail(message) {
process.exitCode = 64;
}

async function drainStdin() {
try {
for await (const _chunk of process.stdin) {
// Drain Git hook ref updates. Later runner layers will parse this stream.
}
} catch (error) {
function drainStdin() {
process.stdin.on("error", (error) => {
const detail = error instanceof Error ? error.message : String(error);

process.stderr.write(`Failed to read pre-push input: ${detail}\n`);
process.exitCode = 1;
}
});
// Drain Git hook ref updates. Later runner layers will parse this stream.
process.stdin.resume();
}
10 changes: 9 additions & 1 deletion hook/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,16 @@ if [ ! -x "$PUSHGATE_RUNNER" ]; then
exit 1
fi

if ! RUNNER_PROTOCOL="$("$PUSHGATE_RUNNER" hook-protocol 2>/dev/null)"; then
if ! RUNNER_PROTOCOL="$("$PUSHGATE_RUNNER" hook-protocol 2>&1)"; then
error "Pushgate runner at ${PUSHGATE_RUNNER} could not report its hook protocol."
if [ -n "$RUNNER_PROTOCOL" ]; then
error "Runner output:"
while IFS= read -r line; do
error " $line"
done <<EOF
$RUNNER_PROTOCOL
EOF
fi
reinstall_hint
exit 1
fi
Expand Down
19 changes: 19 additions & 0 deletions test/hook.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,25 @@ test("fails clearly when the runner hook protocol is outdated", async () => {
});
});

test("surfaces runner output when the protocol probe cannot execute", async () => {
await withHarness(async (harness) => {
await harness.installRunnerStub();

const result = await harness.runHook({
env: {
PUSHGATE_RUNNER_PROTOCOL_ERROR: "env: node: No such file or directory",
PUSHGATE_RUNNER_PROTOCOL_EXIT: "127",
},
stdin: "",
});
const output = cleanHookOutput(result);

assert.equal(result.code, 1, output);
assert.match(output, /could not report its hook protocol/);
assert.match(output, /env: node: No such file or directory/);
});
});

test("allows a real installed-hook push through the boundary runner", async () => {
await withHarness(async (harness) => {
await harness.installRealRunner();
Expand Down
6 changes: 6 additions & 0 deletions test/support/hook-harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ case "\${1:-}" in
if [ "$#" -ne 1 ]; then
exit 64
fi
if [ "$PUSHGATE_RUNNER_PROTOCOL_EXIT" -ne 0 ]; then
printf '%s\\n' "$PUSHGATE_RUNNER_PROTOCOL_ERROR" >&2
exit "$PUSHGATE_RUNNER_PROTOCOL_EXIT"
fi
printf '%s\\n' "$PUSHGATE_RUNNER_PROTOCOL"
;;
pre-push)
Expand Down Expand Up @@ -312,6 +316,8 @@ function createSandboxEnv(
PATH: [binDir, ...systemPath].join(delimiter),
PUSHGATE_RUNNER_EXIT: "0",
PUSHGATE_RUNNER_PROTOCOL: "1",
PUSHGATE_RUNNER_PROTOCOL_ERROR: "",
PUSHGATE_RUNNER_PROTOCOL_EXIT: "0",
PUSHGATE_STUB_DIR: artifactsDir,
TERM: "dumb",
XDG_CONFIG_HOME: join(homeDir, ".config"),
Expand Down
Loading