diff --git a/.gitea/scripts/add-annotations.sh b/.gitea/scripts/add-annotations.sh index 6cd9855..dbe206c 100755 --- a/.gitea/scripts/add-annotations.sh +++ b/.gitea/scripts/add-annotations.sh @@ -1,92 +1,104 @@ #!/bin/bash -set -eo pipefail +# ============================================================================ +# Generate ArtifactHub changelog annotations from git commit history +# ============================================================================ -CHART_FILE="Chart.yaml" -if [ ! -f "${CHART_FILE}" ]; then - echo "ERROR: ${CHART_FILE} not found!" 1>&2 +set -euo pipefail + +readonly CHART_FILE="Chart.yaml" +readonly RC_PATTERN="\-rc([-\.][0-9]+)?$" + +CHANGE_LOG_YAML="" + +cleanup() { + if [[ -n "${CHANGE_LOG_YAML:-}" && -f "${CHANGE_LOG_YAML}" ]]; then + rm -f "${CHANGE_LOG_YAML}" + fi +} +trap cleanup EXIT + +if [[ ! -f "${CHART_FILE}" ]]; then + echo "ERROR: ${CHART_FILE} not found!" >&2 exit 1 fi -rc_pattern="\-rc([-\.][0-9]+)?$" - # Exclude prerelease tags (matching -rc or -rc.) from default tag selection -DEFAULT_NEW_TAG="$(git tag --sort=-version:refname | grep --invert-match --perl-regexp "${rc_pattern}" | head --lines 1)" -DEFAULT_OLD_TAG="$(git tag --sort=-version:refname | grep --invert-match --perl-regexp "${rc_pattern}" | head --lines 2 | tail --lines 1)" +DEFAULT_NEW_TAG="$(git tag --sort=-version:refname | grep --invert-match --perl-regexp "${RC_PATTERN}" | head --lines 1)" +DEFAULT_OLD_TAG="$(git tag --sort=-version:refname | grep --invert-match --perl-regexp "${RC_PATTERN}" | head --lines 2 | tail --lines 1)" -if [ -z "${1}" ]; then - read -p "Enter start tag [${DEFAULT_OLD_TAG}]: " OLD_TAG - if [ -z "${OLD_TAG}" ]; then +if [[ -z "${1:-}" ]]; then + read -rp "Enter start tag [${DEFAULT_OLD_TAG}]: " OLD_TAG + if [[ -z "${OLD_TAG}" ]]; then OLD_TAG="${DEFAULT_OLD_TAG}" fi - while [ -z "$(git tag --list "${OLD_TAG}")" ]; do - echo "ERROR: Tag '${OLD_TAG}' not found!" 1>&2 - read -p "Enter start tag [${DEFAULT_OLD_TAG}]: " OLD_TAG - if [ -z "${OLD_TAG}" ]; then + while [[ -z "$(git tag --list "${OLD_TAG}")" ]]; do + echo "ERROR: Tag '${OLD_TAG}' not found!" >&2 + read -rp "Enter start tag [${DEFAULT_OLD_TAG}]: " OLD_TAG + if [[ -z "${OLD_TAG}" ]]; then OLD_TAG="${DEFAULT_OLD_TAG}" fi done else - OLD_TAG=${1} - if [ -z "$(git tag --list "${OLD_TAG}")" ]; then - echo "ERROR: Tag '${OLD_TAG}' not found!" 1>&2 + OLD_TAG="${1}" + if [[ -z "$(git tag --list "${OLD_TAG}")" ]]; then + echo "ERROR: Tag '${OLD_TAG}' not found!" >&2 exit 1 fi fi -if [ -z "${2}" ]; then - read -p "Enter end tag [${DEFAULT_NEW_TAG}]: " NEW_TAG - if [ -z "${NEW_TAG}" ]; then +if [[ -z "${2:-}" ]]; then + read -rp "Enter end tag [${DEFAULT_NEW_TAG}]: " NEW_TAG + if [[ -z "${NEW_TAG}" ]]; then NEW_TAG="${DEFAULT_NEW_TAG}" fi - while [ -z "$(git tag --list "${NEW_TAG}")" ]; do - echo "ERROR: Tag '${NEW_TAG}' not found!" 1>&2 - read -p "Enter end tag [${DEFAULT_NEW_TAG}]: " NEW_TAG - if [ -z "${NEW_TAG}" ]; then + while [[ -z "$(git tag --list "${NEW_TAG}")" ]]; do + echo "ERROR: Tag '${NEW_TAG}' not found!" >&2 + read -rp "Enter end tag [${DEFAULT_NEW_TAG}]: " NEW_TAG + if [[ -z "${NEW_TAG}" ]]; then NEW_TAG="${DEFAULT_NEW_TAG}" fi done else - NEW_TAG=${2} + NEW_TAG="${2}" - if [ -z "$(git tag --list "${NEW_TAG}")" ]; then - echo "ERROR: Tag '${NEW_TAG}' not found!" 1>&2 + if [[ -z "$(git tag --list "${NEW_TAG}")" ]]; then + echo "ERROR: Tag '${NEW_TAG}' not found!" >&2 exit 1 fi fi -# Check if NEW_TAG is a prerelease (matches -rc or -rc- suffix) -if [[ "${NEW_TAG}" =~ ${rc_pattern} ]]; then +if [[ "${NEW_TAG}" =~ ${RC_PATTERN} ]]; then echo "INFO: Tag '${NEW_TAG}' is a prerelease, setting prerelease annotation and skipping changelog." yq --no-colors --inplace ".annotations.\"artifacthub.io/prerelease\" = \"true\" | sort_keys(.)" "${CHART_FILE}" exit 0 fi -CHANGE_LOG_YAML=$(mktemp) +CHANGE_LOG_YAML="$(mktemp)" echo "[]" > "${CHANGE_LOG_YAML}" -function map_type_to_kind() { +map_type_to_kind() { case "${1}" in feat) echo "added" - ;; + ;; fix) echo "fixed" - ;; + ;; chore|style|test|ci|docs|refac) echo "changed" - ;; + ;; revert) echo "removed" - ;; + ;; sec) echo "security" - ;; + ;; *) echo "skip" - ;; + ;; esac } @@ -97,9 +109,9 @@ echo "INFO: Generate change log entries from ${OLD_TAG} until ${NEW_TAG}" while IFS= read -r line; do if [[ "${line}" =~ ^([a-zA-Z]+)(\([^\)]+\))?\:\ (.+)$ ]]; then TYPE="${BASH_REMATCH[1]}" - KIND=$(map_type_to_kind "${TYPE}") + KIND="$(map_type_to_kind "${TYPE}")" - if [ "${KIND}" == "skip" ]; then + if [[ "${KIND}" == "skip" ]]; then continue fi @@ -109,16 +121,13 @@ while IFS= read -r line; do jq --arg kind "${KIND}" --arg description "${DESC}" '. += [ $ARGS.named ]' < "${CHANGE_LOG_YAML}" > "${CHANGE_LOG_YAML}.new" mv "${CHANGE_LOG_YAML}.new" "${CHANGE_LOG_YAML}" - fi done <<< "${COMMIT_TITLES}" -if [ -s "${CHANGE_LOG_YAML}" ]; then +if [[ -s "${CHANGE_LOG_YAML}" ]]; then yq --inplace --input-format json --output-format yml "${CHANGE_LOG_YAML}" yq --no-colors --inplace ".annotations.\"artifacthub.io/changes\" |= loadstr(\"${CHANGE_LOG_YAML}\") | sort_keys(.)" "${CHART_FILE}" else - echo "ERROR: Changelog file is empty: ${CHANGE_LOG_YAML}" 1>&2 + echo "ERROR: Changelog file is empty: ${CHANGE_LOG_YAML}" >&2 exit 1 fi - -rm "${CHANGE_LOG_YAML}"