feat(agent-queue): PR mode uses existing local repo via git worktree (no clone)
When AQ_FLEET_REPO_BASE/<repo> is an existing checkout, create a git worktree off it for branch aq/job/<id> (shares objects + remotes, leaves the main checkout untouched) instead of cloning. Falls back to clone for remote-only repos. selftest exercises the worktree path. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
b442b95728
commit
d6fa1d9e28
@ -643,39 +643,44 @@ build_agent_cmd() {
|
|||||||
_fleet_pr_prepare() {
|
_fleet_pr_prepare() {
|
||||||
local repo=$1 base=${2:-main} jid=$3 logf=$4
|
local repo=$1 base=${2:-main} jid=$3 logf=$4
|
||||||
local reposdir="${AQ_FLEET_REPOS_DIR:-$STATE/repos}"; mkdir -p "$reposdir"
|
local reposdir="${AQ_FLEET_REPOS_DIR:-$STATE/repos}"; mkdir -p "$reposdir"
|
||||||
local safe dir url br src="" origin_url=""
|
local safe dir url br sp; safe=$(printf '%s' "$repo" | tr -c 'A-Za-z0-9._-' '_')
|
||||||
safe=$(printf '%s' "$repo" | tr -c 'A-Za-z0-9._-' '_'); dir="$reposdir/$safe"
|
br="aq/job/$jid"
|
||||||
# MVP: if AQ_FLEET_REPO_BASE/<repo> is an existing local repo, use it as the clone
|
|
||||||
# SOURCE (fast, no network) and push/PR to its GitHub origin. Credentials embedded
|
# MVP: if AQ_FLEET_REPO_BASE/<repo> is an existing local checkout, use it via a
|
||||||
# in the local origin URL are stripped — gh's credential helper handles auth.
|
# git WORKTREE — no clone. The worktree shares the repo's objects + remotes (push/
|
||||||
|
# PR go to its origin) and leaves the main checkout untouched. One worktree dir per
|
||||||
|
# repo, force-recreated each job.
|
||||||
if [[ -n "${AQ_FLEET_REPO_BASE:-}" && -d "$AQ_FLEET_REPO_BASE/$repo/.git" ]]; then
|
if [[ -n "${AQ_FLEET_REPO_BASE:-}" && -d "$AQ_FLEET_REPO_BASE/$repo/.git" ]]; then
|
||||||
src="$AQ_FLEET_REPO_BASE/$repo"
|
local src="$AQ_FLEET_REPO_BASE/$repo" wt="$reposdir/${safe}__wt"
|
||||||
origin_url=$(git -C "$src" remote get-url origin 2>/dev/null | sed -E 's#://[^@/]*@#://#')
|
git -C "$src" fetch --quiet origin "$base" >>"$logf" 2>&1 || true
|
||||||
fi
|
git -C "$src" worktree remove --force "$wt" >>"$logf" 2>&1 || true
|
||||||
# Resolve a clone URL: local source wins; else full URLs pass through; absolute/
|
git -C "$src" worktree prune >>"$logf" 2>&1 || true
|
||||||
# existing local paths used as-is; otherwise `owner/name` -> GitHub HTTPS.
|
rm -rf "$wt" 2>/dev/null || true
|
||||||
if [[ -n "$src" ]]; then url="$src"; else
|
sp="origin/$base"; git -C "$src" rev-parse -q --verify "$sp" >/dev/null 2>&1 || sp="$base"
|
||||||
case "$repo" in
|
git -C "$src" worktree add --force -B "$br" "$wt" "$sp" >>"$logf" 2>&1 \
|
||||||
*://*|git@*) url="$repo";;
|
|| { echo "PR: worktree add failed ($src $sp)" >>"$logf"; return 1; }
|
||||||
/*) url="$repo";;
|
git -C "$wt" config user.email >/dev/null 2>&1 || git -C "$wt" config user.email "agent-queue@fleet.local"
|
||||||
*) [[ -e "$repo" ]] && url="$repo" || url="https://github.com/$repo.git";;
|
git -C "$wt" config user.name >/dev/null 2>&1 || git -C "$wt" config user.name "agent-queue"
|
||||||
esac
|
echo "$wt"; return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Fallback (no local checkout): clone. Full URLs pass through; absolute/existing
|
||||||
|
# local paths used as-is; otherwise `owner/name` -> GitHub HTTPS.
|
||||||
|
dir="$reposdir/$safe"
|
||||||
|
case "$repo" in
|
||||||
|
*://*|git@*) url="$repo";;
|
||||||
|
/*) url="$repo";;
|
||||||
|
*) [[ -e "$repo" ]] && url="$repo" || url="https://github.com/$repo.git";;
|
||||||
|
esac
|
||||||
if [[ -d "$dir/.git" ]]; then
|
if [[ -d "$dir/.git" ]]; then
|
||||||
[[ -n "$origin_url" ]] && git -C "$dir" remote set-url origin "$origin_url" >>"$logf" 2>&1 || true
|
|
||||||
git -C "$dir" fetch --quiet origin "$base" >>"$logf" 2>&1 || { echo "PR: fetch failed for $base" >>"$logf"; return 1; }
|
git -C "$dir" fetch --quiet origin "$base" >>"$logf" 2>&1 || { echo "PR: fetch failed for $base" >>"$logf"; return 1; }
|
||||||
else
|
else
|
||||||
git clone --quiet "$url" "$dir" >>"$logf" 2>&1 || { echo "PR: clone failed for $url" >>"$logf"; return 1; }
|
git clone --quiet "$url" "$dir" >>"$logf" 2>&1 || { echo "PR: clone failed for $url" >>"$logf"; return 1; }
|
||||||
# Repoint to the upstream GitHub origin (when cloned from a local mirror).
|
|
||||||
[[ -n "$origin_url" ]] && git -C "$dir" remote set-url origin "$origin_url" >>"$logf" 2>&1 || true
|
|
||||||
git -C "$dir" fetch --quiet origin "$base" >>"$logf" 2>&1 || true
|
git -C "$dir" fetch --quiet origin "$base" >>"$logf" 2>&1 || true
|
||||||
fi
|
fi
|
||||||
br="aq/job/$jid"
|
|
||||||
git -C "$dir" checkout --quiet -B "$br" "origin/$base" >>"$logf" 2>&1 \
|
git -C "$dir" checkout --quiet -B "$br" "origin/$base" >>"$logf" 2>&1 \
|
||||||
|| git -C "$dir" checkout --quiet -B "$br" "$base" >>"$logf" 2>&1 \
|
|| git -C "$dir" checkout --quiet -B "$br" "$base" >>"$logf" 2>&1 \
|
||||||
|| { echo "PR: cannot branch $br off $base" >>"$logf"; return 1; }
|
|| { echo "PR: cannot branch $br off $base" >>"$logf"; return 1; }
|
||||||
# Ensure a commit identity exists (fall back to a bot identity if the host has
|
|
||||||
# no global git user configured) so the PR commit never fails.
|
|
||||||
git -C "$dir" config user.email >/dev/null 2>&1 || git -C "$dir" config user.email "agent-queue@fleet.local"
|
git -C "$dir" config user.email >/dev/null 2>&1 || git -C "$dir" config user.email "agent-queue@fleet.local"
|
||||||
git -C "$dir" config user.name >/dev/null 2>&1 || git -C "$dir" config user.name "agent-queue"
|
git -C "$dir" config user.name >/dev/null 2>&1 || git -C "$dir" config user.name "agent-queue"
|
||||||
echo "$dir"
|
echo "$dir"
|
||||||
|
|||||||
@ -868,8 +868,10 @@ fi
|
|||||||
# 35d. PR mode: a fleet job carrying a `repo` -> agent works on aq/job/<id> in an
|
# 35d. PR mode: a fleet job carrying a `repo` -> agent works on aq/job/<id> in an
|
||||||
# isolated checkout, PR is opened (gh stub), and the prUrl is reported on release.
|
# isolated checkout, PR is opened (gh stub), and the prUrl is reported on release.
|
||||||
prbare="$tmp/pr-origin.git"; git init --bare -q "$prbare"
|
prbare="$tmp/pr-origin.git"; git init --bare -q "$prbare"
|
||||||
prseed="$tmp/pr-seed"; git clone -q "$prbare" "$prseed" 2>/dev/null
|
# Existing local checkout under a repo base (worktree source — no clone at job time).
|
||||||
( cd "$prseed" && git config user.email t@t && git config user.name t \
|
prbase="$tmp/prbase"; mkdir -p "$prbase"
|
||||||
|
git clone -q "$prbare" "$prbase/learning_test" 2>/dev/null
|
||||||
|
( cd "$prbase/learning_test" && git config user.email t@t && git config user.name t \
|
||||||
&& echo seed > README.md && git add -A && git commit -qm seed \
|
&& echo seed > README.md && git add -A && git commit -qm seed \
|
||||||
&& git branch -M main && git push -q origin main ) >/dev/null 2>&1
|
&& git branch -M main && git push -q origin main ) >/dev/null 2>&1
|
||||||
prengine="$tmp/pr-engine"
|
prengine="$tmp/pr-engine"
|
||||||
@ -879,10 +881,10 @@ printf '#!/usr/bin/env bash\necho "$@" >> "%s"\necho "https://github.com/test/re
|
|||||||
export AGENT_QUEUE_ROOT="$tmp/queue-fl-pr"; export AQ_FLEET_CWD="$work"
|
export AGENT_QUEUE_ROOT="$tmp/queue-fl-pr"; export AQ_FLEET_CWD="$work"
|
||||||
"$AQ" init >/dev/null
|
"$AQ" init >/dev/null
|
||||||
export AQ_FSTUB_CALLS="$tmp/fl-pr-calls.log" AQ_FSTUB_CLAIM_FLAG="$tmp/fl-pr-claimed" \
|
export AQ_FSTUB_CALLS="$tmp/fl-pr-calls.log" AQ_FSTUB_CLAIM_FLAG="$tmp/fl-pr-claimed" \
|
||||||
AQ_FSTUB_JOB_ID="fjob_pr" AQ_FSTUB_BODY="add a file" AQ_FSTUB_REPO="$prbare" AQ_FSTUB_BASE="main" \
|
AQ_FSTUB_JOB_ID="fjob_pr" AQ_FSTUB_BODY="add a file" AQ_FSTUB_REPO="learning_test" AQ_FSTUB_BASE="main" \
|
||||||
AQ_FSTUB_VERIFY="true" AQ_FSTUB_AUTOMERGE="1"
|
AQ_FSTUB_VERIFY="true" AQ_FSTUB_AUTOMERGE="1"
|
||||||
: > "$AQ_FSTUB_CALLS"; rm -f "$AQ_FSTUB_CLAIM_FLAG"
|
: > "$AQ_FSTUB_CALLS"; rm -f "$AQ_FSTUB_CLAIM_FLAG"
|
||||||
AQ_FLEET=1 AQ_FLEET_PR=1 AQ_FLEET_AUTOSHIP=1 AGENT_QUEUE_POLL=1 \
|
AQ_FLEET=1 AQ_FLEET_PR=1 AQ_FLEET_AUTOSHIP=1 AGENT_QUEUE_POLL=1 AQ_FLEET_REPO_BASE="$prbase" \
|
||||||
AQ_FLEET_REPOS_DIR="$tmp/pr-repos" GH_BIN="$ghstub" DEVIN_BIN="$prengine" "$AQ" run --once >/dev/null 2>&1
|
AQ_FLEET_REPOS_DIR="$tmp/pr-repos" GH_BIN="$ghstub" DEVIN_BIN="$prengine" "$AQ" run --once >/dev/null 2>&1
|
||||||
if git -C "$prbare" rev-parse --verify aq/job/fjob_pr >/dev/null 2>&1 \
|
if git -C "$prbare" rev-parse --verify aq/job/fjob_pr >/dev/null 2>&1 \
|
||||||
&& grep -q -- '--title Add smoke marker file' "$tmp/gh-calls.log" 2>/dev/null \
|
&& grep -q -- '--title Add smoke marker file' "$tmp/gh-calls.log" 2>/dev/null \
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user