mirror of
https://github.com/DeBrosOfficial/network.git
synced 2025-12-12 22:38:50 +00:00
feat: add script to automate changelog updates
- Introduced a new script `update_changelog.sh` that automates the process of generating and updating the changelog based on git diffs. - The script checks for necessary dependencies, validates the current git state, and interacts with the OpenRouter API to generate changelog entries. - It updates the version in the Makefile and inserts the new changelog entry into `CHANGELOG.md` while ensuring proper formatting and error handling.
This commit is contained in:
parent
30d18aca02
commit
69fd6e32f1
288
scripts/update_changelog.sh
Executable file
288
scripts/update_changelog.sh
Executable file
@ -0,0 +1,288 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
NOCOLOR='\033[0m'
|
||||
|
||||
log() { echo -e "${CYAN}[update-changelog]${NOCOLOR} $1"; }
|
||||
error() { echo -e "${RED}[ERROR]${NOCOLOR} $1"; }
|
||||
success() { echo -e "${GREEN}[SUCCESS]${NOCOLOR} $1"; }
|
||||
warning() { echo -e "${YELLOW}[WARNING]${NOCOLOR} $1"; }
|
||||
|
||||
# OpenRouter API key
|
||||
OPENROUTER_API_KEY="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"
|
||||
|
||||
# File paths
|
||||
CHANGELOG_FILE="CHANGELOG.md"
|
||||
MAKEFILE="Makefile"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
# Check dependencies
|
||||
if ! command -v jq > /dev/null 2>&1; then
|
||||
error "jq is required but not installed. Install it with: brew install jq (macOS) or apt-get install jq (Linux)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v curl > /dev/null 2>&1; then
|
||||
error "curl is required but not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if we're in a git repo
|
||||
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
||||
error "Not in a git repository"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get current branch
|
||||
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
REMOTE_BRANCH="origin/$CURRENT_BRANCH"
|
||||
|
||||
# Check if remote branch exists
|
||||
if ! git rev-parse --verify "$REMOTE_BRANCH" > /dev/null 2>&1; then
|
||||
warning "Remote branch $REMOTE_BRANCH does not exist. Using main/master as baseline."
|
||||
if git rev-parse --verify "origin/main" > /dev/null 2>&1; then
|
||||
REMOTE_BRANCH="origin/main"
|
||||
elif git rev-parse --verify "origin/master" > /dev/null 2>&1; then
|
||||
REMOTE_BRANCH="origin/master"
|
||||
else
|
||||
warning "No remote branch found. Using HEAD as baseline."
|
||||
REMOTE_BRANCH="HEAD"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Gather all git diffs
|
||||
log "Collecting git diffs..."
|
||||
|
||||
# Unstaged changes
|
||||
UNSTAGED_DIFF=$(git diff 2>/dev/null || echo "")
|
||||
|
||||
# Staged changes
|
||||
STAGED_DIFF=$(git diff --cached 2>/dev/null || echo "")
|
||||
|
||||
# Unpushed commits
|
||||
UNPUSHED_DIFF=$(git diff "$REMOTE_BRANCH"..HEAD 2>/dev/null || echo "")
|
||||
|
||||
# Combine all diffs
|
||||
ALL_DIFFS="${UNSTAGED_DIFF}
|
||||
---
|
||||
STAGED CHANGES:
|
||||
---
|
||||
${STAGED_DIFF}
|
||||
---
|
||||
UNPUSHED COMMITS:
|
||||
---
|
||||
${UNPUSHED_DIFF}"
|
||||
|
||||
# Check if there are any changes
|
||||
if [ -z "$(echo "$UNSTAGED_DIFF$STAGED_DIFF$UNPUSHED_DIFF" | tr -d '[:space:]')" ]; then
|
||||
log "No changes detected (unstaged, staged, or unpushed). Skipping changelog update."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get current version from Makefile
|
||||
CURRENT_VERSION=$(grep "^VERSION :=" "$MAKEFILE" | sed 's/.*:= *//' | tr -d ' ')
|
||||
|
||||
if [ -z "$CURRENT_VERSION" ]; then
|
||||
error "Could not find VERSION in Makefile"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Current version: $CURRENT_VERSION"
|
||||
|
||||
# Prepare prompt for OpenRouter
|
||||
PROMPT="You are analyzing git diffs to create a changelog entry. Based on the following git diffs, create a simple, easy-to-understand changelog entry.
|
||||
|
||||
Current version: $CURRENT_VERSION
|
||||
|
||||
Git diffs:
|
||||
\`\`\`
|
||||
$ALL_DIFFS
|
||||
\`\`\`
|
||||
|
||||
Please respond with ONLY a valid JSON object in this exact format:
|
||||
{
|
||||
\"version\": \"x.y.z\",
|
||||
\"bump_type\": \"minor\" or \"patch\",
|
||||
\"date\": \"YYYY-MM-DD\",
|
||||
\"added\": [\"item1\", \"item2\"],
|
||||
\"changed\": [\"item1\", \"item2\"],
|
||||
\"fixed\": [\"item1\", \"item2\"]
|
||||
}
|
||||
|
||||
Rules:
|
||||
- Bump version based on changes: use \"minor\" for new features, \"patch\" for bug fixes and small changes
|
||||
- Never bump major version (keep major version the same)
|
||||
- Keep descriptions simple and easy to understand (1-2 sentences max per item)
|
||||
- Only include items that actually changed
|
||||
- If a category is empty, use an empty array []
|
||||
- Date should be today's date in YYYY-MM-DD format"
|
||||
|
||||
# Call OpenRouter API
|
||||
log "Calling OpenRouter API to generate changelog..."
|
||||
|
||||
set +e # Temporarily disable exit on error to check curl response
|
||||
RESPONSE=$(curl -s -X POST "https://openrouter.ai/api/v1/chat/completions" \
|
||||
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"model\": \"google/gemini-2.5-flash-preview-09-2025\",
|
||||
\"messages\": [
|
||||
{
|
||||
\"role\": \"user\",
|
||||
\"content\": $(echo "$PROMPT" | jq -Rs .)
|
||||
}
|
||||
],
|
||||
\"temperature\": 0.3
|
||||
}")
|
||||
CURL_EXIT_CODE=$?
|
||||
set -e # Re-enable exit on error
|
||||
|
||||
# Check if API call succeeded
|
||||
if [ $CURL_EXIT_CODE -ne 0 ] || [ -z "$RESPONSE" ]; then
|
||||
error "Failed to call OpenRouter API"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for API errors in response
|
||||
if echo "$RESPONSE" | jq -e '.error' > /dev/null 2>&1; then
|
||||
error "OpenRouter API error:"
|
||||
echo "$RESPONSE" | jq -r '.error.message // .error'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract JSON from response
|
||||
JSON_CONTENT=$(echo "$RESPONSE" | jq -r '.choices[0].message.content' 2>/dev/null)
|
||||
|
||||
# Check if content was extracted
|
||||
if [ -z "$JSON_CONTENT" ] || [ "$JSON_CONTENT" = "null" ]; then
|
||||
error "Failed to extract content from API response"
|
||||
echo "Response: $RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Try to extract JSON if it's wrapped in markdown code blocks
|
||||
if echo "$JSON_CONTENT" | grep -q '```json'; then
|
||||
JSON_CONTENT=$(echo "$JSON_CONTENT" | sed -n '/```json/,/```/p' | sed '1d;$d')
|
||||
elif echo "$JSON_CONTENT" | grep -q '```'; then
|
||||
JSON_CONTENT=$(echo "$JSON_CONTENT" | sed -n '/```/,/```/p' | sed '1d;$d')
|
||||
fi
|
||||
|
||||
# Validate JSON
|
||||
if ! echo "$JSON_CONTENT" | jq . > /dev/null 2>&1; then
|
||||
error "Invalid JSON response from API:"
|
||||
echo "$JSON_CONTENT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Parse JSON
|
||||
NEW_VERSION=$(echo "$JSON_CONTENT" | jq -r '.version')
|
||||
BUMP_TYPE=$(echo "$JSON_CONTENT" | jq -r '.bump_type')
|
||||
DATE=$(echo "$JSON_CONTENT" | jq -r '.date')
|
||||
ADDED=$(echo "$JSON_CONTENT" | jq -r '.added[]?' | sed 's/^/- /')
|
||||
CHANGED=$(echo "$JSON_CONTENT" | jq -r '.changed[]?' | sed 's/^/- /')
|
||||
FIXED=$(echo "$JSON_CONTENT" | jq -r '.fixed[]?' | sed 's/^/- /')
|
||||
|
||||
log "Generated version: $NEW_VERSION ($BUMP_TYPE bump)"
|
||||
log "Date: $DATE"
|
||||
|
||||
# Validate version format
|
||||
if ! echo "$NEW_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
||||
error "Invalid version format: $NEW_VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate date format
|
||||
if ! echo "$DATE" | grep -qE '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'; then
|
||||
error "Invalid date format: $DATE (expected YYYY-MM-DD)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate bump type
|
||||
if [ "$BUMP_TYPE" != "minor" ] && [ "$BUMP_TYPE" != "patch" ]; then
|
||||
error "Invalid bump type: $BUMP_TYPE (must be 'minor' or 'patch')"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update Makefile
|
||||
log "Updating Makefile..."
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# macOS sed requires backup extension
|
||||
sed -i '' "s/^VERSION := .*/VERSION := $NEW_VERSION/" "$MAKEFILE"
|
||||
else
|
||||
# Linux sed
|
||||
sed -i "s/^VERSION := .*/VERSION := $NEW_VERSION/" "$MAKEFILE"
|
||||
fi
|
||||
success "Makefile updated to version $NEW_VERSION"
|
||||
|
||||
# Update CHANGELOG.md
|
||||
log "Updating CHANGELOG.md..."
|
||||
|
||||
# Create changelog entry
|
||||
CHANGELOG_ENTRY="## [$NEW_VERSION] - $DATE
|
||||
|
||||
### Added
|
||||
"
|
||||
if [ -n "$ADDED" ]; then
|
||||
CHANGELOG_ENTRY+="$ADDED"$'\n'
|
||||
else
|
||||
CHANGELOG_ENTRY+="\n"
|
||||
fi
|
||||
|
||||
CHANGELOG_ENTRY+="
|
||||
### Changed
|
||||
"
|
||||
if [ -n "$CHANGED" ]; then
|
||||
CHANGELOG_ENTRY+="$CHANGED"$'\n'
|
||||
else
|
||||
CHANGELOG_ENTRY+="\n"
|
||||
fi
|
||||
|
||||
CHANGELOG_ENTRY+="
|
||||
### Deprecated
|
||||
|
||||
### Removed
|
||||
|
||||
### Fixed
|
||||
"
|
||||
if [ -n "$FIXED" ]; then
|
||||
CHANGELOG_ENTRY+="$FIXED"$'\n'
|
||||
else
|
||||
CHANGELOG_ENTRY+="\n"
|
||||
fi
|
||||
|
||||
CHANGELOG_ENTRY+="
|
||||
"
|
||||
|
||||
# Insert after [Unreleased] section using awk (more portable)
|
||||
# Find the line number after [Unreleased] section (after the "### Fixed" line)
|
||||
INSERT_LINE=$(awk '/^## \[Unreleased\]/{found=1} found && /^### Fixed$/{print NR+1; exit}' "$CHANGELOG_FILE")
|
||||
|
||||
if [ -z "$INSERT_LINE" ]; then
|
||||
# Fallback: insert after line 16 (after [Unreleased] section)
|
||||
INSERT_LINE=16
|
||||
fi
|
||||
|
||||
# Use a temp file approach to insert multiline content
|
||||
TMP_FILE=$(mktemp)
|
||||
{
|
||||
head -n $((INSERT_LINE - 1)) "$CHANGELOG_FILE"
|
||||
printf '%s' "$CHANGELOG_ENTRY"
|
||||
tail -n +$INSERT_LINE "$CHANGELOG_FILE"
|
||||
} > "$TMP_FILE"
|
||||
mv "$TMP_FILE" "$CHANGELOG_FILE"
|
||||
|
||||
success "CHANGELOG.md updated with version $NEW_VERSION"
|
||||
|
||||
log "Changelog update complete!"
|
||||
log "New version: $NEW_VERSION"
|
||||
log "Bump type: $BUMP_TYPE"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user