fix(recipe-upgrade): reconcile mirror from TRUE coopcloud upstream, not from the mirror itself
The reconcile that's supposed to make the mirror main == upstream main was fetching origin/main — but origin is the cc-ci MIRROR, so it synced the mirror to itself (a no-op) and never pulled real upstream. Fix: fetch coopcloud explicitly (git.coopcloud.tech/coop-cloud/<recipe>, default branch main OR master) via an 'upstream' remote and force-sync the mirror main + tags from it. Every recipe has a coopcloud correspondent; none are forked. Also reorder the skill so the reconcile runs BEFORE the upgrade check, so the check sees the real current recipe. Verified by divergence test (diverged a mirror, reconcile snapped it back to coopcloud HEAD). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -51,31 +51,37 @@ test** to make a PR green.
|
||||
> 2. **Dirty worktree** is usually just the untracked cc-ci overlay (`compose.ccci.yml`) — don't skip on
|
||||
> that. `git stash -u` before the checks and `stash pop` after.
|
||||
|
||||
On cc-ci, refresh the recipe and see what's available (creds + stash first; each abra call pty-wrapped):
|
||||
```
|
||||
ssh cc-ci 'export PATH=/run/current-system/sw/bin:$PATH; R=<recipe>; \
|
||||
url=$(git -C ~/.abra/recipes/$R config --get remote.origin.url); \
|
||||
case "$url" in https://git.autonomic.zone/*) \
|
||||
git -C ~/.abra/recipes/$R remote set-url origin "https://'"$GITEA_USERNAME"':'"$GITEA_PASSWORD"'@${url#https://}";; esac; \
|
||||
git -C ~/.abra/recipes/$R stash -u >/dev/null 2>&1 || true; \
|
||||
script -qec "abra recipe fetch $R --force -n" /dev/null; \
|
||||
git -C ~/.abra/recipes/$R fetch origin main; \
|
||||
script -qec "abra recipe versions $R -m -n" /dev/null; \
|
||||
script -qec "abra recipe upgrade $R -m -n" /dev/null; \
|
||||
git -C ~/.abra/recipes/$R stash pop >/dev/null 2>&1 || true'
|
||||
```
|
||||
- Skip a recipe as `SKIPPED — dirty-worktree` **only if it is still dirty with TRACKED changes after the
|
||||
stash** (real local edits), not for the untracked overlay.
|
||||
- **Reconcile the mirror first (always, even if up to date).** Run:
|
||||
**Sync the mirror from TRUE upstream FIRST, then check for upgrades against that** — so the check sees
|
||||
the real current recipe, not a stale mirror.
|
||||
|
||||
- **(a) Reconcile the mirror from coopcloud (always — do this BEFORE the check).** Run:
|
||||
```
|
||||
set -a; . /srv/cc-ci/.testenv; set +a
|
||||
ssh cc-ci "GITEA_USERNAME='$GITEA_USERNAME' GITEA_PASSWORD='$GITEA_PASSWORD' GITEA_URL='$GITEA_URL' bash -s <recipe> --reconcile-only" \
|
||||
< /srv/cc-ci/.claude/skills/recipe-upgrade/open-recipe-pr.sh
|
||||
```
|
||||
This force-syncs the `recipe-maintainers/<recipe>` mirror `main` to be **identical to true upstream
|
||||
main**, and **closes any open mirror PR whose changes are already in upstream main** (merged
|
||||
upstream — the mirror just never reflected it). Do this before the up-to-date check so a stale
|
||||
already-merged PR gets cleaned up even when there's nothing new to upgrade.
|
||||
This fetches **true upstream from coopcloud** (`git.coopcloud.tech/coop-cloud/<recipe>`, default branch
|
||||
main OR master — every recipe has a coopcloud correspondent and none are forked) and force-syncs the
|
||||
`recipe-maintainers/<recipe>` mirror's `main` + tags to be **identical to it**. (The checkout's
|
||||
`origin` is the mirror, so the reconcile fetches coopcloud *explicitly* via an `upstream` remote — it
|
||||
does NOT sync the mirror to itself.) It also **closes any open mirror PR already in upstream main**.
|
||||
|
||||
- **(b) Refresh the local checkout + check for upgrades** (creds + stash per the box; each abra call
|
||||
pty-wrapped) — the checkout pulls from the now-coopcloud-synced mirror:
|
||||
```
|
||||
ssh cc-ci 'export PATH=/run/current-system/sw/bin:$PATH; R=<recipe>; \
|
||||
url=$(git -C ~/.abra/recipes/$R config --get remote.origin.url); \
|
||||
case "$url" in https://git.autonomic.zone/*) \
|
||||
git -C ~/.abra/recipes/$R remote set-url origin "https://'"$GITEA_USERNAME"':'"$GITEA_PASSWORD"'@${url#https://}";; esac; \
|
||||
git -C ~/.abra/recipes/$R stash -u >/dev/null 2>&1 || true; \
|
||||
script -qec "abra recipe fetch $R --force -n" /dev/null; \
|
||||
git -C ~/.abra/recipes/$R fetch origin main; \
|
||||
script -qec "abra recipe versions $R -m -n" /dev/null; \
|
||||
script -qec "abra recipe upgrade $R -m -n" /dev/null; \
|
||||
git -C ~/.abra/recipes/$R stash pop >/dev/null 2>&1 || true'
|
||||
```
|
||||
Skip a recipe as `SKIPPED — dirty-worktree` **only if it is still dirty with TRACKED changes after the
|
||||
stash** (real local edits), not for the untracked overlay.
|
||||
- **No upgrades available → stop** (status `SKIPPED — up-to-date`) — after the reconcile above.
|
||||
- Check `git log HEAD..origin/main` and upstream PRs (`git.coopcloud.tech/coop-cloud/<recipe>/pulls`)
|
||||
— if someone already started the bump, **re-plan from the tip of `origin/main`**, not from scratch.
|
||||
|
||||
@ -11,9 +11,10 @@
|
||||
# < /srv/cc-ci/.claude/skills/recipe-upgrade/open-recipe-pr.sh
|
||||
#
|
||||
# Always (both modes):
|
||||
# - Force-syncs the mirror's `main` to be IDENTICAL to true upstream `main`
|
||||
# (origin/main of the abra checkout = git.coopcloud.tech). This guarantees
|
||||
# every open PR is measured against the real current upstream.
|
||||
# - Force-syncs the mirror's `main` to be IDENTICAL to true upstream `main`, fetched EXPLICITLY from
|
||||
# coopcloud (`git.coopcloud.tech/coop-cloud/<recipe>`, default branch main OR master) via an
|
||||
# `upstream` remote — NOT from the checkout's `origin`, which is the mirror itself. This guarantees
|
||||
# the mirror really mirrors upstream and every open PR is measured against the real current upstream.
|
||||
# - Closes any open mirror PR whose changes are ALREADY IN upstream main
|
||||
# (i.e. merging it is a no-op) — it was merged upstream; the mirror just
|
||||
# never reflected it.
|
||||
@ -49,11 +50,24 @@ AUTH=(-u "${GITEA_USERNAME}:${GITEA_PASSWORD}")
|
||||
[ -d "${RECIPE_DIR}/.git" ] || { echo "ERROR: ${RECIPE_DIR} is not a git repo (run 'abra recipe fetch ${RECIPE}')"; exit 1; }
|
||||
cd "${RECIPE_DIR}"
|
||||
|
||||
# --- The true current upstream main ---
|
||||
echo "→ Fetching upstream main..."
|
||||
git fetch --quiet origin main
|
||||
NEW_MAIN_SHA=$(git rev-parse refs/remotes/origin/main)
|
||||
# --- The true current upstream main = COOPCLOUD ---
|
||||
# Every recipe has a coop-cloud correspondent and NONE are intentionally forked, so upstream is always
|
||||
# git.coopcloud.tech/coop-cloud/<recipe>. NOTE: the abra checkout's `origin` is the cc-ci MIRROR
|
||||
# (recipe-maintainers/<recipe>), so we must fetch coopcloud EXPLICITLY via an `upstream` remote — using
|
||||
# `origin` here would sync the mirror to itself (a no-op) and never pick up real upstream changes.
|
||||
# coopcloud is public, so no creds are needed for this fetch.
|
||||
UPSTREAM_URL="${UPSTREAM_URL:-https://git.coopcloud.tech/coop-cloud/${RECIPE}.git}"
|
||||
echo "→ Fetching true upstream ${UPSTREAM_URL} ..."
|
||||
git remote | grep -qx upstream && git remote set-url upstream "${UPSTREAM_URL}" || git remote add upstream "${UPSTREAM_URL}"
|
||||
git fetch --quiet --prune --tags upstream 2>/dev/null || {
|
||||
echo "ERROR: cannot fetch coopcloud upstream for ${RECIPE} (${UPSTREAM_URL}). Every recipe must have a coop-cloud correspondent — fix the URL/mirror."; exit 1; }
|
||||
# coopcloud's default branch (main OR master) is what the mirror's `main` must mirror exactly.
|
||||
UP_REF=$(git ls-remote --symref upstream HEAD 2>/dev/null | sed -n 's#^ref:[[:space:]]*refs/heads/\([^[:space:]]*\).*#upstream/\1#p' | head -1)
|
||||
[ -n "${UP_REF}" ] || for b in main master; do git rev-parse --verify -q "upstream/$b" >/dev/null 2>&1 && { UP_REF="upstream/$b"; break; }; done
|
||||
[ -n "${UP_REF}" ] || { echo "ERROR: no default branch found on coopcloud ${RECIPE}"; exit 1; }
|
||||
NEW_MAIN_SHA=$(git rev-parse "${UP_REF}")
|
||||
MAIN_TREE=$(git rev-parse "${NEW_MAIN_SHA}^{tree}")
|
||||
echo " upstream ${UP_REF} = ${NEW_MAIN_SHA:0:8}"
|
||||
|
||||
# --- Ensure the mirror repo exists ---
|
||||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "${AUTH[@]}" "${API}/repos/${NAMESPACE}/${RECIPE}")
|
||||
@ -77,9 +91,10 @@ fi
|
||||
REMOTE_URL="https://${GITEA_USERNAME}:${PASS_ENC}@${GITEA_URL}/${NAMESPACE}/${RECIPE}.git"
|
||||
git remote | grep -qx gitea && git remote set-url gitea "${REMOTE_URL}" || git remote add gitea "${REMOTE_URL}"
|
||||
|
||||
# --- Mirror main := true upstream main (identical) ---
|
||||
# --- Mirror main := true upstream main (identical); mirror also gets upstream's published tags ---
|
||||
echo "→ Force-syncing gitea/main to upstream main (${NEW_MAIN_SHA:0:8})..."
|
||||
git push --force gitea "${NEW_MAIN_SHA}:refs/heads/main"
|
||||
git push --quiet gitea "refs/tags/*:refs/tags/*" 2>/dev/null || true # coopcloud published versions
|
||||
git fetch --quiet gitea '+refs/heads/*:refs/remotes/gitea/*' || true
|
||||
|
||||
# --- Preconditions for open mode ---
|
||||
|
||||
Reference in New Issue
Block a user