refactor(ci-setup): extract container-port/image/proxy-port constants

The container-internal port (4747 ×5), the image reference (×3), and the
Caddy proxy-port arithmetic (opts.port + 1 ×5) were duplicated across the
generated artifacts, so the port contract could drift if one site was
updated and others missed. Hoist CONTAINER_PORT and GITNEXUS_IMAGE
constants and a caddyProxyPort() helper. Generated output is byte-identical
(existing template tests pass unchanged). buildMcpSnippet's auth-conditional
display port (opts.port+1 for token, opts.port for no-auth) is intentionally
left as-is — it is not the Caddy proxy port.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Gergo Magyar 2026-06-14 09:01:35 +00:00
parent 847e901e39
commit 2f7d62ba92

View file

@ -5,6 +5,17 @@ const COMMERCIAL_NOTICE =
'# ⚠ COMMERCIAL USE: verify PolyForm-Noncommercial-1.0.0 license before deploying to client environments.';
const GENERATED_NOTICE = '# Generated by: gitnexus ci-setup';
// The port gitnexus serve always binds inside the container/image (the host or
// proxy-facing port is derived from opts.port). Keep these in one place so the
// port contract can't drift across the generated artifacts.
const CONTAINER_PORT = 4747;
const GITNEXUS_IMAGE = 'ghcr.io/abhigyanpatwari/gitnexus:latest';
/** The Caddy reverse-proxy port (one above the gitnexus serve port). */
function caddyProxyPort(opts: CiSetupOptions): number {
return opts.port + 1;
}
function buildGitHubActionsWorkflow(opts: CiSetupOptions): string {
const onBlock =
opts.branchStrategy === 'pr-scoped'
@ -135,7 +146,7 @@ ${GENERATED_NOTICE}
services:
gitnexus:
image: ghcr.io/abhigyanpatwari/gitnexus:latest
image: ${GITNEXUS_IMAGE}
# No ports: — gitnexus is accessible only to the proxy on the internal network.
volumes:
- gitnexus-data:/data/gitnexus
@ -144,7 +155,7 @@ services:
GITNEXUS_HOME: /data/gitnexus
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:4747/api/health"]
test: ["CMD", "curl", "-f", "http://localhost:${CONTAINER_PORT}/api/health"]
interval: 30s
timeout: 5s
retries: 3
@ -153,7 +164,7 @@ services:
gitnexus-proxy:
image: caddy:alpine
ports:
- "\${GITNEXUS_PROXY_PORT:-${opts.port + 1}}:${opts.port + 1}"
- "\${GITNEXUS_PROXY_PORT:-${caddyProxyPort(opts)}}:${caddyProxyPort(opts)}"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
environment:
@ -178,9 +189,9 @@ ${GENERATED_NOTICE}
services:
gitnexus:
image: ghcr.io/abhigyanpatwari/gitnexus:latest
image: ${GITNEXUS_IMAGE}
ports:
- "\${GITNEXUS_PORT:-${opts.port}}:4747"
- "\${GITNEXUS_PORT:-${opts.port}}:${CONTAINER_PORT}"
volumes:
- gitnexus-data:/data/gitnexus
- \${WORKSPACE_DIR:-./workspace}:/workspace:ro
@ -188,7 +199,7 @@ services:
GITNEXUS_HOME: /data/gitnexus
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:4747/api/health"]
test: ["CMD", "curl", "-f", "http://localhost:${CONTAINER_PORT}/api/health"]
interval: 30s
timeout: 5s
retries: 3
@ -204,12 +215,12 @@ function buildDockerCompose(opts: CiSetupOptions): string {
}
function buildCaddyfile(opts: CiSetupOptions): string {
const proxyPort = opts.port + 1;
const proxyPort = caddyProxyPort(opts);
return `:${proxyPort} {
@authorized header Authorization "Bearer {env.GITNEXUS_TOKEN}"
handle @authorized {
reverse_proxy gitnexus:4747
reverse_proxy gitnexus:${CONTAINER_PORT}
}
respond "Unauthorized" 401
@ -284,8 +295,8 @@ az containerapp create \\
--name "\$APP_NAME" \\
--resource-group "\$RESOURCE_GROUP" \\
--environment "\$ENVIRONMENT" \\
--image ghcr.io/abhigyanpatwari/gitnexus:latest \\
--target-port 4747 \\
--image ${GITNEXUS_IMAGE} \\
--target-port ${CONTAINER_PORT} \\
--ingress internal \\
--env-vars "GITNEXUS_HOME=/data/gitnexus" \\
--volume-name gitnexus-data \\
@ -361,7 +372,7 @@ Copy the MCP entry from \`.claude/gitnexus-mcp-snippet.json\` into \`~/.claude/s
"mcpServers": {
"gitnexus": {
"type": "http",
"url": "http://<GITNEXUS_HOST>:${opts.port + 1}/api/mcp",
"url": "http://<GITNEXUS_HOST>:${caddyProxyPort(opts)}/api/mcp",
"headers": {
"Authorization": "Bearer YOUR_GITNEXUS_TOKEN"
}
@ -420,7 +431,7 @@ execution flows, and blast-radius impact — without reading every file on every
| Auth model | ${authLabel} | ${opts.auth === 'token' ? 'Prevents unauthorized access to indexed source code' : 'Deployment behind trusted network perimeter'} |
| Branch index strategy | ${branchLabel} | ${opts.branchStrategy === 'pr-scoped' ? 'Keeps AI clients aware of in-progress work on open PRs' : 'Simpler; indexes only merged code'} |
| Server port | ${opts.port} | Default \`gitnexus serve\` port |
${opts.auth === 'token' ? `| Proxy port | ${opts.port + 1} | Caddy listens here; gitnexus is internal-only |\n` : ''}
${opts.auth === 'token' ? `| Proxy port | ${caddyProxyPort(opts)} | Caddy listens here; gitnexus is internal-only |\n` : ''}
---
## Connecting your AI client