feat(git-gate): add DockerGitGate sidecar lifecycle + image
test / unit (pull_request) Successful in 16s
test / integration (pull_request) Successful in 15s

Dockerfile.git-gate builds a small alpine image with git,
openssh-client, and gitleaks; the directory layout the entrypoint
and per-upstream cp's expect is pre-created in the image so docker
cp can target paths beneath /etc/git-gate and /git-gate/creds at
container-create time (cp doesn't create intermediate dirs).

DockerGitGate.start mirrors DockerSSHGate's shape: build, create,
cp the rendered entrypoint + hook + per-upstream identity files
(plus a known_hosts file synthesized from KnownHostKey when set),
attach the egress network, start. build_image gains an optional
dockerfile= argument so the gate can build from its own
Dockerfile in the shared context.

PRD: docs/prds/0008-git-gate.md
This commit is contained in:
2026-05-12 20:58:51 -04:00
parent 2fb90f2087
commit 2d955a5512
3 changed files with 249 additions and 3 deletions
+11 -3
View File
@@ -100,12 +100,20 @@ def slugify(name: str) -> str:
return slug
def build_image(ref: str, context: str) -> None:
def build_image(ref: str, context: str, *, dockerfile: str = "") -> None:
"""Invokes `docker build` every call. Layer cache makes no-change
rebuilds cheap; running every time means Dockerfile edits land
without manual `docker rmi`."""
without manual `docker rmi`.
`dockerfile` is an optional path (relative to `context`, or
absolute) for callers that need to build from a non-default
Dockerfile in the same context — e.g. `Dockerfile.git-gate`."""
info(f"building image {ref} from {context} (layer cache keeps repeat builds fast)")
subprocess.run(["docker", "build", "-t", ref, context], check=True)
args = ["docker", "build", "-t", ref]
if dockerfile:
args.extend(["-f", dockerfile])
args.append(context)
subprocess.run(args, check=True)
_TRUST_DIALOG_NODE_SCRIPT = (