Files
pikasTech-HWLAB/scripts/src/gitops-render/templates/git-mirror-flush.sh
T

77 lines
3.2 KiB
Bash

#!/bin/sh
set -eu
repo_url="ssh://git@ssh.github.com:443/pikasTech/HWLAB.git"
repo_path="/cache/pikasTech/HWLAB.git"
lock_dir="/cache/.hwlab-flush.lock"
started_ms=$(node -e 'console.log(Date.now())')
now_ms() { node -e 'console.log(Date.now())'; }
emit_timing() {
phase="$1"
status="$2"
started="$3"
finished=$(now_ms)
duration=$((finished - started))
printf '{"event":"git-mirror-flush-timing","phase":"%s","status":"%s","durationMs":%s,"repository":"pikasTech/HWLAB"}
' "$phase" "$status" "$duration"
}
if ! mkdir "$lock_dir" 2>/dev/null; then
echo "git mirror flush already running"
exit 0
fi
trap 'rmdir "$lock_dir" 2>/dev/null || true' EXIT INT TERM
mkdir -p /root/.ssh
cp /git-ssh/ssh-privatekey /root/.ssh/id_rsa
chmod 0400 /root/.ssh/id_rsa
# __HWLAB_GIT_MIRROR_SSH_PRELUDE__
/script/install-hooks.sh
for gitops_branch in __HWLAB_GITOPS_BRANCH_ARGS__; do
local_head=$(git -C "$repo_path" show-ref --verify --hash "refs/heads/$gitops_branch" 2>/dev/null || true)
if [ -z "$local_head" ]; then
echo "git mirror flush skips missing local refs/heads/$gitops_branch"
continue
fi
fetch_started=$(now_ms)
timeout 90 git -C "$repo_path" fetch --quiet "$repo_url" "refs/heads/$gitops_branch:refs/mirror-stage/heads/$gitops_branch"
emit_timing "fetch-$gitops_branch" succeeded "$fetch_started"
github_head=$(git -C "$repo_path" show-ref --verify --hash "refs/mirror-stage/heads/$gitops_branch" 2>/dev/null || true)
if [ -n "$github_head" ] && [ "$github_head" != "$local_head" ] && ! git -C "$repo_path" merge-base --is-ancestor "$github_head" "$local_head"; then
echo "git mirror flush rejected divergent $gitops_branch local=$local_head github=$github_head" >&2
exit 52
fi
if [ "$local_head" != "$github_head" ]; then
push_started=$(now_ms)
timeout 120 git -C "$repo_path" push "$repo_url" "$local_head:refs/heads/$gitops_branch"
emit_timing "push-$gitops_branch" succeeded "$push_started"
else
echo "git mirror flush $gitops_branch already matches GitHub"
fi
git -C "$repo_path" update-ref "refs/mirror-stage/heads/$gitops_branch" "$local_head"
done
git -C "$repo_path" update-server-info
flushed_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)
export flushed_at
export gitops_branches_json=__HWLAB_GITOPS_BRANCHES_JSON_SHELL__
node - <<'NODE' | tee /cache/HWLAB.last-flush.json
const { execFileSync } = require("node:child_process");
const repo = "/cache/pikasTech/HWLAB.git";
const gitopsBranches = JSON.parse(process.env.gitops_branches_json || "[]");
function rev(ref) {
try { return execFileSync("git", ["-C", repo, "rev-parse", ref], { encoding: "utf8" }).trim() || null; } catch { return null; }
}
const refs = {};
for (const branch of gitopsBranches) {
refs["refs/heads/" + branch] = rev("refs/heads/" + branch);
refs["refs/mirror-stage/heads/" + branch] = rev("refs/mirror-stage/heads/" + branch);
}
const pendingFlush = gitopsBranches.some((branch) => refs["refs/heads/" + branch] && refs["refs/mirror-stage/heads/" + branch] && refs["refs/heads/" + branch] !== refs["refs/mirror-stage/heads/" + branch]);
console.log(JSON.stringify({
event: "git-mirror-flush",
status: "flushed",
repository: "pikasTech/HWLAB",
flushedAt: process.env.flushed_at,
pendingFlush,
refs
}));
NODE
emit_timing total succeeded "$started_ms"