import os import re import subprocess from datetime import datetime def get_version(): script_dir = os.path.dirname(os.path.abspath(__file__)) project_dir = os.path.dirname(script_dir) platformio_path = os.path.join(project_dir, 'platformio.ini') with open(platformio_path, 'r') as f: content = f.read() version_match = re.search(r'version\s*=\s*"([^"]+)"', content) return version_match.group(1) if version_match else None def get_last_tag(): try: result = subprocess.run(['git', 'describe', '--tags', '--abbrev=0'], capture_output=True, text=True) return result.stdout.strip() except subprocess.CalledProcessError: return None def categorize_commit(commit_msg): """Categorize commit messages based on conventional commits""" lower_msg = commit_msg.lower() if any(x in lower_msg for x in ['feat', 'add', 'new']): return 'Added' elif any(x in lower_msg for x in ['fix', 'bug']): return 'Fixed' else: return 'Changed' def get_changes_from_git(): """Get changes from git commits since last tag""" changes = { 'Added': [], 'Changed': [], 'Fixed': [] } last_tag = get_last_tag() # Get commits since last tag git_log_command = ['git', 'log', '--pretty=format:%s'] if last_tag: git_log_command.append(f'{last_tag}..HEAD') try: result = subprocess.run(git_log_command, capture_output=True, text=True) commits = result.stdout.strip().split('\n') # Filter out empty commits and categorize for commit in commits: if commit: category = categorize_commit(commit) # Clean up commit message clean_msg = re.sub(r'^(feat|fix|chore|docs|style|refactor|perf|test)(\(.*\))?:', '', commit).strip() changes[category].append(clean_msg) except subprocess.CalledProcessError: print("Error: Failed to get git commits") return None return changes def push_changes(version): """Push changes to upstream""" try: # Stage the CHANGELOG.md subprocess.run(['git', 'add', 'CHANGELOG.md'], check=True) # Commit the changelog commit_msg = f"docs: update changelog for version {version}" subprocess.run(['git', 'commit', '-m', commit_msg], check=True) # Push to origin (local) subprocess.run(['git', 'push', 'origin'], check=True) print("Successfully pushed to origin") except subprocess.CalledProcessError as e: print(f"Error during git operations: {e}") return False return True def update_changelog(): print("Starting changelog update...") # Add this line version = get_version() print(f"Current version: {version}") # Add this line today = datetime.now().strftime('%Y-%m-%d') script_dir = os.path.dirname(os.path.abspath(__file__)) project_dir = os.path.dirname(script_dir) changelog_path = os.path.join(project_dir, 'CHANGELOG.md') # Get changes from git changes = get_changes_from_git() if not changes: print("No changes found or error occurred") return # Create changelog entry changelog_entry = f"## [{version}] - {today}\n" for section, entries in changes.items(): if entries: # Only add sections that have entries changelog_entry += f"### {section}\n" for entry in entries: changelog_entry += f"- {entry}\n" changelog_entry += "\n" if not os.path.exists(changelog_path): with open(changelog_path, 'w') as f: f.write(f"# Changelog\n\n{changelog_entry}") push_changes(version) else: with open(changelog_path, 'r') as f: content = f.read() if f"[{version}]" not in content: updated_content = content.replace("# Changelog\n", f"# Changelog\n\n{changelog_entry}") with open(changelog_path, 'w') as f: f.write(updated_content) push_changes(version) else: print(f"Version {version} already exists in changelog") if __name__ == "__main__": update_changelog()