Last active
July 25, 2025 20:49
-
-
Save valmat/cd64141685f2655c4a02d59902962ca3 to your computer and use it in GitHub Desktop.
Automatically creates a new tag and AI generated description for it
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/env bash | |
| set -e | |
| model="gpt-4.1"; | |
| temperature=0.8; | |
| endpoint_url="https://api.openai.com/v1/chat/completions" | |
| api_key="$OPENAI_API_KEY" | |
| # the hash of the commit that was marked with the last tag | |
| latest_tag_hash=$(git rev-list --tags --max-count=1) | |
| # the name of the last tag, using its hash | |
| latest_tag=$(git describe --tags --abbrev=0 $latest_tag_hash) | |
| minor_ver="${latest_tag##*.}" | |
| base_ver="${latest_tag%.*}" | |
| ((minor_ver+=1)) | |
| new_tag="${base_ver}.${minor_ver}" | |
| prompt="Below is the output of \`git log <latest_tag>..HEAD\`."` | |
| `"\nPlease provide a perfect tag ($new_tag) message."` | |
| `"\nUse emojis in the message text when appropriate. Use past tense."` | |
| `"\nProvide a message ready for direct substitution "` | |
| `"(don't use \`\`\` and provide multiline message)."` | |
| `" The message is intended for git, so format it as a plain text (not Markdown)." | |
| if ! [[ $# -eq 0 ]]; then | |
| prompt="${prompt}\n\nUse the following hint provided by the developer to generate the tag message: \`$1\`."` | |
| `"\nThe message language is strictly English." | |
| fi | |
| # Output the commit log from the previous tag to the HEAD (current state) | |
| # use the found name of the previous tag to start the story | |
| message=`git log $latest_tag..HEAD` | |
| echo "$latest_tag -> $new_tag" | |
| if [ -z "$message" ]; then | |
| echo "Nothing to commit, working tree clean" >&2 | |
| exit 1 | |
| fi | |
| echo "$message" > "/tmp/gitaitag-message.txt" | |
| json_payload=$(jq -n \ | |
| --arg model "$model" \ | |
| --arg temperature "$temperature" \ | |
| --arg prompt "$prompt" \ | |
| --rawfile message "/tmp/gitaitag-message.txt" \ | |
| '{ | |
| model: $model, | |
| temperature: ($temperature | tonumber), | |
| messages: [ | |
| { | |
| role: "system", | |
| content: $prompt | |
| },{ | |
| role: "user", | |
| content: $message | |
| } | |
| ] | |
| }') | |
| echo "$json_payload" > "/tmp/gitaitag-payload.txt" | |
| rm -f "/tmp/gitaitag-message.txt" | |
| response=$(curl -s "$endpoint_url" \ | |
| -H "Content-Type: application/json" \ | |
| -H "Authorization: Bearer $api_key" \ | |
| --data-binary "@/tmp/gitaitag-payload.txt") | |
| # Clean up the temporary file | |
| rm "/tmp/gitaitag-payload.txt" | |
| # Checking if the "error" key is in the response | |
| if echo "$response" | jq -e '.error' > /dev/null; then | |
| echo "Error: $(echo "$response" | jq -r '.error.message')" >&2 | |
| exit 2 | |
| else | |
| # If there is no error, trying to extract the desired message | |
| content=$(echo "$response" | jq -e -r '.choices[0].message.content') | |
| # Checking if the message was extracted | |
| if ! [[ $? -eq 0 ]]; then | |
| # If the message could not be extracted, | |
| # output the original text of the response to stderr | |
| echo "Failed to extract the message. Response was:" >&2 | |
| echo "$response" >&2 | |
| exit 3 | |
| fi | |
| fi | |
| description_file=$(mktemp) | |
| echo "$content" > "$description_file" | |
| nano "$description_file" | |
| git tag -a "$new_tag" -F "$description_file" | |
| cat "$description_file" | |
| rm "$description_file" |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
gitaitag: AI-powered Git Tag Message Generatorgitaitagis a bash script for Linux and MacOS that helps you create clear, expressive, and professional git tag messages using an OpenAI-compatible API.It automatically suggests the next tag version, summarizes all changes since the last tag, and generates a tag description complete with appropriate emojis and an English, developer-friendly style.
No more struggling over "release notes" or tag comments—let the AI do the heavy lifting!
Features
Requirements
jq(for JSON parsing)curl(for API calls)nano(or modify in the script for your favorite editor)$OPENAI_API_KEYin your environmentInstallation
Install dependencies:
Download the script:
Copy the script from the GitHub Gist or use direct download:
Add to your
$PATH:Ensure
~/binis in your PATH (add this to~/.bashrc,~/.zshrc, etc.):Restart your terminal or
sourceyour shell config file.Set your OpenAI API key:
Usage
Go to your git project directory:
cd /path/to/your/repoRun the script:
nanoby default) for optional edits(Optional) Provide a hint for the AI:
gitaitag "Major refactor and new API integration"Notes
nanoin the script.Example