diff --git a/automation/README.md b/automation/README.md index 9c19b0c..da8ef8d 100644 --- a/automation/README.md +++ b/automation/README.md @@ -160,6 +160,18 @@ cp automation/pr-review-watcher.config.example.json ~/pr-review-watcher/pr-revie - A Windows `.ps1` port is not provided yet (pms1 is the sole worker); port it from `claude-issue-watcher.ps1` only if you need a failover. +**Updating the deployed copy:** `update-pr-review-watcher.sh` refreshes the watcher +script in one command, from a dedicated self-update checkout (`~/pr-review-watcher/.src`) +that never races the issue watcher's clone. Copy it once, then: + +```sh +cp automation/update-pr-review-watcher.sh ~/pr-review-watcher/ # one-time +~/pr-review-watcher/update-pr-review-watcher.sh # pull from master +~/pr-review-watcher/update-pr-review-watcher.sh some/branch # or a branch (pre-merge testing) +``` + +It reads the live config for the token/URL, never clobbers the config, and self-updates. + ## Test database (for autofix verification) So the fix stage can verify against realistic data without touching production: diff --git a/automation/update-pr-review-watcher.sh b/automation/update-pr-review-watcher.sh new file mode 100644 index 0000000..99ac74e --- /dev/null +++ b/automation/update-pr-review-watcher.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# Refresh the deployed PR-review watcher from the repo, in one command. +# +# ~/pr-review-watcher/update-pr-review-watcher.sh # from master (default) +# ~/pr-review-watcher/update-pr-review-watcher.sh some/branch # from a branch (pre-merge testing) +# +# Pulls the latest script into a dedicated self-update checkout (~/pr-review-watcher/.src), +# separate from any work clone so it never races the issue watcher, then copies the +# watcher (and this updater) into place. NEVER touches the live config (real token). + +set -euo pipefail + +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONFIG="$HERE/pr-review-watcher.config.json" +[ -f "$CONFIG" ] || { echo "Config not found: $CONFIG (deploy the watcher first)"; exit 1; } +REF="${1:-master}" +SRC="$HERE/.src" + +cfg() { jq -r "$1" "$CONFIG"; } +URL=$(cfg .forgejoUrl); REPO=$(cfg .repo); TOKEN=$(cfg .token) +host=${URL#*://}; scheme=${URL%%://*}; owner=${REPO%%/*} +CLONE="${scheme}://${owner}:${TOKEN}@${host}/${REPO}.git" + +if [ ! -d "$SRC/.git" ]; then + echo "First run: cloning $REPO into $SRC" + git clone -q "$CLONE" "$SRC" +fi +git -C "$SRC" remote set-url origin "$CLONE" # keep the token fresh if it was rotated +git -C "$SRC" fetch origin -q --prune +# Prefer the remote-tracking ref; fall back to a literal ref (tag) if not a branch. +git -C "$SRC" checkout -f -q "origin/$REF" 2>/dev/null || git -C "$SRC" checkout -f -q "$REF" +git -C "$SRC" clean -fdq + +cp "$SRC/automation/claude-pr-review-watcher.sh" "$HERE/" +cp "$SRC/automation/update-pr-review-watcher.sh" "$HERE/" 2>/dev/null || true # self-update +# Seed the config from the example ONLY if missing -- never clobber the real token. +[ -f "$CONFIG" ] || cp "$SRC/automation/pr-review-watcher.config.example.json" "$CONFIG" + +echo "Updated from '$REF' ($(git -C "$SRC" rev-parse --short HEAD)). Watcher script is current." +echo "Dry-run: $HERE/claude-pr-review-watcher.sh $CONFIG"