#!/bin/bash # Script to generate release notes for InfluxDB v3.x releases # Usage: ./generate-release-notes.sh [--no-fetch] [--pull] [additional_repo_paths...] # # Options: # --no-fetch Skip fetching latest commits from remote # --pull Pull latest changes (implies fetch) - use with caution as it may change your working directory # # Example: ./generate-release-notes.sh v3.1.0 v3.2.0 /path/to/influxdb /path/to/influxdb_pro /path/to/influxdb_iox # Example: ./generate-release-notes.sh --no-fetch v3.1.0 v3.2.0 /path/to/influxdb # Example: ./generate-release-notes.sh --pull v3.1.0 v3.2.0 /path/to/influxdb /path/to/influxdb_pro set -e # Parse command line options FETCH_COMMITS=true PULL_COMMITS=false while [[ $# -gt 0 ]]; do case $1 in --no-fetch) FETCH_COMMITS=false shift ;; --pull) PULL_COMMITS=true FETCH_COMMITS=true shift ;; -*) echo "Unknown option $1" exit 1 ;; *) break ;; esac done # Parse remaining arguments FROM_VERSION="${1:-v3.1.0}" TO_VERSION="${2:-v3.2.0}" PRIMARY_REPO="${3:-/Users/ja/Documents/github/influxdb}" # Collect additional repositories (all arguments after the third) ADDITIONAL_REPOS=() shift 3 2>/dev/null || true while [ $# -gt 0 ]; do ADDITIONAL_REPOS+=("$1") shift done # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color echo -e "${BLUE}Generating release notes for ${TO_VERSION}${NC}" echo -e "Primary Repository: ${PRIMARY_REPO}" if [ ${#ADDITIONAL_REPOS[@]} -gt 0 ]; then echo -e "Additional Repositories:" for repo in "${ADDITIONAL_REPOS[@]}"; do echo -e " - ${repo}" done fi echo -e "From: ${FROM_VERSION} To: ${TO_VERSION}\n" # Function to extract PR number from commit message extract_pr_number() { echo "$1" | grep -oE '#[0-9]+' | head -1 | sed 's/#//' } # Function to get commits from a repository get_commits_from_repo() { local repo_path="$1" local pattern="$2" local format="${3:-%h %s}" if [ -d "$repo_path" ]; then git -C "$repo_path" log --format="$format" "${FROM_VERSION}..${TO_VERSION}" 2>/dev/null | grep -E "$pattern" || true fi } # Function to analyze API-related commits analyze_api_changes() { local repo_path="$1" local repo_name="$2" if [ ! -d "$repo_path" ]; then return fi # Look for API-related file changes local api_files=$(git -C "$repo_path" diff --name-only "${FROM_VERSION}..${TO_VERSION}" 2>/dev/null | grep -E "(api|handler|endpoint|route)" | head -10 || true) # Look for specific API endpoint patterns in commit messages and diffs local api_commits=$(git -C "$repo_path" log --format="%h %s" "${FROM_VERSION}..${TO_VERSION}" 2>/dev/null | \ grep -iE "(api|endpoint|/write|/query|/ping|/health|/metrics|v1|v2|v3)" || true) if [ -n "$api_files" ] || [ -n "$api_commits" ]; then echo " Repository: $repo_name" if [ -n "$api_files" ]; then echo " Modified API files:" echo "$api_files" | while read -r file; do echo " - $file" done fi if [ -n "$api_commits" ]; then echo " API-related commits:" echo "$api_commits" | while read -r commit; do echo " - $commit" done fi echo fi } # Get the release date RELEASE_DATE=$(git -C "$PRIMARY_REPO" log -1 --format=%ai "$TO_VERSION" | cut -d' ' -f1) echo -e "${GREEN}Release Date: ${RELEASE_DATE}${NC}\n" # Create array of all repositories ALL_REPOS=("$PRIMARY_REPO") for repo in "${ADDITIONAL_REPOS[@]}"; do ALL_REPOS+=("$repo") done # Fetch latest commits from all repositories (if enabled) if [ "$FETCH_COMMITS" = true ]; then if [ "$PULL_COMMITS" = true ]; then echo -e "${YELLOW}Pulling latest changes from all repositories...${NC}" echo -e "${RED}Warning: This will modify your working directories!${NC}" else echo -e "${YELLOW}Fetching latest commits from all repositories...${NC}" fi for repo in "${ALL_REPOS[@]}"; do if [ -d "$repo" ]; then repo_name=$(basename "$repo") if [ "$PULL_COMMITS" = true ]; then echo -e " Pulling changes in $repo_name..." if git -C "$repo" pull origin 2>/dev/null; then echo -e " ${GREEN}✓${NC} Successfully pulled changes in $repo_name" else echo -e " ${RED}✗${NC} Failed to pull changes in $repo_name (trying fetch only)" if git -C "$repo" fetch origin 2>/dev/null; then echo -e " ${GREEN}✓${NC} Successfully fetched from $repo_name" else echo -e " ${RED}✗${NC} Failed to fetch from $repo_name (continuing with local commits)" fi fi else echo -e " Fetching from $repo_name..." if git -C "$repo" fetch origin 2>/dev/null; then echo -e " ${GREEN}✓${NC} Successfully fetched from $repo_name" else echo -e " ${RED}✗${NC} Failed to fetch from $repo_name (continuing with local commits)" fi fi else echo -e " ${RED}✗${NC} Repository not found: $repo" fi done else echo -e "${YELLOW}Skipping fetch (using local commits only)${NC}" fi # Collect commits by category from all repositories echo -e "\n${YELLOW}Analyzing commits across all repositories...${NC}" # Initialize variables FEATURES="" FIXES="" BREAKING="" PERF="" API_CHANGES="" # Collect commits from all repositories for repo in "${ALL_REPOS[@]}"; do if [ -d "$repo" ]; then repo_name=$(basename "$repo") echo -e " Analyzing $repo_name..." # Features repo_features=$(get_commits_from_repo "$repo" "^[a-f0-9]+ feat:" | sed "s/^[a-f0-9]* feat: /- [$repo_name] /") if [ -n "$repo_features" ]; then FEATURES="$FEATURES$repo_features"$'\n' fi # Fixes repo_fixes=$(get_commits_from_repo "$repo" "^[a-f0-9]+ fix:" | sed "s/^[a-f0-9]* fix: /- [$repo_name] /") if [ -n "$repo_fixes" ]; then FIXES="$FIXES$repo_fixes"$'\n' fi # Breaking changes repo_breaking=$(get_commits_from_repo "$repo" "^[a-f0-9]+ .*(BREAKING|breaking change)" | sed "s/^[a-f0-9]* /- [$repo_name] /") if [ -n "$repo_breaking" ]; then BREAKING="$BREAKING$repo_breaking"$'\n' fi # Performance improvements repo_perf=$(get_commits_from_repo "$repo" "^[a-f0-9]+ perf:" | sed "s/^[a-f0-9]* perf: /- [$repo_name] /") if [ -n "$repo_perf" ]; then PERF="$PERF$repo_perf"$'\n' fi # API changes repo_api=$(get_commits_from_repo "$repo" "(api|endpoint|/write|/query|/ping|/health|/metrics|v1|v2|v3)" | sed "s/^[a-f0-9]* /- [$repo_name] /") if [ -n "$repo_api" ]; then API_CHANGES="$API_CHANGES$repo_api"$'\n' fi fi done # Analyze API changes in detail echo -e "\n${YELLOW}Analyzing HTTP API changes...${NC}" for repo in "${ALL_REPOS[@]}"; do repo_name=$(basename "$repo") analyze_api_changes "$repo" "$repo_name" done # Generate markdown output OUTPUT_FILE="release-notes-${TO_VERSION}.md" cat > "$OUTPUT_FILE" << EOF ## ${TO_VERSION} {date="${RELEASE_DATE}"} ### Features EOF # Add features if [ -n "$FEATURES" ]; then echo "$FEATURES" | while IFS= read -r line; do if [ -n "$line" ]; then PR=$(extract_pr_number "$line") # Clean up the commit message CLEAN_LINE=$(echo "$line" | sed -E 's/ \(#[0-9]+\)$//') if [ -n "$PR" ]; then echo "$CLEAN_LINE ([#$PR](https://github.com/influxdata/influxdb/pull/$PR))" >> "$OUTPUT_FILE" else echo "$CLEAN_LINE" >> "$OUTPUT_FILE" fi fi done else echo "- No new features in this release" >> "$OUTPUT_FILE" fi # Add bug fixes cat >> "$OUTPUT_FILE" << EOF ### Bug Fixes EOF if [ -n "$FIXES" ]; then echo "$FIXES" | while IFS= read -r line; do if [ -n "$line" ]; then PR=$(extract_pr_number "$line") CLEAN_LINE=$(echo "$line" | sed -E 's/ \(#[0-9]+\)$//') if [ -n "$PR" ]; then echo "$CLEAN_LINE ([#$PR](https://github.com/influxdata/influxdb/pull/$PR))" >> "$OUTPUT_FILE" else echo "$CLEAN_LINE" >> "$OUTPUT_FILE" fi fi done else echo "- No bug fixes in this release" >> "$OUTPUT_FILE" fi # Add breaking changes if any if [ -n "$BREAKING" ]; then cat >> "$OUTPUT_FILE" << EOF ### Breaking Changes EOF echo "$BREAKING" | while IFS= read -r line; do if [ -n "$line" ]; then PR=$(extract_pr_number "$line") CLEAN_LINE=$(echo "$line" | sed -E 's/ \(#[0-9]+\)$//') if [ -n "$PR" ]; then echo "$CLEAN_LINE ([#$PR](https://github.com/influxdata/influxdb/pull/$PR))" >> "$OUTPUT_FILE" else echo "$CLEAN_LINE" >> "$OUTPUT_FILE" fi fi done fi # Add performance improvements if any if [ -n "$PERF" ]; then cat >> "$OUTPUT_FILE" << EOF ### Performance Improvements EOF echo "$PERF" | while IFS= read -r line; do if [ -n "$line" ]; then PR=$(extract_pr_number "$line") CLEAN_LINE=$(echo "$line" | sed -E 's/ \(#[0-9]+\)$//') if [ -n "$PR" ]; then echo "$CLEAN_LINE ([#$PR](https://github.com/influxdata/influxdb/pull/$PR))" >> "$OUTPUT_FILE" else echo "$CLEAN_LINE" >> "$OUTPUT_FILE" fi fi done fi # Add HTTP API changes if any if [ -n "$API_CHANGES" ]; then cat >> "$OUTPUT_FILE" << EOF ### HTTP API Changes EOF echo "$API_CHANGES" | while IFS= read -r line; do if [ -n "$line" ]; then PR=$(extract_pr_number "$line") CLEAN_LINE=$(echo "$line" | sed -E 's/ \(#[0-9]+\)$//') if [ -n "$PR" ]; then echo "$CLEAN_LINE ([#$PR](https://github.com/influxdata/influxdb/pull/$PR))" >> "$OUTPUT_FILE" else echo "$CLEAN_LINE" >> "$OUTPUT_FILE" fi fi done fi # Add API analysis summary cat >> "$OUTPUT_FILE" << EOF ### API Analysis Summary The following endpoints may have been affected in this release: - v1 API endpoints: \`/write\`, \`/query\`, \`/ping\` - v2 API endpoints: \`/api/v2/write\`, \`/api/v2/query\` - v3 API endpoints: \`/api/v3/*\` - System endpoints: \`/health\`, \`/metrics\` Please review the commit details above and consult the API documentation for specific changes. EOF echo -e "\n${GREEN}Release notes generated in: ${OUTPUT_FILE}${NC}" echo -e "${YELLOW}Please review and edit the generated notes before adding to documentation.${NC}" echo -e "${BLUE}API changes have been automatically detected and included.${NC}"