#!/bin/bash set -euo pipefail readonly LINE="==================================================" readonly SUBLINE="--------------------------------------------------" section() { printf '\n%s\n%s\n%s\n' "$LINE" "$1" "$SUBLINE" } info() { printf '[info] %s\n' "$1" } fail() { printf '[error] %s\n' "$1" >&2 exit 1 } require_env() { local name="$1" local value="$2" if [ -z "$value" ] || [ "$value" = "null" ]; then fail "$name 未設定" fi printf '%s=%s\n' "$name" "$value" } write_output() { printf 'version=%s\n' "$1" >> "$GITHUB_OUTPUT" } normalize_beta_flag() { local value="${1:-false}" if [ -z "$value" ] || [ "$value" = "null" ]; then printf '%s\n' "false" return fi printf '%s\n' "$value" } latest_stable_version() { local release_json="$1" if [ -z "$release_json" ] || [ "$release_json" = "null" ]; then printf '%s\n' "0.0.0" return fi printf '%s' "$release_json" | jq -r ' if type == "array" then [ .[] | select(.tag_name? and (.tag_name | test("-beta\\.") | not)) | .tag_name ][0] // "v0.0.0" else "v0.0.0" end | sub("^v"; "") ' } next_release_version() { local latest_version="$1" local major minor patch IFS='.' read -r major minor patch <<< "$latest_version" major="${major:-0}" minor="${minor:-0}" patch="${patch:-0}" patch=$((patch + 1)) if [ "$patch" -ge 10 ]; then patch=0 minor=$((minor + 1)) fi if [ "$minor" -ge 10 ]; then minor=0 major=$((major + 1)) fi printf '%s.%s.%s\n' "$major" "$minor" "$patch" } next_beta_number() { local release_json="$1" local version="$2" if [ -z "$release_json" ] || [ "$release_json" = "null" ]; then printf '%s\n' "1" return fi printf '%s' "$release_json" | jq -r --arg prefix "v${version}-beta." ' if type == "array" then [ .[] | select(.tag_name? and (.tag_name | startswith($prefix))) | .tag_name | ltrimstr($prefix) | try tonumber catch empty ] | if length > 0 then max else 0 end else 0 end ' | awk '{print $1 + 1}' } calculate_version() { local release_json="$1" local is_beta="$2" if [ -z "$release_json" ] || [ "$release_json" = "null" ]; then if [ "$is_beta" = "true" ]; then printf '%s\t%s\n' "0.0.0" "0.0.1-beta.1" else printf '%s\t%s\n' "0.0.0" "0.0.1" fi return fi printf '%s' "$release_json" | jq -r --arg is_beta "$is_beta" ' def stable_version: if type == "array" then [ .[] | select(.tag_name? and (.tag_name | test("-beta\\.") | not)) | .tag_name ][0] // "v0.0.0" else "v0.0.0" end | sub("^v"; ""); def next_release($latest): ($latest | split(".") | map(tonumber? // 0)) as $parts | ($parts[0] // 0) as $major | ($parts[1] // 0) as $minor | ($parts[2] // 0) as $patch | ($patch + 1) as $next_patch | if $next_patch >= 10 then if ($minor + 1) >= 10 then "\(($major + 1)).0.0" else "\($major).\($minor + 1).0" end else "\($major).\($minor).\($next_patch)" end; def beta_max($prefix): [ .[] | select(.tag_name? and (.tag_name | startswith($prefix))) | .tag_name | ltrimstr($prefix) | try tonumber catch empty ] | if length > 0 then max else 0 end; (stable_version) as $base | (next_release($base)) as $next | if $is_beta == "true" then $base + "\t" + ($next + "-beta." + ((beta_max("v" + $next + "-beta.") + 1) | tostring)) else $base + "\t" + $next end ' } main() { section "參數檢查" require_env "GITEA_SERVER_URL" "${GITEA_SERVER_URL:-}" require_env "GITEA_REPOSITORY" "${GITEA_REPOSITORY:-}" if [ -n "${RUNNER_TOKEN:-}" ] && [ "${RUNNER_TOKEN:-}" != "null" ]; then info "RUNNER_TOKEN=***" else info "RUNNER_TOKEN=未提供" fi IS_BETA="$(normalize_beta_flag "${IS_BETA:-false}")" info "IS_BETA=$IS_BETA" section "取得版本資料" RELEASE_URL="$GITEA_SERVER_URL/api/v1/repos/$GITEA_REPOSITORY/releases" info "RELEASE_URL=$RELEASE_URL" if [ -n "${RUNNER_TOKEN:-}" ] && [ "${RUNNER_TOKEN:-}" != "null" ]; then info "使用授權 token 取得 release" RELEASE_JSON="$(curl -fsS -H "Authorization: token $RUNNER_TOKEN" "$RELEASE_URL")" else info "使用匿名請求取得 release" RELEASE_JSON="$(curl -fsS "$RELEASE_URL")" fi VERSION_INFO="$(calculate_version "$RELEASE_JSON" "$IS_BETA")" IFS=$'\t' read -r LATEST_TAG NEW_VERSION <<< "$VERSION_INFO" info "LATEST_VERSION=$LATEST_TAG" section "計算版本號" info "NEW_VERSION=$NEW_VERSION" write_output "$NEW_VERSION" } if [ "${BASH_SOURCE[0]}" = "$0" ]; then main "$@" fi