Skip to content

Commit 4ae728c

Browse files
committed
fix(core): move session backup hook to post-push
1 parent 895f9fd commit 4ae728c

4 files changed

Lines changed: 30 additions & 8 deletions

File tree

packages/lib/src/core/docker-git-scripts.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
/**
1212
* Names of docker-git scripts that must be available inside generated containers.
1313
*
14-
* These scripts are referenced by git hooks (pre-push, pre-commit) and session
15-
* backup workflows. They are copied into each project's build context under
14+
* These scripts are referenced by git hooks (pre-push, post-push, pre-commit) and
15+
* session backup workflows. They are copied into each project's build context under
1616
* `scripts/` and embedded into the Docker image at `/opt/docker-git/scripts/`.
1717
*
1818
* @pure true

packages/lib/src/core/templates-entrypoint/git.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ const entrypointGitHooksTemplate = String
129129
.raw`# 3) Install global git hooks to protect main/master + managed AGENTS context
130130
HOOKS_DIR="/opt/docker-git/hooks"
131131
PRE_PUSH_HOOK="$HOOKS_DIR/pre-push"
132+
POST_PUSH_HOOK="$HOOKS_DIR/post-push"
132133
mkdir -p "$HOOKS_DIR"
133134
134135
cat <<'EOF' > "$PRE_PUSH_HOOK"
@@ -256,14 +257,17 @@ done
256257
EOF
257258
chmod 0755 "$PRE_PUSH_HOOK"
258259
259-
cat <<'EOF' >> "$PRE_PUSH_HOOK"
260+
cat <<'EOF' > "$POST_PUSH_HOOK"
261+
#!/usr/bin/env bash
262+
set -euo pipefail
260263
264+
# 5) Run session backup after successful push
261265
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
262266
cd "$REPO_ROOT"
263267
264-
# CHANGE: resolve session-backup script from /opt/docker-git/scripts (embedded) or repo-local fallback
265-
# WHY: docker-git scripts are now embedded in the container image at /opt/docker-git/scripts
266-
# REF: issue-176
268+
# CHANGE: run session backup in post-push so source commit has already landed in remote
269+
# WHY: backups should mirror successfully pushed state and not block push validation
270+
# REF: issue-192
267271
if [ "${"${"}DOCKER_GIT_SKIP_SESSION_BACKUP:-}" != "1" ]; then
268272
if command -v gh >/dev/null 2>&1; then
269273
BACKUP_SCRIPT=""
@@ -273,11 +277,13 @@ if [ "${"${"}DOCKER_GIT_SKIP_SESSION_BACKUP:-}" != "1" ]; then
273277
BACKUP_SCRIPT="$REPO_ROOT/scripts/session-backup-gist.js"
274278
fi
275279
if [ -n "$BACKUP_SCRIPT" ]; then
276-
node "$BACKUP_SCRIPT" --verbose || echo "[session-backup] Warning: session backup failed (non-fatal)"
280+
node "$BACKUP_SCRIPT" || echo "[session-backup] Warning: session backup failed (non-fatal)"
277281
fi
278282
fi
279283
fi
280284
EOF
285+
chmod 0755 "$POST_PUSH_HOOK"
286+
281287
git config --system core.hooksPath "$HOOKS_DIR" || true
282288
git config --global core.hooksPath "$HOOKS_DIR" || true`
283289

packages/lib/tests/core/templates.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { defaultTemplateConfig, type TemplateConfig } from "../../src/core/domai
44
import { renderDockerCompose } from "../../src/core/templates/docker-compose.js"
55
import { renderEntrypoint } from "../../src/core/templates-entrypoint.js"
66
import { renderEntrypointDnsRepair } from "../../src/core/templates-entrypoint/dns-repair.js"
7+
import { renderEntrypointGitHooks } from "../../src/core/templates-entrypoint/git.js"
78

89
const makeTemplateConfig = (overrides: Partial<TemplateConfig> = {}): TemplateConfig => ({
910
...defaultTemplateConfig,
@@ -47,6 +48,21 @@ describe("renderEntrypointDnsRepair", () => {
4748
})
4849
})
4950

51+
describe("renderEntrypointGitHooks", () => {
52+
it("installs pre-push protection checks and post-push backup hook", () => {
53+
const hooks = renderEntrypointGitHooks()
54+
55+
expect(hooks).toContain('PRE_PUSH_HOOK="$HOOKS_DIR/pre-push"')
56+
expect(hooks).toContain('POST_PUSH_HOOK="$HOOKS_DIR/post-push"')
57+
expect(hooks).toContain("cat <<'EOF' > \"$PRE_PUSH_HOOK\"")
58+
expect(hooks).toContain("cat <<'EOF' > \"$POST_PUSH_HOOK\"")
59+
expect(hooks).toContain("check_issue_managed_block_range")
60+
expect(hooks).toContain("Run session backup after successful push")
61+
expect(hooks).toContain("node \"$BACKUP_SCRIPT\"")
62+
expect(hooks).not.toContain("node \"$BACKUP_SCRIPT\" --verbose")
63+
})
64+
})
65+
5066
describe("renderDockerCompose", () => {
5167
it("renders fallback DNS servers for the main container even without Playwright", () => {
5268
const compose = renderDockerCompose(makeTemplateConfig())

scripts/session-backup-gist.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ const buildSnapshotReadme = ({ backupRepo, source, manifestUrl, summary, session
410410
"",
411411
`- Manifest: ${manifestUrl}`,
412412
"",
413-
"Generated automatically by the docker-git `pre-push` session backup hook.",
413+
"Generated automatically by the docker-git `post-push` session backup hook.",
414414
"",
415415
].join("\n");
416416

0 commit comments

Comments
 (0)