mirror of
https://github.com/penpot/penpot.git
synced 2026-08-01 19:06:18 +00:00
✨ Wire host git identity into the devenv container
run-devenv-agentic now seeds the container's global git config from the
host on every bring-up so commits made inside the devenv (typically by
coding agents reached through start-coding-agent) carry a real
author/committer instead of the bare `penpot@<container>` fallback that
makes review unworkable.
New optional flags on run-devenv-agentic:
--git-user-name NAME author/committer name
--git-user-email EMAIL matching email
When a flag is omitted the value is resolved from the host's effective
`git config user.{name,email}` (plain `git config`, no --global) so a
per-repo override in <repo>/.git/config wins over ~/.gitconfig -- matching
what `git commit` on the host would actually record. If neither flag nor
host config provides a value the script prints a warning and continues;
in-container commits will fail until the user fixes it.
start-instance applies the values via two `docker exec ... git config
--global user.{name,email}` calls right after the container reaches
Running, before start-tmux.sh is launched. Keeps the write logic next to
the rest of the per-instance bring-up and out of the tmux script -- no
env-var contract between manage.sh and the tmux entry point is needed.
Docs updated in docs/technical-guide/developer/devenv.md (new "Git
identity inside the container" section) and the agentic-devenv guide.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5efec8fad5
commit
ea5a2f6b4c
@ -85,6 +85,19 @@ instance up, so you don't need to compute the offsets by hand. See the
|
|||||||
the workspace and lifecycle details (including the `--sync` flag and shutdown
|
the workspace and lifecycle details (including the `--sync` flag and shutdown
|
||||||
shape).
|
shape).
|
||||||
|
|
||||||
|
**Git identity for agent commits.** Coding agents typically need to commit
|
||||||
|
inside the devenv, so `run-devenv-agentic` wires a Git identity into the
|
||||||
|
container's global config on every bring-up. By default it propagates the
|
||||||
|
host's effective `git config user.{name,email}` (local repo override wins
|
||||||
|
over `~/.gitconfig`, matching what `git commit` on the host would record).
|
||||||
|
Override either with `--git-user-name "Full Name"` /
|
||||||
|
`--git-user-email you@example.com` — useful when you want agent commits to
|
||||||
|
carry an identity different from your normal one. Without either source the
|
||||||
|
script warns and proceeds; commits made by the agent will fail until you fix
|
||||||
|
it. See the
|
||||||
|
[Dev environment guide](./devenv.md#git-identity-inside-the-container) for
|
||||||
|
the full mechanics.
|
||||||
|
|
||||||
> **Note:** the MCP and Serena tmux windows are only added when the session is
|
> **Note:** the MCP and Serena tmux windows are only added when the session is
|
||||||
> first created. If you've already run `./manage.sh run-devenv` (non-agentic)
|
> first created. If you've already run `./manage.sh run-devenv` (non-agentic)
|
||||||
> in an instance, `run-devenv-agentic` errors out because the instance is
|
> in an instance, `run-devenv-agentic` errors out because the instance is
|
||||||
|
|||||||
@ -106,7 +106,27 @@ Container-internal ports stay fixed. Target a specific instance with
|
|||||||
`start-coding-agent` (`--instance ws1` on `run-devenv-shell` /
|
`start-coding-agent` (`--instance ws1` on `run-devenv-shell` /
|
||||||
`run-devenv`). The `--ws` flag accepts a **non-negative integer only** —
|
`run-devenv`). The `--ws` flag accepts a **non-negative integer only** —
|
||||||
`--ws main` or `--ws ws1` is rejected, keeping the flag shape uniform across
|
`--ws main` or `--ws ws1` is rejected, keeping the flag shape uniform across
|
||||||
commands. `run-devenv-agentic` also accepts `--serena-context CTX`.
|
commands. `run-devenv-agentic` also accepts `--serena-context CTX` and
|
||||||
|
`--git-user-name NAME` / `--git-user-email EMAIL` (see below).
|
||||||
|
|
||||||
|
### Git identity inside the container
|
||||||
|
|
||||||
|
`run-devenv-agentic` wires a Git author identity into the container's
|
||||||
|
**global** git config (`git config --global user.{name,email}`) so commits
|
||||||
|
made from inside the devenv carry a real author/committer. Without this,
|
||||||
|
the container would commit as the unconfigured `penpot@<container>`
|
||||||
|
fallback — usable but useless for review.
|
||||||
|
|
||||||
|
The values come from `--git-user-name NAME` / `--git-user-email EMAIL`
|
||||||
|
when passed, or from your host's effective `git config user.{name,email}`
|
||||||
|
otherwise. "Effective" here means the values plain `git config user.X`
|
||||||
|
returns at the working directory `manage.sh` is invoked from — local
|
||||||
|
(`<repo>/.git/config`) overrides global (`~/.gitconfig`), matching what
|
||||||
|
`git commit` on the host would record. If neither is available the script
|
||||||
|
prints a warning and continues — commits will fail inside the container
|
||||||
|
until you set an identity. The values are applied every time
|
||||||
|
`run-devenv-agentic` brings an instance up (idempotent), so re-running
|
||||||
|
with different flags is the way to change the in-container identity.
|
||||||
|
|
||||||
### Shared state and workers
|
### Shared state and workers
|
||||||
|
|
||||||
|
|||||||
55
manage.sh
55
manage.sh
@ -645,6 +645,8 @@ function parse-ws-integer {
|
|||||||
function start-instance {
|
function start-instance {
|
||||||
local instance="$1"
|
local instance="$1"
|
||||||
local serena_context="$2"
|
local serena_context="$2"
|
||||||
|
local git_user_name="${3:-}"
|
||||||
|
local git_user_email="${4:-}"
|
||||||
|
|
||||||
instance-compose "$instance" up -d --no-deps main redis
|
instance-compose "$instance" up -d --no-deps main redis
|
||||||
|
|
||||||
@ -660,6 +662,16 @@ function start-instance {
|
|||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Seed the container's global git config from the values resolved on the
|
||||||
|
# host so commits made inside the devenv carry a real author/committer. Empty
|
||||||
|
# values are skipped — the host-identity warning is the caller's job.
|
||||||
|
if [[ -n "$git_user_name" ]]; then
|
||||||
|
docker exec "$container" sudo -u penpot git config --global user.name "$git_user_name"
|
||||||
|
fi
|
||||||
|
if [[ -n "$git_user_email" ]]; then
|
||||||
|
docker exec "$container" sudo -u penpot git config --global user.email "$git_user_email"
|
||||||
|
fi
|
||||||
|
|
||||||
# Detached tmux so callers don't block on attach. Agentic mode is the only
|
# Detached tmux so callers don't block on attach. Agentic mode is the only
|
||||||
# mode here, so MCP and Serena are always on.
|
# mode here, so MCP and Serena are always on.
|
||||||
docker exec -d \
|
docker exec -d \
|
||||||
@ -710,6 +722,14 @@ function print-instance-info {
|
|||||||
# ws1+ also sync implicitly the first time when their workspace
|
# ws1+ also sync implicitly the first time when their workspace
|
||||||
# directory does not exist yet.
|
# directory does not exist yet.
|
||||||
# --serena-context CTX passed to Serena (default: desktop-app).
|
# --serena-context CTX passed to Serena (default: desktop-app).
|
||||||
|
# --git-user-name NAME Git author/committer name to wire into the
|
||||||
|
# container's global git config (so commits made inside the
|
||||||
|
# devenv carry a real identity). Defaults to the host's
|
||||||
|
# effective `git config user.name` when omitted (resolved at
|
||||||
|
# the current working directory, so a per-repo local override
|
||||||
|
# in <repo>/.git/config takes precedence over ~/.gitconfig).
|
||||||
|
# --git-user-email EMAIL matching email; defaults to the host's effective
|
||||||
|
# `git config user.email` (same local-over-global precedence).
|
||||||
#
|
#
|
||||||
# ws0 is the worker-bearer and must be running whenever any ws1+ is up. When
|
# ws0 is the worker-bearer and must be running whenever any ws1+ is up. When
|
||||||
# starting ws1+, ws0 is brought up first automatically if it is not already
|
# starting ws1+, ws0 is brought up first automatically if it is not already
|
||||||
@ -718,6 +738,8 @@ function run-devenv-agentic {
|
|||||||
local target="ws0"
|
local target="ws0"
|
||||||
local do_sync=false
|
local do_sync=false
|
||||||
local serena_context="desktop-app"
|
local serena_context="desktop-app"
|
||||||
|
local git_user_name=""
|
||||||
|
local git_user_email=""
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@ -727,6 +749,10 @@ function run-devenv-agentic {
|
|||||||
do_sync=true; shift;;
|
do_sync=true; shift;;
|
||||||
--serena-context)
|
--serena-context)
|
||||||
serena_context="$2"; shift 2;;
|
serena_context="$2"; shift 2;;
|
||||||
|
--git-user-name)
|
||||||
|
git_user_name="$2"; shift 2;;
|
||||||
|
--git-user-email)
|
||||||
|
git_user_email="$2"; shift 2;;
|
||||||
*)
|
*)
|
||||||
echo "run-devenv-agentic: unknown argument '$1'" >&2
|
echo "run-devenv-agentic: unknown argument '$1'" >&2
|
||||||
return 1;;
|
return 1;;
|
||||||
@ -738,6 +764,26 @@ function run-devenv-agentic {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Fall back to the host developer's effective git identity when the
|
||||||
|
# respective flag is not provided. Plain `git config user.X` (no --global)
|
||||||
|
# honours the local->global->system precedence, so a per-repo override in
|
||||||
|
# <repo>/.git/config takes precedence over ~/.gitconfig -- matching what
|
||||||
|
# `git commit` on the host would actually record. `|| true` swallows the
|
||||||
|
# non-zero exit for a missing entry; the empty result is propagated
|
||||||
|
# untouched and surfaces as a no-op inside the container (start-tmux.sh
|
||||||
|
# skips `git config --global` when the env var is empty).
|
||||||
|
if [[ -z "$git_user_name" ]]; then
|
||||||
|
git_user_name="$(git config user.name 2>/dev/null || true)"
|
||||||
|
fi
|
||||||
|
if [[ -z "$git_user_email" ]]; then
|
||||||
|
git_user_email="$(git config user.email 2>/dev/null || true)"
|
||||||
|
fi
|
||||||
|
if [[ -z "$git_user_name" || -z "$git_user_email" ]]; then
|
||||||
|
echo "[$target] warning: host git identity is incomplete (name='${git_user_name}', email='${git_user_email}')." >&2
|
||||||
|
echo " Commits made inside the devenv will fail until you set it via --git-user-name / --git-user-email" >&2
|
||||||
|
echo " or 'git config user.{name,email}' on the host." >&2
|
||||||
|
fi
|
||||||
|
|
||||||
if devenv-main-running "$target"; then
|
if devenv-main-running "$target"; then
|
||||||
echo "run-devenv-agentic: instance '$target' is already running." >&2
|
echo "run-devenv-agentic: instance '$target' is already running." >&2
|
||||||
return 1
|
return 1
|
||||||
@ -753,7 +799,7 @@ function run-devenv-agentic {
|
|||||||
echo "[ws0] not running; starting it first (workers run only on ws0)."
|
echo "[ws0] not running; starting it first (workers run only on ws0)."
|
||||||
echo "Starting ws0..."
|
echo "Starting ws0..."
|
||||||
write-instance-mcp-configs "ws0"
|
write-instance-mcp-configs "ws0"
|
||||||
start-instance "ws0" "$serena_context"
|
start-instance "ws0" "$serena_context" "$git_user_name" "$git_user_email"
|
||||||
print-instance-info "ws0"
|
print-instance-info "ws0"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -772,7 +818,7 @@ function run-devenv-agentic {
|
|||||||
|
|
||||||
echo "Starting $target..."
|
echo "Starting $target..."
|
||||||
write-instance-mcp-configs "$target"
|
write-instance-mcp-configs "$target"
|
||||||
start-instance "$target" "$serena_context"
|
start-instance "$target" "$serena_context" "$git_user_name" "$git_user_email"
|
||||||
print-instance-info "$target"
|
print-instance-info "$target"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1185,7 +1231,10 @@ function usage {
|
|||||||
echo " Auto-starts ws0 first when --ws N (N>=1) is requested (workers run only on ws0)."
|
echo " Auto-starts ws0 first when --ws N (N>=1) is requested (workers run only on ws0)."
|
||||||
echo " Options: --ws N (default: 0; non-negative integer only),"
|
echo " Options: --ws N (default: 0; non-negative integer only),"
|
||||||
echo " --sync (re-seed workspace from live repo; ws1+ only),"
|
echo " --sync (re-seed workspace from live repo; ws1+ only),"
|
||||||
echo " --serena-context CONTEXT (default: desktop-app)"
|
echo " --serena-context CONTEXT (default: desktop-app),"
|
||||||
|
echo " --git-user-name NAME / --git-user-email EMAIL"
|
||||||
|
echo " (default: host's effective 'git config user.{name,email}',"
|
||||||
|
echo " honouring per-repo local overrides)"
|
||||||
echo "- attach-devenv Attaches to the tmux session inside a running instance."
|
echo "- attach-devenv Attaches to the tmux session inside a running instance."
|
||||||
echo " Options: --ws N (default: 0; non-negative integer only)"
|
echo " Options: --ws N (default: 0; non-negative integer only)"
|
||||||
echo "- start-coding-agent <client> Launches an AI coding agent against one workspace with the right MCP config wired in."
|
echo "- start-coding-agent <client> Launches an AI coding agent against one workspace with the right MCP config wired in."
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user