forked from heavy-duty/rig
fix: release channel is tag-only; revert coolify Documentation=
Claude REQUEST_CHANGES on !114: the latest-release path must never fall through to refs/heads/<tag> (would install a branch while INSTALLED_FROM still names the release). release_tag_url is the single refs/tags URL on every forge; regression test drives the heads-only stub. Also restore coolify Documentation= to github.com — forge flip needs an @andres ruling, not a shipped default in this PR.
This commit is contained in:
parent
df075b9ecf
commit
1343cb9871
3 changed files with 42 additions and 6 deletions
|
|
@ -206,7 +206,7 @@ log "writing ${UNIT_DIR}/coolify-dump.service"
|
||||||
cat > "$UNIT_DIR/coolify-dump.service" <<UNIT
|
cat > "$UNIT_DIR/coolify-dump.service" <<UNIT
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Age-encrypted dump of the Coolify control-plane database
|
Description=Age-encrypted dump of the Coolify control-plane database
|
||||||
Documentation=https://forgejo.heavyduty.builders/heavy-duty/rig
|
Documentation=https://github.com/heavy-duty/rig
|
||||||
Requires=docker.service
|
Requires=docker.service
|
||||||
After=docker.service
|
After=docker.service
|
||||||
|
|
||||||
|
|
@ -231,7 +231,7 @@ log "writing ${UNIT_DIR}/coolify-dump.timer (${SCHEDULE})"
|
||||||
cat > "$UNIT_DIR/coolify-dump.timer" <<UNIT
|
cat > "$UNIT_DIR/coolify-dump.timer" <<UNIT
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Nightly Coolify control-plane dump
|
Description=Nightly Coolify control-plane dump
|
||||||
Documentation=https://forgejo.heavyduty.builders/heavy-duty/rig
|
Documentation=https://github.com/heavy-duty/rig
|
||||||
|
|
||||||
[Timer]
|
[Timer]
|
||||||
OnCalendar=${SCHEDULE}
|
OnCalendar=${SCHEDULE}
|
||||||
|
|
|
||||||
22
install.sh
22
install.sh
|
|
@ -130,6 +130,10 @@ resolve_latest_tag() {
|
||||||
# the same two paths and the same disambiguation: refs/tags first so a pin
|
# the same two paths and the same disambiguation: refs/tags first so a pin
|
||||||
# always outranks a same-named branch, then refs/heads for RIG_REF=main.
|
# always outranks a same-named branch, then refs/heads for RIG_REF=main.
|
||||||
# Host is the only forge-specific input — no second grammar (#111).
|
# Host is the only forge-specific input — no second grammar (#111).
|
||||||
|
#
|
||||||
|
# The RELEASE channel (RIG_REF unset) must NOT use this list: a missing tag
|
||||||
|
# archive must fail loudly, never fall through to a same-named branch and
|
||||||
|
# still report the resolved tag in INSTALLED_FROM. Use release_tag_url.
|
||||||
ref_candidate_urls() {
|
ref_candidate_urls() {
|
||||||
local host="${RIG_HOST:-https://github.com}"
|
local host="${RIG_HOST:-https://github.com}"
|
||||||
host="${host%/}"
|
host="${host%/}"
|
||||||
|
|
@ -137,6 +141,15 @@ ref_candidate_urls() {
|
||||||
printf '%s/%s/archive/refs/heads/%s.tar.gz\n' "$host" "$1" "$2"
|
printf '%s/%s/archive/refs/heads/%s.tar.gz\n' "$host" "$1" "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# release_tag_url <owner/repo> <tag> — the RELEASE channel is tag-only on
|
||||||
|
# every forge (#111 / #32). One URL, refs/tags only: if that archive is
|
||||||
|
# gone the install dies, it never quietly takes refs/heads/<tag>.
|
||||||
|
release_tag_url() {
|
||||||
|
local host="${RIG_HOST:-https://github.com}"
|
||||||
|
host="${host%/}"
|
||||||
|
printf '%s/%s/archive/refs/tags/%s.tar.gz\n' "$host" "$1" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
# install_script_url — the curl|bash entrypoint URL for this REPO on RIG_HOST.
|
# install_script_url — the curl|bash entrypoint URL for this REPO on RIG_HOST.
|
||||||
# GitHub serves raw files at raw.githubusercontent.com; Forgejo at
|
# GitHub serves raw files at raw.githubusercontent.com; Forgejo at
|
||||||
# /raw/branch/<ref>/<path>. The refusal hint and bin/rig usage() both print
|
# /raw/branch/<ref>/<path>. The refusal hint and bin/rig usage() both print
|
||||||
|
|
@ -261,9 +274,10 @@ else
|
||||||
die "set RIG_REF: e.g. curl -fsSL $(install_script_url) | RIG_REF=main bash"
|
die "set RIG_REF: e.g. curl -fsSL $(install_script_url) | RIG_REF=main bash"
|
||||||
fi
|
fi
|
||||||
log "latest release: $REF"
|
log "latest release: $REF"
|
||||||
# Same candidate grammar as an explicit pin: tags first so the pin wins,
|
# Tag-only: the channel resolved a RELEASE tag, so the download is that
|
||||||
# then heads — identical on every forge RIG_HOST names (#111).
|
# tag's archive and nothing else. Falling through to refs/heads would
|
||||||
mapfile -t urls < <(ref_candidate_urls "$REPO" "$REF")
|
# install a branch while INSTALLED_FROM still names the tag (#111 review).
|
||||||
|
mapfile -t urls < <(release_tag_url "$REPO" "$REF")
|
||||||
else
|
else
|
||||||
mapfile -t urls < <(ref_candidate_urls "$REPO" "$REF")
|
mapfile -t urls < <(ref_candidate_urls "$REPO" "$REF")
|
||||||
fi
|
fi
|
||||||
|
|
@ -279,7 +293,7 @@ else
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
[ -n "$got" ] \
|
[ -n "$got" ] \
|
||||||
|| die "failed to download $REPO@$REF — no candidate URL worked (host ${RIG_HOST:-https://github.com}; tried refs/tags then refs/heads)"
|
|| die "failed to download $REPO@$REF — no candidate URL worked (host ${RIG_HOST:-https://github.com}; tried ${urls[*]})"
|
||||||
|
|
||||||
log "extracting archive"
|
log "extracting archive"
|
||||||
tar -xzf "$TMPDIR/rig.tar.gz" -C "$TMPDIR" \
|
tar -xzf "$TMPDIR/rig.tar.gz" -C "$TMPDIR" \
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ FAKEHOME="$WORK/home"; mkdir -p "$FAKEHOME"
|
||||||
RL="$WORK/installer-fns.sh"
|
RL="$WORK/installer-fns.sh"
|
||||||
awk '/^resolve_latest_tag\(\) \{/,/^\}/' "$ROOT/install.sh" > "$RL"
|
awk '/^resolve_latest_tag\(\) \{/,/^\}/' "$ROOT/install.sh" > "$RL"
|
||||||
awk '/^ref_candidate_urls\(\) \{/,/^\}/' "$ROOT/install.sh" >> "$RL"
|
awk '/^ref_candidate_urls\(\) \{/,/^\}/' "$ROOT/install.sh" >> "$RL"
|
||||||
|
awk '/^release_tag_url\(\) \{/,/^\}/' "$ROOT/install.sh" >> "$RL"
|
||||||
awk '/^install_script_url\(\) \{/,/^\}/' "$ROOT/install.sh" >> "$RL"
|
awk '/^install_script_url\(\) \{/,/^\}/' "$ROOT/install.sh" >> "$RL"
|
||||||
check "installer fns extracted (guards the awk)" 0 "redirect_url" cat "$RL"
|
check "installer fns extracted (guards the awk)" 0 "redirect_url" cat "$RL"
|
||||||
|
|
||||||
|
|
@ -184,6 +185,27 @@ check "channel latest: the refusal says what is missing" 1 "no release" \
|
||||||
rinst "$H2" "$B2" CURL_STUB_REDIRECT=https://github.com/heavy-duty/rig/releases
|
rinst "$H2" "$B2" CURL_STUB_REDIRECT=https://github.com/heavy-duty/rig/releases
|
||||||
check "channel latest: the refusal installed NOTHING" 1 "" test -e "$H2"
|
check "channel latest: the refusal installed NOTHING" 1 "" test -e "$H2"
|
||||||
|
|
||||||
|
# Channel 1, regression — a resolved tag whose archive is gone must FAIL,
|
||||||
|
# never fall through to refs/heads/<tag> and still claim the release
|
||||||
|
# (claude REQUEST_CHANGES on !114: INSTALLED_FROM would name the tag for a
|
||||||
|
# branch tree). CURL_STUB_OK only matches heads — if the installer tries it,
|
||||||
|
# the install would succeed and this check would fail.
|
||||||
|
H2b="$WORK/h2b"; B2b="$WORK/b2b"; LOG2b="$WORK/log2b"
|
||||||
|
check "channel latest: missing tag archive does NOT fall through to heads" \
|
||||||
|
1 "no candidate URL worked" rinst "$H2b" "$B2b" \
|
||||||
|
CURL_STUB_REDIRECT=https://github.com/heavy-duty/rig/releases/tag/3.3.3 \
|
||||||
|
CURL_STUB_OK=refs/heads/3.3.3 CURL_STUB_LOG="$LOG2b"
|
||||||
|
check "channel latest: ...and installed NOTHING (branch was never taken)" 1 "" \
|
||||||
|
test -e "$H2b"
|
||||||
|
# The log also holds the releases/latest probe; the download tries are the
|
||||||
|
# archive URLs. Exactly one archive try, and it is refs/tags — never heads.
|
||||||
|
check "channel latest: ...exactly one archive URL was tried" 0 "1" \
|
||||||
|
grep -c '/archive/' "$LOG2b"
|
||||||
|
check "channel latest: ...that try was refs/tags" 0 "refs/tags/3.3.3" \
|
||||||
|
cat "$LOG2b"
|
||||||
|
check "channel latest: ...refs/heads was never consulted" 1 "" \
|
||||||
|
grep -q 'refs/heads/' "$LOG2b"
|
||||||
|
|
||||||
# Channel 2 — RIG_REF=<tag>: refs/tags wins, and the latest-release probe is
|
# Channel 2 — RIG_REF=<tag>: refs/tags wins, and the latest-release probe is
|
||||||
# never consulted (a pin resolves nothing).
|
# never consulted (a pin resolves nothing).
|
||||||
H3="$WORK/h3"; B3="$WORK/b3"; LOG3="$WORK/log3"
|
H3="$WORK/h3"; B3="$WORK/b3"; LOG3="$WORK/log3"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue