Skip to main content
Glama
tag_version.sh7.17 kB
#!/bin/bash # Script to create a git tag and update CHANGELOG.md # Usage: ./tag-version.sh <version> [--dry-run] set -e DRY_RUN=false # Parse arguments while [[ $# -gt 0 ]]; do case $1 in --dry-run) DRY_RUN=true shift ;; *) VERSION="$1" shift ;; esac done if [ -z "$VERSION" ]; then echo "Usage: $0 <version> [--dry-run]" echo "Example: $0 11.0.1" echo "Example: $0 11.0.1 --dry-run" exit 1 fi DATE=$(date +%Y-%m-%d) if [ "$DRY_RUN" = true ]; then echo "[DRY RUN MODE]" echo "" fi # Check if gh CLI is installed and configured if ! command -v gh &> /dev/null; then echo "Error: GitHub CLI (gh) is not installed" echo "Please install it: https://cli.github.com/" exit 1 fi if ! gh auth status &> /dev/null; then echo "Error: GitHub CLI is not authenticated" echo "Please run: gh auth login" exit 1 fi # Detect main branch (master or main) CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) if git rev-parse --verify master >/dev/null 2>&1; then MAIN_BRANCH="master" elif git rev-parse --verify main >/dev/null 2>&1; then MAIN_BRANCH="main" else echo "Error: Could not detect main branch (neither master nor main exists)" exit 1 fi # Check if we're on the main branch if [ "$CURRENT_BRANCH" != "$MAIN_BRANCH" ]; then echo "Error: You must be on the $MAIN_BRANCH branch to create a release" echo "Current branch: $CURRENT_BRANCH" exit 1 fi # Check if working copy is clean if ! git diff-index --quiet HEAD --; then echo "Error: Working copy is not clean. Please commit or stash your changes." git status --short exit 1 fi # Check if we're up to date with remote git fetch origin "$MAIN_BRANCH" --quiet LOCAL=$(git rev-parse @) REMOTE=$(git rev-parse @{u}) if [ "$LOCAL" != "$REMOTE" ]; then echo "Error: Your local $MAIN_BRANCH branch is not up to date with origin/$MAIN_BRANCH" echo "Please run: git pull origin $MAIN_BRANCH" exit 1 fi # Check if tag already exists if git rev-parse "v$VERSION" >/dev/null 2>&1; then echo "Error: Tag v$VERSION already exists" exit 1 fi # Get repository URL for PR links GIT_REMOTE=$(git remote get-url origin 2>/dev/null || echo "") if [[ "$GIT_REMOTE" =~ github.com[:/]([^/]+)/([^/.]+) ]]; then REPO_OWNER="${BASH_REMATCH[1]}" REPO_NAME="${BASH_REMATCH[2]}" REPO_URL="https://github.com/$REPO_OWNER/$REPO_NAME" else REPO_URL="" fi # Get the last tag LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") if [ -z "$LAST_TAG" ]; then echo "No previous tag found, getting all commits" COMMIT_RANGE="" else echo "Getting commits since $LAST_TAG" COMMIT_RANGE="$LAST_TAG..HEAD" fi # Get commit hashes if [ -z "$COMMIT_RANGE" ]; then COMMIT_HASHES=$(git log --pretty=format:"%H" --no-merges) else COMMIT_HASHES=$(git log "$COMMIT_RANGE" --pretty=format:"%H" --no-merges) fi # Check if there are commits if [ -z "$COMMIT_HASHES" ]; then echo "No new commits since last tag" exit 1 fi # Process commits: separate breaking changes and sort # Use a delimiter to separate commits (a string that won't appear in commit messages) COMMIT_DELIMITER="<<<COMMIT_SEPARATOR>>>" BREAKING_CHANGES_RAW="" REGULAR_COMMITS_RAW="" while IFS= read -r hash; do # Get subject and body subject=$(git log -1 --pretty=format:"%s" "$hash") body=$(git log -1 --pretty=format:"%b" "$hash") # Convert PR numbers to links if we have a repo URL if [ -n "$REPO_URL" ]; then subject=$(echo "$subject" | sed -E "s|#([0-9]+)|[#\1]($REPO_URL/pull/\1)|g") body=$(echo "$body" | sed -E "s|#([0-9]+)|[#\1]($REPO_URL/pull/\1)|g") fi # Check if it's a breaking change (contains ! before :) if [[ "$subject" =~ ^[a-z]+(\([^\)]+\))?\!: ]]; then # Make subject bold in markdown commit_entry="- **$subject**" # Add body if it exists, indented with two spaces for markdown if [ -n "$body" ]; then # Indent body lines with two spaces and preserve newlines indented_body=$(echo "$body" | sed 's/^/ /') commit_entry="${commit_entry}"$'\n'"${indented_body}" fi BREAKING_CHANGES_RAW="${BREAKING_CHANGES_RAW}${commit_entry}${COMMIT_DELIMITER}"$'\n' else REGULAR_COMMITS_RAW="${REGULAR_COMMITS_RAW}- ${subject}${COMMIT_DELIMITER}"$'\n' fi done <<< "$COMMIT_HASHES" # Sort breaking changes (sort by first line only, keep blocks together) BREAKING_CHANGES="" if [ -n "$BREAKING_CHANGES_RAW" ]; then BREAKING_CHANGES=$(echo "$BREAKING_CHANGES_RAW" | awk -v delim="$COMMIT_DELIMITER" ' BEGIN { RS=delim"\n"; ORS="" } NF { commits[NR] = $0; keys[NR] = $0; sub(/\n.*/, "", keys[NR]) } END { n = asort(keys, sorted_keys) for (i = 1; i <= n; i++) { for (j in keys) { if (keys[j] == sorted_keys[i]) { print commits[j] "\n" delete keys[j] break } } } } ') fi # Sort regular commits REGULAR_COMMITS="" if [ -n "$REGULAR_COMMITS_RAW" ]; then REGULAR_COMMITS=$(echo "$REGULAR_COMMITS_RAW" | sed "s/${COMMIT_DELIMITER}//g" | sort)$'\n' fi # Combine: breaking changes first, then regular commits SORTED_COMMITS="" if [ -n "$BREAKING_CHANGES" ]; then SORTED_COMMITS="$BREAKING_CHANGES" fi if [ -n "$REGULAR_COMMITS" ]; then SORTED_COMMITS="${SORTED_COMMITS}${REGULAR_COMMITS}" fi # Prepare the new changelog entry NEW_ENTRY="## $VERSION ($DATE) $SORTED_COMMITS " # Prepare release notes for GitHub RELEASE_NOTES="$SORTED_COMMITS" # Update CHANGELOG.md and version in pyproject.toml if [ "$DRY_RUN" = true ]; then echo "Would update CHANGELOG.md with:" echo "$NEW_ENTRY" echo "Would run: git add CHANGELOG.md" echo "Would run: git commit -m \"chore: release $VERSION (CHANGELOG)\"" echo "Would run: git tag -a \"v$VERSION\" -m \"Version $VERSION\"" echo "Would run: git push origin HEAD v$VERSION" echo "Would run: gh release create \"v$VERSION\" --title \"v$VERSION\" --notes <release notes>" exit 0 fi if [ -f "CHANGELOG.md" ]; then # Keep existing entries (skip the first line "# Changelog") EXISTING_ENTRIES=$(tail -n +2 CHANGELOG.md) echo "# Changelog $NEW_ENTRY$EXISTING_ENTRIES" > CHANGELOG.md else # Create new CHANGELOG.md echo "# Changelog $NEW_ENTRY" > CHANGELOG.md fi echo "CHANGELOG.md updated with commits from $LAST_TAG to HEAD" # Commit CHANGELOG update git add CHANGELOG.md git commit -m "chore: release $VERSION (CHANGELOG)" echo "✓ Committed pyproject.toml and CHANGELOG.md" # Create the git tag git tag -a "v$VERSION" -m "Version $VERSION" echo "✓ Created tag v$VERSION" # Push the commit and tag git push origin HEAD "v$VERSION" echo "✓ Pushed commit and tag v$VERSION to origin" # Create GitHub release echo "$RELEASE_NOTES" | gh release create "v$VERSION" \ --title "v$VERSION" \ --notes-file - echo "✓ Created GitHub release v$VERSION"

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bolinocroustibat/datagouv-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server