feat(publish): rebuild releases nightly and let stable follow the tested one
CI / security-codeql (push) Blocked by required conditions
CI / test-unit (push) Blocked by required conditions
CI / test-integration (push) Blocked by required conditions
CI / test-env-virtual (push) Blocked by required conditions
CI / test-env-nix (push) Blocked by required conditions
CI / test-e2e (push) Blocked by required conditions
CI / test-virgin-user (push) Blocked by required conditions
CI / test-virgin-root (push) Blocked by required conditions
CI / lint-shell (push) Blocked by required conditions
CI / lint-python (push) Blocked by required conditions
CI / lint-docker (push) Blocked by required conditions
CodeQL Advanced / Check security (none, actions) (push) Blocked by required conditions
CodeQL Advanced / Check security (none, python) (push) Blocked by required conditions
Test Units / test-unit (push) Blocked by required conditions
Test Code Integration / test-integration (push) Blocked by required conditions
Test OS Containers / test-env-virtual (arch) (push) Blocked by required conditions
Test OS Containers / test-env-virtual (centos) (push) Blocked by required conditions
Test OS Containers / test-env-virtual (debian) (push) Blocked by required conditions
Test OS Containers / test-env-virtual (fedora) (push) Blocked by required conditions
Test OS Containers / test-env-virtual (ubuntu) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (arch) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (centos) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (debian) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (fedora) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (ubuntu) (push) Blocked by required conditions
Test End-To-End / test-e2e (arch) (push) Blocked by required conditions
Test End-To-End / test-e2e (centos) (push) Blocked by required conditions
Test End-To-End / test-e2e (debian) (push) Blocked by required conditions
Test End-To-End / test-e2e (fedora) (push) Blocked by required conditions
Test End-To-End / test-e2e (ubuntu) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (arch) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (centos) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (debian) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (fedora) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (ubuntu) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (arch) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (centos) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (debian) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (fedora) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (ubuntu) (push) Blocked by required conditions
ShellCheck / lint-shell (push) Blocked by required conditions
Ruff (Python code sniffer) / lint-python (push) Blocked by required conditions
Docker Linter / Lint Dockerfile (push) Blocked by required conditions
CI / security-codeql (push) Blocked by required conditions
CI / test-unit (push) Blocked by required conditions
CI / test-integration (push) Blocked by required conditions
CI / test-env-virtual (push) Blocked by required conditions
CI / test-env-nix (push) Blocked by required conditions
CI / test-e2e (push) Blocked by required conditions
CI / test-virgin-user (push) Blocked by required conditions
CI / test-virgin-root (push) Blocked by required conditions
CI / lint-shell (push) Blocked by required conditions
CI / lint-python (push) Blocked by required conditions
CI / lint-docker (push) Blocked by required conditions
CodeQL Advanced / Check security (none, actions) (push) Blocked by required conditions
CodeQL Advanced / Check security (none, python) (push) Blocked by required conditions
Test Units / test-unit (push) Blocked by required conditions
Test Code Integration / test-integration (push) Blocked by required conditions
Test OS Containers / test-env-virtual (arch) (push) Blocked by required conditions
Test OS Containers / test-env-virtual (centos) (push) Blocked by required conditions
Test OS Containers / test-env-virtual (debian) (push) Blocked by required conditions
Test OS Containers / test-env-virtual (fedora) (push) Blocked by required conditions
Test OS Containers / test-env-virtual (ubuntu) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (arch) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (centos) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (debian) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (fedora) (push) Blocked by required conditions
Test Virgin Nix (flake only) / test-env-nix (ubuntu) (push) Blocked by required conditions
Test End-To-End / test-e2e (arch) (push) Blocked by required conditions
Test End-To-End / test-e2e (centos) (push) Blocked by required conditions
Test End-To-End / test-e2e (debian) (push) Blocked by required conditions
Test End-To-End / test-e2e (fedora) (push) Blocked by required conditions
Test End-To-End / test-e2e (ubuntu) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (arch) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (centos) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (debian) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (fedora) (push) Blocked by required conditions
Test Virgin User / test-virgin-user (ubuntu) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (arch) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (centos) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (debian) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (fedora) (push) Blocked by required conditions
Test Virgin Root / test-virgin-root (ubuntu) (push) Blocked by required conditions
ShellCheck / lint-shell (push) Blocked by required conditions
Ruff (Python code sniffer) / lint-python (push) Blocked by required conditions
Docker Linter / Lint Dockerfile (push) Blocked by required conditions
Every image build now carries <version> and the immutable <version>.<unix-ts>; latest goes to the newest release on main, each prefix (2, 2.3) to the newest release starting with it, and stable to the release the git tag stable marks, which "Mark stable commit" sets only after all tests passed. publish-containers.yml runs daily at 03:00 UTC and on workflow_dispatch. A rebuild publishes the newest release and, when the git tag stable sits on an older one, that release too, so both get base-image security updates. compute-publish-container-info.sh emits the release list with each release's moving tags; image.sh takes them as --aliases instead of --stable. A platform build whose installed package set equals the published <version> pushes nothing, and a merge whose image index equals the published one only moves the tags not yet on it, without a new stamp. Only vX.Y.Z tags count as releases; v2.4.0-rc1 no longer moves 2 or 2.4. The build scripts come from the release commit: releases tagged before this change keep the old scripts until a newer release replaces them. tests/integration: 22 tests for release choice, aliases, the stable rebuild, the push skip and the triggers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
08738d812e
commit
c2f0a56699
10 files changed
+748
-130
No files matched your search
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
WORKFLOW_RUN_SHA="${WORKFLOW_RUN_SHA:?WORKFLOW_RUN_SHA must be set}"
|
||||
|
||||
git checkout -f "${WORKFLOW_RUN_SHA}"
|
||||
git fetch --tags --force
|
||||
git tag --list 'stable' 'v*' --sort=version:refname | tail -n 20
|
||||
@@ -1,23 +1,91 @@
|
||||
#!/usr/bin/env bash
|
||||
# Param: WORKFLOW_RUN_SHA commit the "Mark stable commit" run tagged; empty on a scheduled or
|
||||
# manual rebuild, which publishes the newest vX.Y.Z release on origin/main
|
||||
# and the release the git tag stable marks
|
||||
# Output: releases=<JSON list of {"sha", "version", "aliases"}> in GITHUB_OUTPUT; aliases are the
|
||||
# moving tags a release takes besides <version> and <version>.<unix-ts>
|
||||
set -euo pipefail
|
||||
|
||||
SHA="$(git rev-parse HEAD)"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
V_TAG="$(git tag --points-at "${SHA}" --list 'v*' | sort -V | tail -n1)"
|
||||
if [[ -z "${V_TAG}" ]]; then
|
||||
echo "No version tag found for ${SHA}. Skipping publish."
|
||||
echo "should_publish=false" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
# shellcheck source=scripts/build/base.sh
|
||||
source "${SCRIPT_DIR}/../../build/base.sh"
|
||||
|
||||
: "${WORKFLOW_RUN_SHA?WORKFLOW_RUN_SHA must be set, empty for a rebuild}"
|
||||
: "${GITHUB_OUTPUT:?GITHUB_OUTPUT must be set}"
|
||||
|
||||
RELEASE_TAG='^v[0-9]+\.[0-9]+\.[0-9]+$'
|
||||
|
||||
release_at() {
|
||||
local listed tag
|
||||
listed="$(git tag --points-at "$1" --sort=-v:refname)"
|
||||
tag="$(grep -m1 -E "${RELEASE_TAG}" <<< "${listed}" || true)"
|
||||
echo "${tag#v}"
|
||||
}
|
||||
|
||||
newest_of() {
|
||||
local prefix="$1" version
|
||||
for version in "${RELEASES[@]}"; do
|
||||
if [[ "${version}." == "${prefix}."* ]]; then
|
||||
echo "${version}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
aliases_of() {
|
||||
local version="$1" prefix
|
||||
local -a aliases=()
|
||||
if [[ "${version}" == "${RELEASES[0]}" ]]; then
|
||||
aliases+=(latest)
|
||||
fi
|
||||
while read -r prefix; do
|
||||
if [[ "${prefix}" != "${version}" && "$(newest_of "${prefix}")" == "${version}" ]]; then
|
||||
aliases+=("${prefix}")
|
||||
fi
|
||||
done < <(version_prefixes "${version}")
|
||||
if [[ "${version}" == "${STABLE}" ]]; then
|
||||
aliases+=(stable)
|
||||
fi
|
||||
echo "${aliases[*]}"
|
||||
}
|
||||
|
||||
listed="$(git tag --merged origin/main --sort=-v:refname)"
|
||||
mapfile -t tags < <(grep -E "${RELEASE_TAG}" <<< "${listed}")
|
||||
RELEASES=("${tags[@]#v}")
|
||||
|
||||
STABLE=""
|
||||
stable_sha="$(git rev-parse -q --verify 'refs/tags/stable^{commit}' || true)"
|
||||
if [[ -n "${stable_sha}" ]]; then
|
||||
STABLE="$(release_at "${stable_sha}")"
|
||||
fi
|
||||
|
||||
VERSION="${V_TAG#v}"
|
||||
targets=()
|
||||
if [[ -n "${WORKFLOW_RUN_SHA}" ]]; then
|
||||
version="$(release_at "${WORKFLOW_RUN_SHA}")"
|
||||
if ! git merge-base --is-ancestor "${WORKFLOW_RUN_SHA}" origin/main; then
|
||||
echo "${WORKFLOW_RUN_SHA} is not on origin/main. Skipping publish."
|
||||
elif [[ -z "${version}" ]]; then
|
||||
echo "No vX.Y.Z tag found for ${WORKFLOW_RUN_SHA}. Skipping publish."
|
||||
else
|
||||
targets+=("${version}")
|
||||
fi
|
||||
else
|
||||
((${#RELEASES[@]} > 0)) || { echo "No vX.Y.Z tag is reachable from origin/main." >&2; exit 1; }
|
||||
targets+=("${RELEASES[0]}")
|
||||
if [[ -z "${STABLE}" ]]; then
|
||||
echo "The git tag stable marks no vX.Y.Z release; the stable image stays where it is."
|
||||
elif [[ "${STABLE}" != "${RELEASES[0]}" ]]; then
|
||||
targets+=("${STABLE}")
|
||||
fi
|
||||
fi
|
||||
|
||||
STABLE_SHA="$(git rev-parse -q --verify 'refs/tags/stable^{commit}' 2>/dev/null || true)"
|
||||
IS_STABLE=false
|
||||
[[ -n "${STABLE_SHA}" && "${STABLE_SHA}" == "${SHA}" ]] && IS_STABLE=true
|
||||
json=""
|
||||
for version in "${targets[@]}"; do
|
||||
sha="$(git rev-parse "v${version}^{commit}")"
|
||||
moving="$(aliases_of "${version}")"
|
||||
echo "Publishing ${version} at ${sha}, moving: ${moving}"
|
||||
json+="${json:+,}{\"sha\":\"${sha}\",\"version\":\"${version}\",\"aliases\":\"${moving}\"}"
|
||||
done
|
||||
|
||||
{
|
||||
echo "should_publish=true"
|
||||
echo "version=${VERSION}"
|
||||
echo "is_stable=${IS_STABLE}"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
echo "releases=[${json}]" >> "${GITHUB_OUTPUT}"
|
||||
@@ -3,7 +3,7 @@ set -euo pipefail
|
||||
|
||||
: "${OWNER:?OWNER must be set}"
|
||||
: "${VERSION:?VERSION must be set}"
|
||||
: "${IS_STABLE:?IS_STABLE must be set}"
|
||||
: "${ALIASES?ALIASES must be set, empty for none}"
|
||||
: "${PKGMGR_DISTRO:?PKGMGR_DISTRO must be set}"
|
||||
|
||||
bash scripts/build/image.sh \
|
||||
@@ -11,5 +11,5 @@ bash scripts/build/image.sh \
|
||||
--registry ghcr.io \
|
||||
--owner "${OWNER}" \
|
||||
--version "${VERSION}" \
|
||||
--stable "${IS_STABLE}" \
|
||||
--aliases "${ALIASES}" \
|
||||
--merge
|
||||
Reference in new issue
Block a user