Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions .github/actions/prerelease-setup/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ The action performs, in order:
upgrade target (`standalone-vcluster-upgrade-version`,
`platform-rc-version`) resolves to the most recently published
pre-release whose final release has not shipped yet, excluding `-next`
internal builds. An empty base
internal builds and anything below the previous stable minor line. A
pre-release that old belongs to a line that was never finished, and once
every current line has gone GA those are all that is left: a manual run
once resolved `0.18.2-alpha.0` that way and died on a missing asset. When
nothing qualifies the step fails and asks for the version explicitly. An
empty base
(`standalone-vcluster-version`, `platform-base-version`) resolves to the
highest stable release strictly below its target, so a maintenance
release is tested against the release before it rather than against
Expand Down Expand Up @@ -51,14 +56,14 @@ provisioning (`aws-test-infra`) and the Ginkgo test execution

<!-- AUTO-DOC-INPUT:START - Do not remove or modify this section -->

| INPUT | TYPE | REQUIRED | DEFAULT | DESCRIPTION |
|-------------------------------------|--------|----------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| github-token | string | true | | GitHub token with contents:read on loft-sh/loft-enterprise. <br>Required because the platform release resolvers <br>call the GitHub API for a <br>private repo; unauthenticated calls return 404. <br>Pass the calling job's github.token from <br>a job whose permissions grant contents:read. |
| platform-base-version | string | false | | Platform version for the initial install <br>(e.g. 4.9.0). Empty resolves to the highest <br>stable release of loft-sh/loft-enterprise below the <br>RC target. |
| platform-rc-version | string | false | | Platform RC version for upgrade (e.g. 4.10.0-alpha.6). <br>Empty resolves to the most recently <br>published platform pre-release whose final release <br>has not shipped, excluding -next builds. |
| role-session-name | string | true | | AWS STS role-session-name. Each consumer job <br>passes a distinct value (e.g. prerelease-vcluster-<run-id>, prerelease-aicloud-<run-id>). |
| standalone-vcluster-upgrade-version | string | false | | vCluster version to upgrade standalone to <br>(e.g. 0.35.0-alpha.7). Empty resolves to the most <br>recently published vCluster pre-release whose final <br>release has not shipped, excluding -next <br>builds. Must differ from the resolved <br>base version. |
| standalone-vcluster-version | string | false | | vCluster version to install for standalone <br>(e.g. 0.34.0). Empty resolves to the highest <br>stable release of loft-sh/vcluster below the <br>upgrade target. |
| INPUT | TYPE | REQUIRED | DEFAULT | DESCRIPTION |
|-------------------------------------|--------|----------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| github-token | string | true | | GitHub token with contents:read on loft-sh/loft-enterprise. <br>Required because the platform release resolvers <br>call the GitHub API for a <br>private repo; unauthenticated calls return 404. <br>Pass the calling job's github.token from <br>a job whose permissions grant contents:read. |
| platform-base-version | string | false | | Platform version for the initial install <br>(e.g. 4.9.0). Empty resolves to the highest <br>stable release of loft-sh/loft-enterprise below the <br>RC target. |
| platform-rc-version | string | false | | Platform RC version for upgrade (e.g. 4.10.0-alpha.6). <br>Empty resolves to the most recently <br>published platform pre-release whose final release <br>has not shipped, excluding -next builds <br>and anything below the previous stable <br>minor line; fails when nothing qualifies. |
| role-session-name | string | true | | AWS STS role-session-name. Each consumer job <br>passes a distinct value (e.g. prerelease-vcluster-<run-id>, prerelease-aicloud-<run-id>). |
| standalone-vcluster-upgrade-version | string | false | | vCluster version to upgrade standalone to <br>(e.g. 0.35.0-alpha.7). Empty resolves to the most <br>recently published vCluster pre-release whose final <br>release has not shipped, excluding -next <br>builds and anything below the previous <br>stable minor line; fails when nothing <br>qualifies. Must differ from the resolved <br>base version. |
| standalone-vcluster-version | string | false | | vCluster version to install for standalone <br>(e.g. 0.34.0). Empty resolves to the highest <br>stable release of loft-sh/vcluster below the <br>upgrade target. |

<!-- AUTO-DOC-INPUT:END -->

Expand Down
4 changes: 2 additions & 2 deletions .github/actions/prerelease-setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ inputs:
required: false
default: ''
standalone-vcluster-upgrade-version:
description: 'vCluster version to upgrade standalone to (e.g. 0.35.0-alpha.7). Empty resolves to the most recently published vCluster pre-release whose final release has not shipped, excluding -next builds. Must differ from the resolved base version.'
description: 'vCluster version to upgrade standalone to (e.g. 0.35.0-alpha.7). Empty resolves to the most recently published vCluster pre-release whose final release has not shipped, excluding -next builds and anything below the previous stable minor line; fails when nothing qualifies. Must differ from the resolved base version.'
required: false
default: ''
platform-base-version:
description: 'Platform version for the initial install (e.g. 4.9.0). Empty resolves to the highest stable release of loft-sh/loft-enterprise below the RC target.'
required: false
default: ''
platform-rc-version:
description: 'Platform RC version for upgrade (e.g. 4.10.0-alpha.6). Empty resolves to the most recently published platform pre-release whose final release has not shipped, excluding -next builds.'
description: 'Platform RC version for upgrade (e.g. 4.10.0-alpha.6). Empty resolves to the most recently published platform pre-release whose final release has not shipped, excluding -next builds and anything below the previous stable minor line; fails when nothing qualifies.'
required: false
default: ''

Expand Down
18 changes: 13 additions & 5 deletions .github/actions/prerelease-setup/src/resolve-versions.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
# Resolves and validates the four version inputs for the pre-release checks.
# An empty upgrade target becomes the most recently published pre-release whose
# final release has not shipped yet; an empty base becomes the highest release
# below that target.
# final release has not shipped yet, on or above the previous stable minor line;
# an empty base becomes the highest release below that target.
#
# Needs GNU coreutils: `sort -V` must rank '~' below everything, which BSD and
# macOS sort do not. The runners are Ubuntu; `make test` on a Mac will disagree.
Expand Down Expand Up @@ -85,16 +85,24 @@ stable_tags() {
| sed 's/^v//' | { grep -E "$STABLE_RE" || true; }
}

line_of() { local v="${1%%-*}"; printf '%s' "${v%.*}"; }

previous_stable_line() {
stable_tags "$1" | while read -r v; do line_of "$v"; echo; done | sort -uV | tail -n2 | head -n1
}

# The most recently published pre-release whose final release is not out yet.
# /releases is not returned in any dependable order, so publish time is read
# from the payload and sorted here rather than trusting the first row.
newest_unreleased_pre_release() {
local repo="$1" released
local repo="$1" released floor
released="$(stable_tags "$repo")"
floor="$(previous_stable_line "$repo")"
local ranked first
ranked="$(pre_release_tags "$repo" | while IFS=$'\t' read -r published version; do
[ -n "$version" ] || continue
if grep -qxF "${version%%-*}" <<<"$released"; then continue; fi
if [ -n "$floor" ] && is_below "$(line_of "$version")" "$floor"; then continue; fi
printf '%s\t%s\t%s\n' "$published" "$(sort_key "$version")" "$version"
done | sort -t "$(printf '\t')" -k1,1r -k2,2Vr)"
[ -n "$ranked" ] || return 0
Expand All @@ -118,7 +126,7 @@ UP="${STANDALONE_VCLUSTER_UPGRADE_VERSION_INPUT:-}"
UP="${UP#v}"
if [ -z "$UP" ]; then
UP="$(newest_unreleased_pre_release vcluster)"
[ -n "$UP" ] || { echo "no vCluster pre-release found in loft-sh/vcluster"; exit 1; }
[ -n "$UP" ] || { echo "no unreleased vCluster pre-release on or above the $(previous_stable_line vcluster) line in loft-sh/vcluster; pass standalone-vcluster-upgrade-version explicitly"; exit 1; }
echo "Resolved newest unreleased vCluster pre-release: $UP"
fi
[[ "$UP" =~ $VERSION_RE ]] || { echo "invalid standalone-vcluster-upgrade-version: $UP"; exit 1; }
Expand All @@ -141,7 +149,7 @@ RC="${PLATFORM_RC_VERSION_INPUT:-}"
RC="${RC#v}"
if [ -z "$RC" ]; then
RC="$(newest_unreleased_pre_release loft-enterprise)"
[ -n "$RC" ] || { echo "no platform pre-release found in loft-sh/loft-enterprise"; exit 1; }
[ -n "$RC" ] || { echo "no unreleased platform pre-release on or above the $(previous_stable_line loft-enterprise) line in loft-sh/loft-enterprise; pass platform-rc-version explicitly"; exit 1; }
echo "Resolved newest unreleased platform pre-release: $RC"
fi
[[ "$RC" =~ $VERSION_RE ]] || { echo "invalid platform-rc-version: $RC"; exit 1; }
Expand Down
71 changes: 71 additions & 0 deletions .github/actions/prerelease-setup/test/resolve-versions.bats
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,74 @@ out() { grep "^$1=" "$GITHUB_OUTPUT" | cut -d= -f2-; }
[ "$status" -ne 0 ]
[[ "$output" == *"no stable vCluster release below 0.35.3-rc.1"* ]]
}

# --- abandoned pre-releases --------------------------------------------------

@test "a pre-release from a line that was never finished is not a target" {
# run 35222301790: every 0.37 pre-release had shipped, so the resolver fell
# through to a 2023 alpha whose line was abandoned before install-standalone.sh existed
set_releases vcluster 1 "[
$(release v0.37.1-rc.2 true 2026-09-10T10:00:00Z),
$(release v0.37.1 false 2026-09-15T10:00:00Z),
$(release v0.37.0 false 2026-09-01T10:00:00Z),
$(release v0.36.2 false 2026-08-20T10:00:00Z),
$(release v0.18.2-alpha.0 true 2023-12-28T13:30:54Z),
$(release v0.18.1 false 2023-12-01T10:00:00Z)
]"
run "$SCRIPT"
[ "$status" -ne 0 ]
[[ "$output" != *"0.18.2-alpha.0"* ]]
[[ "$output" == *"pass standalone-vcluster-upgrade-version explicitly"* ]]
}

@test "a maintenance pre-release on the previous line is still a target" {
set_releases vcluster 1 "[
$(release v0.36.4-rc.1 true 2026-10-10T10:00:00Z),
$(release v0.37.3 false 2026-10-05T10:00:00Z),
$(release v0.36.3 false 2026-09-20T10:00:00Z),
$(release v0.18.2-alpha.0 true 2023-12-28T13:30:54Z)
]"
run "$SCRIPT"
[ "$status" -eq 0 ]
[ "$(out standalone-vcluster-upgrade-version)" = "0.36.4-rc.1" ]
[ "$(out standalone-vcluster-version)" = "0.36.3" ]
}

@test "a patch pre-release on the current line is a target" {
set_releases vcluster 1 "[
$(release v0.37.4-rc.1 true 2026-10-16T13:11:47Z),
$(release v0.37.3 false 2026-10-05T10:00:00Z),
$(release v0.36.3 false 2026-09-20T10:00:00Z)
]"
run "$SCRIPT"
[ "$status" -eq 0 ]
[ "$(out standalone-vcluster-upgrade-version)" = "0.37.4-rc.1" ]
[ "$(out standalone-vcluster-version)" = "0.37.3" ]
}

@test "a pre-release of the next major is a target" {
export STANDALONE_VCLUSTER_UPGRADE_VERSION_INPUT="0.36.1-rc.3"
set_releases loft-enterprise 1 "[
$(release v5.0.0-alpha.1 true 2026-10-08T20:41:44Z),
$(release v4.12.3 false 2026-10-01T10:00:00Z),
$(release v4.11.3 false 2026-09-01T10:00:00Z),
$(release v2.3.1-alpha.0 true 2022-01-01T10:00:00Z)
]"
run "$SCRIPT"
[ "$status" -eq 0 ]
[ "$(out platform-rc-version)" = "5.0.0-alpha.1" ]
[ "$(out platform-base-version)" = "4.12.3" ]
}

@test "the platform target is rejected the same way" {
export STANDALONE_VCLUSTER_UPGRADE_VERSION_INPUT="0.36.1-rc.3"
set_releases loft-enterprise 1 "[
$(release v4.12.3 false 2026-10-01T10:00:00Z),
$(release v4.11.3 false 2026-09-01T10:00:00Z),
$(release v2.3.1-alpha.0 true 2022-01-01T10:00:00Z)
]"
run "$SCRIPT"
[ "$status" -ne 0 ]
[[ "$output" != *"2.3.1-alpha.0"* ]]
[[ "$output" == *"pass platform-rc-version explicitly"* ]]
}
Loading