fix(2): R014 normalize — repoint recipe origin to local bare with annotated tag (abra force-fetches tags before lint, reverting in-place re-annotation)

Diagnosed: abra runs git fetch --tags --force from origin before its pinned-deploy lint, so
re-annotating the lightweight tag in place is reverted before R014 runs. Fix: after re-annotating,
clone the recipe to a local bare repo (carrying the annotated tag) and repoint origin at it, so
abra's force-fetch pulls the annotated tag. Verified: abra recipe lint R014 then PASSES and the
annotation sticks. Deployed commit unchanged. No-op for all-annotated recipes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-29 13:59:03 +01:00
parent 8c19b1fadc
commit da44e2ca8a

View File

@ -84,13 +84,19 @@ def recipe_checkout(recipe: str, version: str) -> None:
def normalize_recipe_tags(recipe: str) -> int:
"""Convert any LIGHTWEIGHT recipe version tags to ANNOTATED in the local checkout, so abra's
pinned-deploy lint passes (R014 'only annotated tags used for recipe version'). Some upstream
coop-cloud recipes ship a stray lightweight tag (e.g. lasuite-meet's `0.3.0+v1.16.0`), which makes
`abra app deploy <pinned-version>` FATA on lint for the whole recipe — blocking the upgrade tier's
prev-version base deploy. This re-creates each lightweight tag as annotated pointing at the SAME
commit, so NO deployed content changes (only the tag object type). No-op for recipes whose tags are
already annotated (most). Returns the count re-annotated."""
"""Make abra's pinned-deploy lint pass (R014 'only annotated tags used for recipe version') when
an upstream coop-cloud recipe ships a stray LIGHTWEIGHT version tag (e.g. lasuite-meet's
`0.3.0+v1.16.0`). Such a tag FATAs `abra app deploy <pinned-version>` lint for the WHOLE recipe,
blocking the upgrade tier's prev-version base deploy.
Two-step, because abra force-fetches tags (`git fetch --tags --force`) from `origin` before it
lints — so re-annotating in place alone is reverted by abra. We therefore:
1. Re-create each lightweight tag as ANNOTATED at the SAME commit (no deployed content changes —
only the tag object type).
2. Snapshot the corrected recipe into a local bare repo and repoint `origin` at it, so abra's
pre-lint force-fetch pulls the *annotated* tag (verified: R014 then passes and the annotation
sticks). The deployed commit is identical; this only corrects tag hygiene abra insists on.
No-op for recipes whose tags are already annotated (most). Returns the count re-annotated."""
import os
path = os.path.expanduser(f"~/.abra/recipes/{recipe}")
@ -123,7 +129,20 @@ def normalize_recipe_tags(recipe: str) -> int:
)
fixed += 1
if fixed:
print(f" normalize_recipe_tags({recipe}): re-annotated {fixed} lightweight tag(s) for R014", flush=True)
# Repoint origin at a local bare snapshot carrying the annotated tags, so abra's pre-lint
# `git fetch --tags --force` (which otherwise reverts the in-place re-annotation to the
# upstream lightweight tag) pulls the corrected tags instead.
bare = os.path.expanduser(f"~/.abra/recipes/.{recipe}-ccci-fixed.git")
subprocess.run(["rm", "-rf", bare], check=False)
subprocess.run(["git", "clone", "--quiet", "--bare", path, bare], check=True)
subprocess.run(
["git", "-C", path, "remote", "set-url", "origin", f"file://{bare}"], check=True
)
print(
f" normalize_recipe_tags({recipe}): re-annotated {fixed} lightweight tag(s) + repointed "
f"origin → local bare (R014; abra force-fetch now preserves annotation)",
flush=True,
)
return fixed