mirror of https://github.com/sysown/proxysql
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
182 lines
6.0 KiB
182 lines
6.0 KiB
#!/usr/bin/env python3
|
|
import subprocess
|
|
import json
|
|
import re
|
|
import sys
|
|
|
|
def run(cmd_list):
|
|
return subprocess.check_output(cmd_list, text=True).strip()
|
|
|
|
# Get merge commits since v3.0.3
|
|
merge_log = run(["git", "log", "v3.0.3..v3.0", "--merges", "--pretty=format:%H %s"])
|
|
lines = merge_log.split('\n')
|
|
pr_numbers = []
|
|
for line in lines:
|
|
if 'Merge pull request' in line:
|
|
match = re.search(r'#(\d+)', line)
|
|
if match:
|
|
pr_numbers.append(match.group(1))
|
|
print(f'Found {len(pr_numbers)} PRs')
|
|
|
|
# Fetch PR details using gh
|
|
prs = []
|
|
for num in pr_numbers:
|
|
try:
|
|
data = run(["gh", "pr", "view", str(num), "--json", "title,body,number,url,labels"])
|
|
pr = json.loads(data)
|
|
prs.append(pr)
|
|
except subprocess.CalledProcessError as e:
|
|
print(f'Failed to fetch PR {num}: {e}')
|
|
continue
|
|
|
|
# Categorize based on labels and title
|
|
categories = {
|
|
'Bug Fixes': [],
|
|
'New Features': [],
|
|
'Improvements': [],
|
|
'Documentation': [],
|
|
'Testing': [],
|
|
'Build/Packaging': [],
|
|
'Refactoring': [],
|
|
'Security': [],
|
|
'Monitoring': [],
|
|
'PostgreSQL': [],
|
|
'MySQL': [],
|
|
'Other': [],
|
|
}
|
|
|
|
def categorize(pr):
|
|
title = pr['title'].lower()
|
|
labels = [l['name'].lower() for l in pr.get('labels', [])]
|
|
# label hints
|
|
for label in labels:
|
|
if 'bug' in label:
|
|
return 'Bug Fixes'
|
|
if 'feature' in label:
|
|
return 'New Features'
|
|
if 'documentation' in label:
|
|
return 'Documentation'
|
|
if 'test' in label:
|
|
return 'Testing'
|
|
if 'security' in label:
|
|
return 'Security'
|
|
if 'refactor' in label:
|
|
return 'Refactoring'
|
|
if 'improvement' in label:
|
|
return 'Improvements'
|
|
# title keywords
|
|
if any(word in title for word in ['fix', 'bug', 'issue', 'crash', 'vulnerability', 'error']):
|
|
return 'Bug Fixes'
|
|
if any(word in title for word in ['add', 'new', 'support', 'implement', 'feature', 'introduce', 'enable']):
|
|
return 'New Features'
|
|
if any(word in title for word in ['improve', 'optimize', 'enhance', 'performance', 'better']):
|
|
return 'Improvements'
|
|
if any(word in title for word in ['doc', 'documentation', 'doxygen']):
|
|
return 'Documentation'
|
|
if any(word in title for word in ['test', 'tap', 'regression']):
|
|
return 'Testing'
|
|
if any(word in title for word in ['build', 'package', 'opensuse', 'docker']):
|
|
return 'Build/Packaging'
|
|
if any(word in title for word in ['refactor', 'cleanup', 'restructure']):
|
|
return 'Refactoring'
|
|
if any(word in title for word in ['security', 'injection', 'vulnerability']):
|
|
return 'Security'
|
|
if any(word in title for word in ['monitor', 'metric', 'log']):
|
|
return 'Monitoring'
|
|
if any(word in title for word in ['postgresql', 'pgsql', 'pg']):
|
|
return 'PostgreSQL'
|
|
if any(word in title for word in ['mysql']):
|
|
return 'MySQL'
|
|
return 'Other'
|
|
|
|
for pr in prs:
|
|
cat = categorize(pr)
|
|
categories[cat].append(pr)
|
|
|
|
# Generate markdown
|
|
output = []
|
|
output.append('# ProxySQL 3.0.4 Detailed Changelog\n')
|
|
output.append('\n')
|
|
output.append('This changelog lists all pull requests merged since ProxySQL 3.0.3.\n')
|
|
output.append('\n')
|
|
|
|
for cat in sorted(categories.keys()):
|
|
entries = categories[cat]
|
|
if not entries:
|
|
continue
|
|
output.append(f'## {cat}\n')
|
|
for pr in entries:
|
|
output.append(f'- **PR #{pr["number"]}**: [{pr["title"]}]({pr["url"]})\n')
|
|
if pr.get('body'):
|
|
# take first non-empty line as summary
|
|
lines = pr['body'].split('\n')
|
|
summary = ''
|
|
for line in lines:
|
|
if line.strip():
|
|
summary = line.strip()
|
|
break
|
|
if summary:
|
|
output.append(f' - {summary}\n')
|
|
output.append('\n')
|
|
|
|
with open('CHANGELOG-3.0.4-detailed.md', 'w') as f:
|
|
f.writelines(output)
|
|
|
|
print('Generated CHANGELOG-3.0.4-detailed.md')
|
|
|
|
# Also generate a concise version for release notes
|
|
release_notes = []
|
|
release_notes.append('# ProxySQL 3.0.4 Release Notes\n')
|
|
release_notes.append('\n')
|
|
release_notes.append('ProxySQL 3.0.4 includes numerous bug fixes, improvements, and new features.\n')
|
|
release_notes.append('\n')
|
|
|
|
# New Features section
|
|
new_features = categories['New Features'] + categories['PostgreSQL'] + categories['MySQL']
|
|
if new_features:
|
|
release_notes.append('## New Features\n')
|
|
for pr in new_features:
|
|
release_notes.append(f'- {pr["title"]} [#{pr["number"]}]({pr["url"]})\n')
|
|
release_notes.append('\n')
|
|
|
|
# Bug Fixes
|
|
bug_fixes = categories['Bug Fixes'] + categories['Security']
|
|
if bug_fixes:
|
|
release_notes.append('## Bug Fixes\n')
|
|
for pr in bug_fixes:
|
|
release_notes.append(f'- {pr["title"]} [#{pr["number"]}]({pr["url"]})\n')
|
|
release_notes.append('\n')
|
|
|
|
# Improvements
|
|
improvements = categories['Improvements'] + categories['Refactoring'] + categories['Monitoring']
|
|
if improvements:
|
|
release_notes.append('## Improvements\n')
|
|
for pr in improvements:
|
|
release_notes.append(f'- {pr["title"]} [#{pr["number"]}]({pr["url"]})\n')
|
|
release_notes.append('\n')
|
|
|
|
# Documentation
|
|
if categories['Documentation']:
|
|
release_notes.append('## Documentation\n')
|
|
for pr in categories['Documentation']:
|
|
release_notes.append(f'- {pr["title"]} [#{pr["number"]}]({pr["url"]})\n')
|
|
release_notes.append('\n')
|
|
|
|
# Testing
|
|
if categories['Testing']:
|
|
release_notes.append('## Testing\n')
|
|
for pr in categories['Testing']:
|
|
release_notes.append(f'- {pr["title"]} [#{pr["number"]}]({pr["url"]})\n')
|
|
release_notes.append('\n')
|
|
|
|
# Build/Packaging
|
|
if categories['Build/Packaging']:
|
|
release_notes.append('## Build/Packaging\n')
|
|
for pr in categories['Build/Packaging']:
|
|
release_notes.append(f'- {pr["title"]} [#{pr["number"]}]({pr["url"]})\n')
|
|
release_notes.append('\n')
|
|
|
|
with open('RELEASE_NOTES-3.0.4.md', 'w') as f:
|
|
f.writelines(release_notes)
|
|
|
|
print('Generated RELEASE_NOTES-3.0.4.md') |