# Auto-PR canonical wrapper updates to consumer repos when wrappers/ changes on # main. Maintenance automation (not artifact publishing), so it is allowed on a # main push under the D7 trigger standard. Requires BOT_TOKEN: the gitea-bot # org token (content+PR write to the consumer repos; never committed). # # Consumer drift checks run only after their sync PRs merge to main. They must # not run on the sync PR itself, which can create recursive cross-repo checks. name: sync-wrappers on: push: branches: [main] paths: - 'wrappers/crucible.sh' - 'wrappers/crucible.ps1' permissions: read-all jobs: sync: runs-on: nix-docker timeout-minutes: 30 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Open sync PRs to consumers env: TOKEN: ${{ secrets.BOT_TOKEN }} SERVER: ${{ github.server_url }} SRC_SHA: ${{ github.sha }} run: | nix develop --command bash -c ' set -euo pipefail [ -n "${TOKEN}" ] || { echo "::error::BOT_TOKEN secret is empty — set the gitea-bot org token"; exit 1; } host="$(echo "$SERVER" | sed -E "s#https?://##")" branch="chore/sync-wrappers-$(echo "$SRC_SHA" | cut -c1-12)" grep -vE "^\s*#|^\s*$" wrappers/consumers.txt | while read -r target; do echo "== syncing $target ==" work="$(mktemp -d)" git clone "https://oauth2:${TOKEN}@${host}/${target}.git" "$work" cp wrappers/crucible.sh wrappers/crucible.ps1 "$work"/ ( cd "$work" git config user.name "crucible-sync-bot" git config user.email "bot@westgate.pw" if git diff --quiet; then echo "no changes for $target"; exit 0; fi git checkout -b "$branch" git add crucible.sh crucible.ps1 git commit -m "chore: sync crucible wrappers from sow-tools@${SRC_SHA}" git push -f origin "$branch" # Capture HTTP status: 201=created, 422=PR already open for this # branch (fine, the force-push above refreshed it). Anything else # (401/404/...) is a real failure — fail loud, do not swallow it. resp="$(mktemp)" code="$(curl -sS -o "$resp" -w "%{http_code}" -X POST \ -H "Authorization: token ${TOKEN}" -H "Content-Type: application/json" \ "${SERVER}/api/v1/repos/${target}/pulls" \ -d "{\"head\":\"${branch}\",\"base\":\"main\",\"title\":\"chore: sync crucible wrappers from sow-tools\"}")" case "$code" in 201) echo "opened sync PR for $target" ;; 422) echo "sync PR already open for $target; refreshed its branch" ;; *) echo "::error::PR create failed for $target (HTTP $code)"; cat "$resp"; exit 1 ;; esac ) rm -rf "$work" done '