Skip to content

Commit e80467d

Browse files
committed
feat(state): track full state dir in git
1 parent d3b06b8 commit e80467d

1 file changed

Lines changed: 31 additions & 28 deletions

File tree

effect-template/packages/lib/src/usecases/state-repo.ts

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,36 +25,43 @@ const resolveStateRoot = (
2525
cwd: string
2626
): string => path.resolve(defaultProjectsRoot(cwd))
2727

28+
const stateGitignoreMarker = "# docker-git state repository"
29+
2830
const defaultStateGitignore = [
29-
"# docker-git state repository",
30-
"# Generated by docker-git to prevent committing secrets and machine-local files.",
31-
"",
32-
"# Secrets (tokens, auth, env)",
33-
"**/.orch/env/",
34-
"**/.orch/auth/",
35-
"",
36-
"# Logs",
37-
"**/*.log",
38-
"",
39-
"# Machine-local SSH allow-list",
40-
"authorized_keys",
31+
stateGitignoreMarker,
32+
"# NOTE: this repo intentionally tracks EVERYTHING under the state dir, including .orch/env and .orch/auth.",
33+
"# Keep the remote private; treat it as sensitive infrastructure state.",
4134
""
4235
].join("\n")
4336

44-
const requiredGitignorePatterns: ReadonlyArray<string> = [
45-
"**/.orch/env/",
46-
"**/.orch/auth/"
47-
]
37+
const normalizeGitignoreText = (text: string): string =>
38+
text
39+
.replaceAll("\r\n", "\n")
40+
.trim()
4841

49-
// CHANGE: ensure state repo has a safe .gitignore
50-
// WHY: prevent accidental commit of secrets (tokens, auth, env) when using git-synced state
51-
// QUOTE(ТЗ): "общая память через гит" / "иметь возможность комитить его на гит"
52-
// REF: user-request-2026-02-08-state-gitignore
42+
const shouldRewriteDockerGitStateGitignore = (existing: string): boolean => {
43+
const normalized = normalizeGitignoreText(existing)
44+
if (!normalized.startsWith(stateGitignoreMarker)) {
45+
return false
46+
}
47+
// Old docker-git default tried to prevent committing secrets. If we still see those patterns,
48+
// rewrite to the new "track everything" default.
49+
const hadSecretIgnores = normalized.includes("**/.orch/env/") || normalized.includes("**/.orch/auth/")
50+
if (!hadSecretIgnores) {
51+
return false
52+
}
53+
return normalized !== normalizeGitignoreText(defaultStateGitignore)
54+
}
55+
56+
// CHANGE: ensure state repo has a .gitignore that allows committing the full state directory
57+
// WHY: user wants the whole ~/.docker-git (including .orch/auth) to be synced via git
58+
// QUOTE(ТЗ): "чтобы вся папка .docker-git уходила на гит Даже .orch/auth и тд"
59+
// REF: user-request-2026-02-10-state-track-all
5360
// SOURCE: n/a
54-
// FORMAT THEOREM: forall root: ensureGitignore(root) -> patternsIncluded(root, required)
61+
// FORMAT THEOREM: forall root: ensureGitignore(root) -> exists(.gitignore(root))
5562
// PURITY: SHELL
5663
// EFFECT: Effect<void, PlatformError, FileSystem | Path>
57-
// INVARIANT: preserves existing file content; only appends missing patterns
64+
// INVARIANT: rewrites only docker-git-managed .gitignore that previously ignored secrets
5865
// COMPLEXITY: O(n) where n = |.gitignore|
5966
const ensureStateGitignore = (
6067
fs: FileSystem.FileSystem,
@@ -76,14 +83,10 @@ const ensureStateGitignore = (
7683
}
7784

7885
const prev = yield* _(fs.readFileString(gitignorePath))
79-
const prevLines = new Set(prev.replaceAll("\r", "").split("\n").map((l) => l.trimEnd()))
80-
const missing = requiredGitignorePatterns.filter((p) => !prevLines.has(p))
81-
if (missing.length === 0) {
86+
if (!shouldRewriteDockerGitStateGitignore(prev)) {
8287
return
8388
}
84-
85-
const next = `${prev.trimEnd()}\n\n# Added by docker-git\n${missing.join("\n")}\n`
86-
yield* _(fs.writeFileString(gitignorePath, next))
89+
yield* _(fs.writeFileString(gitignorePath, defaultStateGitignore))
8790
})
8891

8992
// CHANGE: manage docker-git state dir as a git repository

0 commit comments

Comments
 (0)