Merge pull request 'fix: [nomad-prep] P12 — dispatcher commits result.json via git push, not bind-mount (#803)' (#818) from fix/issue-803 into main
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
This commit is contained in:
commit
c363ee0aea
1 changed files with 73 additions and 7 deletions
|
|
@ -342,30 +342,96 @@ get_dispatch_mode() {
|
|||
fi
|
||||
}
|
||||
|
||||
# Write result file for an action
|
||||
# Usage: write_result <action_id> <exit_code> <logs>
|
||||
write_result() {
|
||||
# Commit result.json to the ops repo via git push (portable, no bind-mount).
|
||||
#
|
||||
# Clones the ops repo into a scratch directory, writes the result file,
|
||||
# commits as vault-bot, and pushes to the primary branch.
|
||||
# Idempotent: skips if result.json already exists upstream.
|
||||
# Retries on push conflict with rebase-and-push (handles concurrent merges).
|
||||
#
|
||||
# Usage: commit_result_via_git <action_id> <exit_code> <logs>
|
||||
commit_result_via_git() {
|
||||
local action_id="$1"
|
||||
local exit_code="$2"
|
||||
local logs="$3"
|
||||
|
||||
local result_file="${VAULT_ACTIONS_DIR}/${action_id}.result.json"
|
||||
local result_relpath="vault/actions/${action_id}.result.json"
|
||||
local ops_clone_url="${FORGE_URL}/${FORGE_OPS_REPO}.git"
|
||||
local branch="${PRIMARY_BRANCH:-main}"
|
||||
local scratch_dir
|
||||
scratch_dir=$(mktemp -d /tmp/dispatcher-result-XXXXXX)
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -rf '${scratch_dir}'" RETURN
|
||||
|
||||
# Shallow clone of the ops repo — only the primary branch
|
||||
if ! git clone --depth 1 --branch "$branch" \
|
||||
"$ops_clone_url" "$scratch_dir" 2>/dev/null; then
|
||||
log "ERROR: Failed to clone ops repo for result commit (action ${action_id})"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Idempotency: skip if result.json already exists upstream
|
||||
if [ -f "${scratch_dir}/${result_relpath}" ]; then
|
||||
log "Result already exists upstream for ${action_id} — skipping commit"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Configure git identity as vault-bot
|
||||
git -C "$scratch_dir" config user.name "vault-bot"
|
||||
git -C "$scratch_dir" config user.email "vault-bot@disinto.local"
|
||||
|
||||
# Truncate logs if too long (keep last 1000 chars)
|
||||
if [ ${#logs} -gt 1000 ]; then
|
||||
logs="${logs: -1000}"
|
||||
fi
|
||||
|
||||
# Write result JSON
|
||||
# Write result JSON via jq (never string-interpolate into JSON)
|
||||
mkdir -p "$(dirname "${scratch_dir}/${result_relpath}")"
|
||||
jq -n \
|
||||
--arg id "$action_id" \
|
||||
--argjson exit_code "$exit_code" \
|
||||
--arg timestamp "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
|
||||
--arg logs "$logs" \
|
||||
'{id: $id, exit_code: $exit_code, timestamp: $timestamp, logs: $logs}' \
|
||||
> "$result_file"
|
||||
> "${scratch_dir}/${result_relpath}"
|
||||
|
||||
log "Result written: ${result_file}"
|
||||
git -C "$scratch_dir" add "$result_relpath"
|
||||
git -C "$scratch_dir" commit -q -m "vault: result for ${action_id}"
|
||||
|
||||
# Push with retry on conflict (rebase-and-push pattern).
|
||||
# Common case: admin merges another action PR between our clone and push.
|
||||
local attempt
|
||||
for attempt in 1 2 3; do
|
||||
if git -C "$scratch_dir" push origin "$branch" 2>/dev/null; then
|
||||
log "Result committed and pushed for ${action_id} (attempt ${attempt})"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "Push conflict for ${action_id} (attempt ${attempt}/3) — rebasing"
|
||||
|
||||
if ! git -C "$scratch_dir" pull --rebase origin "$branch" 2>/dev/null; then
|
||||
# Rebase conflict — check if result was pushed by another process
|
||||
git -C "$scratch_dir" rebase --abort 2>/dev/null || true
|
||||
if git -C "$scratch_dir" fetch origin "$branch" 2>/dev/null && \
|
||||
git -C "$scratch_dir" show "origin/${branch}:${result_relpath}" >/dev/null 2>&1; then
|
||||
log "Result already exists upstream for ${action_id} (pushed by another process)"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
log "ERROR: Failed to push result for ${action_id} after 3 attempts"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Write result file for an action via git push to the ops repo.
|
||||
# Usage: write_result <action_id> <exit_code> <logs>
|
||||
write_result() {
|
||||
local action_id="$1"
|
||||
local exit_code="$2"
|
||||
local logs="$3"
|
||||
|
||||
commit_result_via_git "$action_id" "$exit_code" "$logs"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue