Ctrl K
ComunidadGuías…

scripts/release_version.sh

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env bash

set -euo pipefail

# Application releases use YY.MM.N[-rc.K]; .agents/skills/release/SKILL.md says
# how N and K are chosen. Bare YY.MM is only an image tag that follows the newest
# stable of its month. Database migration sequences are separate.
parse_release_tag() {
  local tag="$1"
  if [[ ! "$tag" =~ ^([1-9][0-9]\.(0[1-9]|1[0-2]))\.(0|[1-9][0-9]*)(-rc\.([1-9][0-9]*))?$ ]]; then
    return 1
  fi
  RELEASE_VERSION="$tag"
  RELEASE_SERIES="${BASH_REMATCH[1]}"
  RELEASE_IS_PRERELEASE=false
  if [[ -n "${BASH_REMATCH[5]}" ]]; then
    RELEASE_IS_PRERELEASE=true
  fi
}

# development_version prints YY.MM.D-dev.<sha7> for HEAD from its committer date
# in UTC, matching internal/version. format-local honors TZ; plain format uses
# the commit's original zone.
development_version() {
  local repo="$1" head month day sha version
  head="$(TZ=UTC git -C "$repo" show -s --format='%cd %H' --date='format-local:%y.%m %d' HEAD)"
  read -r month day sha <<<"$head"
  version="$month.${day#0}"
  if ! parse_release_tag "$version"; then
    echo "Cannot derive a calendar version from HEAD" >&2
    return 1
  fi
  printf '%s-dev.%s\n' "$version" "${sha:0:7}"
}

# previous_release_tag prints the newest stable release tag that is an ancestor
# of HEAD, excluding tags on HEAD itself. Legacy v0.31.x tags count because
# v0.31.0 is the fixed upgrade baseline.
previous_release_tag() {
  local repo="$1" head_sha tag tag_sha
  head_sha="$(git -C "$repo" rev-parse HEAD)"
  # List calendar releases first: the legacy v prefix would otherwise sort ahead.
  while IFS= read -r tag; do
    if parse_release_tag "$tag"; then
      [[ "$RELEASE_IS_PRERELEASE" == false ]] || continue
    elif [[ ! "$tag" =~ ^v0\.31\.(0|[1-9][0-9]*)$ ]]; then
      continue
    fi
    tag_sha="$(git -C "$repo" rev-list -n 1 "$tag")"
    [[ "$tag_sha" != "$head_sha" ]] || continue
    if git -C "$repo" merge-base --is-ancestor "$tag" HEAD; then
      printf '%s\n' "$tag"
      return
    fi
  done < <(
    git -C "$repo" tag --list '[1-9][0-9].*' --sort=-version:refname
    git -C "$repo" tag --list 'v0.31.*' --sort=-version:refname
  )
  echo 'No supported previous release found' >&2
  return 1
}

previous_release_image() {
  local tag
  if ! tag="$(previous_release_tag "$1")"; then
    echo 'Pass --previous-image' >&2
    return 1
  fi
  printf 'neosmemo/memos:%s\n' "${tag#v}"
}

if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  case "${1:-}" in
    development-version)
      development_version "${2:-.}"
      exit
      ;;
    previous-tag)
      previous_release_tag "${2:?repository required}"
      exit
      ;;
    previous-image)
      previous_release_image "${2:?repository required}"
      exit
      ;;
  esac
  tag="${2:?release tag required}"
  if ! parse_release_tag "$tag"; then
    echo "Unsupported release tag format: $tag" >&2
    exit 1
  fi
  case "${1:-}" in
    version)
      printf 'tag=%s\nversion=%s\nseries=%s\nis_prerelease=%s\n' \
        "$tag" "$RELEASE_VERSION" "$RELEASE_SERIES" "$RELEASE_IS_PRERELEASE"
      ;;
    image-tags)
      printf '%s\n' "$RELEASE_VERSION"
      if [[ "$RELEASE_IS_PRERELEASE" == false ]]; then
        printf '%s\nstable\n' "$RELEASE_SERIES"
      fi
      ;;
    *) echo "Unknown release command: ${1:-}" >&2; exit 1 ;;
  esac
fi