feat (experimental): give every app a local git repo and deploy on merge (v2.7.204) - #27
Open
akindejuh wants to merge 1 commit into
Open
feat (experimental): give every app a local git repo and deploy on merge (v2.7.204)#27akindejuh wants to merge 1 commit into
akindejuh wants to merge 1 commit into
Conversation
`git_app.go` has had a complete, hardened, unit-tested per-app git implementation since v2.6.x, but every caller was an MCP write path. In the framework and cloud editions those paths don't exist, so the code was unreachable: a locally scaffolded app had no history, and - because the scaffold shipped no .gitignore of its own - a user's first `git init && git add .` committed env.yaml and a binary data.db. The machinery was already there; nothing was calling it. `benmore new` now initialises the repo, writes the protective .gitignore, and points core.hooksPath at a tracked .githooks/ directory. Hooks live in .githooks/ rather than .git/hooks/ because .git is never cloned - the deploy behaviour has to travel with the repo to be a team workflow rather than one machine's trick. Merging into the default branch deploys to the dev instance via `benmore deploy`, which keeps the server-side write-time validators in the path; having the router pull from git instead would have routed around the same gate that guards every other write. Production is deliberately not automated - `benmore promote` stays an explicit decision made after dev has been seen working, rather than making the riskiest deploy the one requiring the least intent. `benmore git-init` exists because `benmore new` is the rarest way an app reaches a developer's machine; apps arriving via pull/sync get a manifest but no repo. It is additive and idempotent throughout, so it is safe to point at a directory that already holds months of work. Verified: pull neither creates nor clobbers a repo and its drift guard still blocks overwrites, so local git and the .benmore/ manifest coexist. Two suite failures (TestAgentDocs_TopicsList, TestNoBareGoFuncInWorkers) predate this change - they fail identically on a clean tree and stem from files absent from the public export. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
git_app.gohas shipped a complete, hardened, unit-tested per-app git implementation since v2.6.x — but every caller was an MCP write path. In the framework and cloud editions those paths don't exist, so the code was unreachable: a locally scaffolded app got no history at all.Worse, the scaffold shipped no
.gitignoreof its own, so a user's firstgit init && git add .committedenv.yamland a binarydata.db. This PR closes that by construction.What
benmore newnow initialises the app as a real repo: framework.gitignore, initial commit, andcore.hooksPath→ a tracked.githooks/.Deploy on merge. Two tracked files are scaffolded:
.githooks/post-merge.github/workflows/benmore-deploy.ymlMerging the default branch deploys to dev. Other branches are ignored, so feature work stays local until it lands.
benmore git-init [dir]retrofits an existing app —benmore newis the rarest way an app reaches a machine; apps frompull/syncget a.benmore/manifest but no repo.Design decisions worth reviewing
benmore promotestays an explicit decision made after dev has been seen working, rather than making the riskiest deploy the one requiring the least intent.benmore deploy, which keeps the server-side write-time validators in the path. Having the router pull from git instead would have routed around the same gate that guards every other write..githooks/, not.git/hooks/—.gitis never cloned, so the behaviour has to travel with the repo to be a team workflow rather than one machine's trick.git-initis additive and idempotent throughout — existing repo keeps its history and branch name, existing.gitignore/hook keeps the user's version, re-run reports "already set up". Refuses any dir withoutapp.yaml/schema.prismaso it can't span a folder of apps.Verification
Manually tested across: no-repo app · re-run · existing repo with history and a non-
mainbranch name · non-app directory (refused) · hook firing after merge · feature-branch merges staying silent.Confirmed no secrets committed (
env.yaml,data.db*untracked), and thatpullneither creates nor clobbers a repo while its drift guard still blocks overwrites — local git and the.benmore/manifest coexist.New tests cover
gitEnsureIgnoreFile,writeDeployAutomation(including the executable bit, and asserting the hook never targets prod), andgitUseTrackedHooks/gitHooksPathSet.Known gap
The generated workflow authenticates via a
BENMORE_TOKENsecret. That name is unverified — the non-interactive auth path lives incli_platform.go, outside this repo. Worth a second pair of eyes before anyone relies on the GitHub-side path; the local hook path is fully tested.Propagation
Per
AGENTS.md:CHANGELOG.mdentry ✅ ·docs/agent/build.mdRecent row ✅ · version bump 2.7.203 → 2.7.204 ✅. ThetopicRecipesentry inmcp_tools_api.gocould not be updated — that file is not in this repo.🤖 Generated with Claude Code