diff --git a/helper-scripts/generate-release-notes.sh b/helper-scripts/generate-release-notes.sh index 58f34212e..d47ae5592 100755 --- a/helper-scripts/generate-release-notes.sh +++ b/helper-scripts/generate-release-notes.sh @@ -1,14 +1,55 @@ #!/bin/bash # Script to generate release notes for InfluxDB v3.x releases -# Usage: ./generate-release-notes.sh +# 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 -# Default values -REPO_PATH="${3:-/Users/ja/Documents/github/influxdb}" +# 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' @@ -18,7 +59,13 @@ BLUE='\033[0;34m' NC='\033[0m' # No Color echo -e "${BLUE}Generating release notes for ${TO_VERSION}${NC}" -echo -e "Repository: ${REPO_PATH}" +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 @@ -26,28 +73,156 @@ 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 "$REPO_PATH" log -1 --format=%ai "$TO_VERSION" | cut -d' ' -f1) +RELEASE_DATE=$(git -C "$PRIMARY_REPO" log -1 --format=%ai "$TO_VERSION" | cut -d' ' -f1) echo -e "${GREEN}Release Date: ${RELEASE_DATE}${NC}\n" -# Collect commits by category -echo -e "${YELLOW}Analyzing commits...${NC}" +# Create array of all repositories +ALL_REPOS=("$PRIMARY_REPO") +for repo in "${ADDITIONAL_REPOS[@]}"; do + ALL_REPOS+=("$repo") +done -# Features -echo -e "\n${GREEN}Features:${NC}" -FEATURES=$(git -C "$REPO_PATH" log --format="%h %s" "${FROM_VERSION}..${TO_VERSION}" | grep -E "^[a-f0-9]+ feat:" | sed 's/^[a-f0-9]* feat: //') +# 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 -# Fixes -echo -e "\n${GREEN}Bug Fixes:${NC}" -FIXES=$(git -C "$REPO_PATH" log --format="%h %s" "${FROM_VERSION}..${TO_VERSION}" | grep -E "^[a-f0-9]+ fix:" | sed 's/^[a-f0-9]* fix: //') +# Collect commits by category from all repositories +echo -e "\n${YELLOW}Analyzing commits across all repositories...${NC}" -# Breaking changes -echo -e "\n${GREEN}Breaking Changes:${NC}" -BREAKING=$(git -C "$REPO_PATH" log --format="%h %s" "${FROM_VERSION}..${TO_VERSION}" | grep -iE "^[a-f0-9]+ .*(BREAKING|breaking change)" | sed 's/^[a-f0-9]* //') +# Initialize variables +FEATURES="" +FIXES="" +BREAKING="" +PERF="" +API_CHANGES="" -# Performance improvements -echo -e "\n${GREEN}Performance:${NC}" -PERF=$(git -C "$REPO_PATH" log --format="%h %s" "${FROM_VERSION}..${TO_VERSION}" | grep -E "^[a-f0-9]+ perf:" | sed 's/^[a-f0-9]* perf: //') +# 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" @@ -60,16 +235,18 @@ EOF # Add features if [ -n "$FEATURES" ]; then - while IFS= read -r line; do - 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" + 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 <<< "$FEATURES" + done else echo "- No new features in this release" >> "$OUTPUT_FILE" fi @@ -82,15 +259,17 @@ cat >> "$OUTPUT_FILE" << EOF EOF if [ -n "$FIXES" ]; then - while IFS= read -r line; do - 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" + 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 <<< "$FIXES" + done else echo "- No bug fixes in this release" >> "$OUTPUT_FILE" fi @@ -102,15 +281,17 @@ if [ -n "$BREAKING" ]; then ### Breaking Changes EOF - while IFS= read -r line; do - 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" + 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 <<< "$BREAKING" + done fi # Add performance improvements if any @@ -120,16 +301,54 @@ if [ -n "$PERF" ]; then ### Performance Improvements EOF - while IFS= read -r line; do - 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" + 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 <<< "$PERF" + 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}" \ No newline at end of file +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}" \ No newline at end of file