Files
deepset-ai--haystack/.github/utils/parse_validate_version.sh
T
wehub-resource-sync c56bef871b
Sync docs with Docusaurus / sync (push) Waiting to run
Tests / Check if changed (push) Waiting to run
Tests / format (push) Blocked by required conditions
Tests / check-imports (push) Blocked by required conditions
Tests / Unit / macos-latest (push) Blocked by required conditions
Tests / Unit / ubuntu-latest (push) Blocked by required conditions
Tests / Unit / windows-latest (push) Blocked by required conditions
Tests / mypy (push) Blocked by required conditions
Tests / Integration / ubuntu-latest (push) Blocked by required conditions
Tests / Integration / macos-latest (push) Blocked by required conditions
Tests / Integration / windows-latest (push) Blocked by required conditions
Tests / notify-slack-on-failure (push) Blocked by required conditions
Tests / Mark tests as completed (push) Blocked by required conditions
Docker image release / Build base image (push) Waiting to run
CodeQL / Analyze (python) (push) Has been cancelled
Update Platform Components Table / update (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:22:28 +08:00

172 lines
5.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# parse_validate_version.sh - Parse and validate version for release
#
# Usage: ./parse_validate_version.sh <version>
# Output: Writes to $GITHUB_OUTPUT if set, otherwise to stdout
#
# Example:
# ./parse_validate_version.sh v2.99.0-rc1
#
# This script is used in the release.yml workflow to parse and validate the version to be released.
# Covers several checks to prevent accidental releases of incorrect versions.
set -euo pipefail
# --- Helpers ---
fail() {
echo ""
echo -e "❌ $1"
echo ""
exit 1
}
ok() {
echo "✅ $1"
}
tag_exists() {
git tag -l "$1" | grep -q "^$1$"
}
branch_exists() {
git ls-remote --heads origin "$1" | grep -q "$1"
}
# --- Parse and validate version ---
VERSION="${1#v}" # Strip 'v' prefix
echo ""
echo "️ Validating: ${1}"
echo ""
if [[ ! "${VERSION}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(-rc([0-9]+))?$ ]]; then
fail "Invalid version format: $1\n\n"\
"Expected format: vMAJOR.MINOR.PATCH or vMAJOR.MINOR.PATCH-rcN\n"\
"Examples: v2.99.0-rc1, v2.99.0, v2.99.1-rc1"
fi
ok "Version format is valid"
MAJOR="${BASH_REMATCH[1]}"
MINOR="${BASH_REMATCH[2]}"
PATCH="${BASH_REMATCH[3]}"
RC_NUM="${BASH_REMATCH[5]:-0}"
if [[ "${RC_NUM}" == "0" && "${VERSION}" == *"-rc0" ]]; then
fail "Cannot release rc0\n\n"\
"rc0 is an internal marker created automatically during branch-off.\n"\
"Release candidates start at rc1."
fi
MAJOR_MINOR="${MAJOR}.${MINOR}"
RELEASE_BRANCH="v${MAJOR_MINOR}.x"
TAG="v${VERSION}"
IS_RC="false"
[[ "${RC_NUM}" != "0" ]] && IS_RC="true"
IS_FIRST_RC="false"
if [[ "${PATCH}" == "0" && "${RC_NUM}" == "1" ]]; then
IS_FIRST_RC="true"
fi
# 1. Tag must not already exist
if tag_exists "${TAG}"; then
fail "Version ${TAG} was already released\n\n"\
"Each version can only be released once.\n"\
"To publish changes, release the next RC or patch version."
fi
ok "Tag ${TAG} does not exist"
# 2. Checks based on release type
if [[ "${IS_FIRST_RC}" == "true" ]]; then
# First RC of minor: branch must NOT exist yet
if branch_exists "${RELEASE_BRANCH}"; then
fail "Branch ${RELEASE_BRANCH} already exists\n\n"\
"The first RC of a minor (e.g., v${MAJOR_MINOR}.0-rc1) creates the release branch.\n"\
"Since the branch exists, this minor was likely already started.\n"\
"Did you mean to release the next RC (rc2, rc3...) or a patch (v${MAJOR_MINOR}.1-rc1)?"
fi
ok "Branch ${RELEASE_BRANCH} does not exist"
# First RC of minor: VERSION.txt must contain rc0
EXPECTED="${MAJOR_MINOR}.0-rc0"
ACTUAL=$(cat VERSION.txt)
if [[ "${ACTUAL}" != "${EXPECTED}" ]]; then
ACTUAL_MINOR=$(echo "${ACTUAL}" | cut -d. -f1,2)
fail "Cannot release v${MAJOR_MINOR}.0-rc1 from this branch\n\n"\
"The main branch is prepared for version ${ACTUAL_MINOR}, not ${MAJOR_MINOR}.\n"\
"Check that you're releasing the correct version."
fi
ok "VERSION.txt = ${EXPECTED}"
else
# Not first RC: branch MUST exist
if ! branch_exists "${RELEASE_BRANCH}"; then
if [[ "${PATCH}" == "0" ]]; then
fail "Branch ${RELEASE_BRANCH} does not exist\n\n"\
"For subsequent RCs (rc2, rc3...), the release branch must already exist.\n"\
"Release the first RC (v${MAJOR_MINOR}.0-rc1) first to create the branch."
else
fail "Branch ${RELEASE_BRANCH} does not exist\n\n"\
"For patch releases, the release branch must already exist.\n"\
"The minor version (v${MAJOR_MINOR}.0) must be released before any patches."
fi
fi
ok "Branch ${RELEASE_BRANCH} exists"
# Subsequent RC (rc2, rc3...): previous RC must exist
if [[ "${RC_NUM}" -gt 1 ]]; then
PREV_RC_NUM=$((RC_NUM - 1))
PREV_TAG="v${MAJOR_MINOR}.${PATCH}-rc${PREV_RC_NUM}"
if ! tag_exists "${PREV_TAG}"; then
fail "Cannot release v${MAJOR_MINOR}.${PATCH}-rc${RC_NUM}\n\n"\
"Previous RC (${PREV_TAG}) was not found.\n"\
"RC versions must be sequential. Release rc${PREV_RC_NUM} first."
fi
ok "Previous tag ${PREV_TAG} exists"
fi
# Final release: at least one RC must exist
if [[ "${RC_NUM}" == "0" ]]; then
RC_TAGS=$(git tag -l "v${MAJOR_MINOR}.${PATCH}-rc*" | grep -v "\-rc0$" || true)
if [[ -z "${RC_TAGS}" ]]; then
fail "Cannot release stable version v${MAJOR_MINOR}.${PATCH}\n\n"\
"No release candidate found for this version.\n"\
"Stable releases require at least one RC first (e.g., v${MAJOR_MINOR}.${PATCH}-rc1)."
fi
LAST_RC=$(echo "${RC_TAGS}" | sort -V | tail -n1)
ok "Found RC: ${LAST_RC}"
# Check Tests workflow passed (only if credentials available)
if [[ -n "${GH_TOKEN:-}" && -n "${GITHUB_REPOSITORY:-}" ]]; then
RC_SHA=$(git rev-list -n 1 "${LAST_RC}")
RESULT=$(gh api "/repos/${GITHUB_REPOSITORY}/actions/runs?head_sha=${RC_SHA}&status=success" \
--jq '.workflow_runs[] | select(.name == "Tests") | .conclusion' 2>/dev/null || true)
if [[ -z "${RESULT}" ]]; then
fail "Cannot release stable version v${MAJOR_MINOR}.${PATCH}\n\n"\
"Tests did not pass on the last RC (${LAST_RC}).\n"\
"Wait for tests to complete, or release a new RC with fixes."
fi
ok "Tests passed on ${LAST_RC}"
fi
fi
fi
echo ""
ok "All validations passed!"
echo ""
# --- Output to GITHUB_OUTPUT (or stdout for local testing) ---
OUTPUT_FILE="${GITHUB_OUTPUT:-/dev/stdout}"
{
echo "version=${VERSION}"
echo "major_minor=${MAJOR_MINOR}"
echo "release_branch=${RELEASE_BRANCH}"
echo "is_rc=${IS_RC}"
echo "is_first_rc=${IS_FIRST_RC}"
} >> "${OUTPUT_FILE}"