diff --git a/.github/workflows/release-docker.yml b/.github/workflows/release-docker.yml index 0426625..6b44a9a 100644 --- a/.github/workflows/release-docker.yml +++ b/.github/workflows/release-docker.yml @@ -5,18 +5,19 @@ on: tags: - "v*" branches: - - develop + - main workflow_dispatch: inputs: - bump: - description: "Version bump type (major stays fixed from latest release)" + release_type: + description: "Release type" required: false default: "patch" type: choice options: - - patch - - minor - major + - minor + - patch + - dev permissions: contents: write @@ -40,11 +41,33 @@ jobs: REPO: ${{ gitea.repository }} EVENT_NAME: ${{ gitea.event_name }} REF_NAME: ${{ gitea.ref_name }} - BUMP_TYPE: ${{ gitea.event.inputs.bump || 'patch' }} + RELEASE_TYPE: ${{ gitea.event.inputs.release_type || 'patch' }} RUN_NUMBER: ${{ gitea.run_number }} DOCKER_API_VERSION: '1.44' run: | - if [ "$EVENT_NAME" = "push" ] && [ "$REF_NAME" = "develop" ]; then + if [ "$EVENT_NAME" = "push" ] && [ "$REF_NAME" = "main" ]; then + prerelease=true + latest_tag="v0.8.31" + if meta_json=$(curl -fsSL -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/json" "https://git.invario-software.eu/api/v1/repos/$REPO/releases/latest" 2>/dev/null); then + tag_name=$(printf "%s" "$meta_json" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n1) + if [ -n "$tag_name" ]; then + latest_tag="$tag_name" + fi + fi + + if [[ "$latest_tag" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then + major=${BASH_REMATCH[1]} + minor=${BASH_REMATCH[2]} + patch=${BASH_REMATCH[3]} + else + major=0 + minor=8 + patch=31 + fi + + patch=$((patch + 1)) + TAG="v${major}.${minor}.${patch}-dev.${RUN_NUMBER:-0}" + elif [ "$EVENT_NAME" = "workflow_dispatch" ] && [ "$RELEASE_TYPE" = "dev" ]; then prerelease=true latest_tag="v0.8.31" if meta_json=$(curl -fsSL -H "Authorization: Bearer $GH_TOKEN" -H "Accept: application/json" "https://git.invario-software.eu/api/v1/repos/$REPO/releases/latest" 2>/dev/null); then @@ -87,9 +110,9 @@ jobs: major=0; minor=8; patch=31 fi - if [ "${BUMP_TYPE:-}" = "major" ]; then + if [ "${RELEASE_TYPE:-}" = "major" ]; then major=$((major + 1)); minor=0; patch=0 - elif [ "${BUMP_TYPE:-}" = "minor" ]; then + elif [ "${RELEASE_TYPE:-}" = "minor" ]; then minor=$((minor + 1)); patch=0 else patch=$((patch + 1)) diff --git a/update.sh b/update.sh index 970011e..52f23a7 100755 --- a/update.sh +++ b/update.sh @@ -223,6 +223,41 @@ print(data.get('tag_name', '').strip()) PY } +strip_prerelease_suffix() { + local tag="$1" + python3 - <<'PY' "$tag" +import re, sys +tag = sys.argv[1].strip() +match = re.match(r'^(v\d+\.\d+\.\d+)', tag) +print(match.group(1) if match else tag) +PY +} + +compare_semver_tags() { + local left_tag="$1" + local right_tag="$2" + python3 - <<'PY' "$left_tag" "$right_tag" +import re, sys + +def parse(tag): + match = re.match(r'^v(\d+)\.(\d+)\.(\d+)', tag.strip()) + if not match: + return None + return tuple(int(part) for part in match.groups()) + +left = parse(sys.argv[1]) +right = parse(sys.argv[2]) +if left is None or right is None: + print('unknown') +elif left > right: + print('gt') +elif left < right: + print('lt') +else: + print('eq') +PY +} + parse_prerelease_flag() { local meta_file="$1" python3 - <<'PY' "$meta_file" @@ -460,28 +495,58 @@ main() { # If user requested a development install, deploy the latest prerelease. if [ "$MODE" = "development" ]; then log_message "Requested development install" - local tag meta_file releases_file bundle_url app_image compose_path + local tag meta_file releases_file stable_meta_file stable_tag prerelease_tag prerelease_base_tag bundle_url app_image compose_path local tmp_dir tmp_dir="$(mktemp -d)" meta_file="$tmp_dir/prerelease.json" + stable_meta_file="$tmp_dir/stable.json" releases_file="$tmp_dir/releases.json" trap 'rm -rf "${tmp_dir:-}"' EXIT - if ! latest_prerelease "$meta_file" "$releases_file"; then - log_message "ERROR: Could not find a prerelease in Gitea" + if ! fetch_release_metadata "$stable_meta_file" "latest"; then + log_message "ERROR: Could not fetch latest stable release metadata" exit 1 fi - tag="$(parse_release_tag "$meta_file")" - if [ -z "$tag" ]; then - log_message "ERROR: Could not determine prerelease tag" + stable_tag="$(parse_release_tag "$stable_meta_file")" + if [ -z "$stable_tag" ]; then + log_message "ERROR: Could not determine latest stable release tag" exit 1 fi + if latest_prerelease "$meta_file" "$releases_file"; then + prerelease_tag="$(parse_release_tag "$meta_file")" + prerelease_base_tag="$(strip_prerelease_suffix "$prerelease_tag")" + else + prerelease_tag="" + prerelease_base_tag="" + fi + + if [ -n "$prerelease_tag" ]; then + case "$(compare_semver_tags "$stable_tag" "$prerelease_base_tag")" in + gt|eq) + log_message "Latest stable release ($stable_tag) supersedes prerelease ($prerelease_tag); using stable release" + tag="$stable_tag" + meta_file="$stable_meta_file" + ;; + lt) + tag="$prerelease_tag" + ;; + *) + log_message "WARNING: Could not compare stable and prerelease versions; preferring prerelease when available" + tag="$prerelease_tag" + ;; + esac + else + log_message "No prerelease found; falling back to stable release $stable_tag" + tag="$stable_tag" + meta_file="$stable_meta_file" + fi + bundle_url="$(fetch_latest_release_bundle "$meta_file")" if [ -z "$bundle_url" ]; then - log_message "ERROR: Prerelease asset not found: $BUNDLE_ASSET" + log_message "ERROR: Release asset not found: $BUNDLE_ASSET" exit 1 fi