#!/usr/bin/env bash # Shared helpers for release and PR title CI scripts. SOURCE_DIR="python_repositories" # Returns bump type (major|minor|patch) or empty if no valid prefix. bump_type_from_title() { local title="$1" local lower lower=$(echo "$title" | tr '[:upper:]' '[:lower:]') if echo "$lower" | grep -qE '^\[(major|breaking)\]'; then echo "major" elif echo "$lower" | grep -qE '^\[(minor|feat)\]'; then echo "minor" elif echo "$lower" | grep -qE '^\[(patch|fix)\]'; then echo "patch" fi } title_has_bump_prefix() { [[ -n "$(bump_type_from_title "$1")" ]] } strip_bump_prefix() { local title="$1" echo "$title" | sed -E 's/^\[(patch|fix|minor|feat|major|breaking)\][[:space:]]*//i' } extract_pr_title_from_merge_commit() { local msg="$1" echo "$msg" | sed -n "s/^Merge pull request '\(.*\)' (#.*/\1/p" } changed_source_files() { grep -E "^${SOURCE_DIR}/" || true } has_source_changes() { local files="$1" echo "$files" | changed_source_files | grep -q . } read_pyproject_version() { sed -n 's/^version = "\(.*\)"/\1/p' pyproject.toml | head -1 } latest_tag_version() { local tag tag=$(git describe --tags --abbrev=0 2>/dev/null || true) if [[ -n "$tag" ]]; then echo "${tag#v}" else read_pyproject_version fi } set_pyproject_version() { local version="$1" sed -i.bak -E "s/^version = \".*\"/version = \"${version}\"/" pyproject.toml rm -f pyproject.toml.bak } # Returns markdown bullet list of commits between two refs (exclusive..inclusive). # Optional third argument limits entries when from_ref is empty (release notes only). commits_between() { local from_ref="$1" local to_ref="${2:-HEAD}" local limit="${3:-}" if [[ -z "$from_ref" ]]; then if [[ -n "$limit" ]]; then git log "${to_ref}" --pretty=format:'- %h %s' -"${limit}" 2>/dev/null || true else git log "${to_ref}" --pretty=format:'- %h %s' 2>/dev/null || true fi else git log "${from_ref}..${to_ref}" --pretty=format:'- %h %s' 2>/dev/null || true fi } commits_since() { commits_between "$1" HEAD } changelog_header() { cat <<'EOF' # Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] EOF } changelog_section() { local version="$1" local date="$2" local summary="$3" local commits="$4" cat <&2 return 1 ;; esac echo "${major}.${minor}.${patch}" }