mirror of
				https://github.com/espressif/esp-protocols.git
				synced 2025-11-04 08:31:37 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			116 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
 | 
						|
# SPDX-License-Identifier: Apache-2.0
 | 
						|
import argparse
 | 
						|
import os
 | 
						|
import re
 | 
						|
 | 
						|
import sh
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    parser = argparse.ArgumentParser(
 | 
						|
        description='Generates a change log from cz commits')
 | 
						|
    parser.add_argument('component')
 | 
						|
    args = parser.parse_args()
 | 
						|
 | 
						|
    old_ref = os.environ.get('CZ_PRE_CURRENT_TAG_VERSION')
 | 
						|
    new_tag = os.environ.get('CZ_PRE_NEW_TAG_VERSION')
 | 
						|
    new_ref = os.environ.get('CZ_PRE_NEW_VERSION')
 | 
						|
    component = args.component
 | 
						|
 | 
						|
    root_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
 | 
						|
 | 
						|
    git = sh.git.bake(_cwd=root_path)
 | 
						|
 | 
						|
    keys = ['breaking', 'major', 'feat', 'fix', 'update']
 | 
						|
    items = {key: [] for key in keys}
 | 
						|
    sections = {
 | 
						|
        'feat': 'Features',
 | 
						|
        'fix': 'Bug Fixes',
 | 
						|
        'update': 'Updated',
 | 
						|
        'breaking': 'Breaking changes',
 | 
						|
        'major': 'Major changes'
 | 
						|
    }
 | 
						|
 | 
						|
    res = git('show-ref', '--tags', _tty_out=False)
 | 
						|
    if old_ref not in res:
 | 
						|
        old_ref = git('rev-list', '--max-parents=0', 'HEAD', _tty_out=False).strip()
 | 
						|
 | 
						|
    brief_log = git.log('--oneline', '{}..HEAD'.format(old_ref), '--', 'components/' + component, _tty_out=False)
 | 
						|
    for oneline in brief_log.splitlines():
 | 
						|
        [commit, brief_msg] = oneline.split(' ', 1)
 | 
						|
        if 'Merge' in str(brief_msg) or brief_msg.startswith('bump('):  # skip Merge commits and bumps
 | 
						|
            continue
 | 
						|
        find_title = re.findall(r'^(fix|feat|esp_modem|esp-modem|mdns)(\([^\)]+\))?:\s*(.+)$', str(brief_msg))
 | 
						|
        item_type = ''             # default prefix
 | 
						|
        item_message = brief_msg   # default body
 | 
						|
        if find_title is not None and len(find_title) > 0:  # Use scopes & types
 | 
						|
            item_type = find_title[0][0]      # prefix (fix/feat/ci)
 | 
						|
            item_message = find_title[0][-1]  # title body
 | 
						|
 | 
						|
        # Add details in parentheses (commit-id and references from the FOOTER section)
 | 
						|
        details = '[{}](https://github.com/espressif/esp-protocols/commit/{})'.format(commit, commit)
 | 
						|
        msg_details = git.show('-s', commit, _tty_out=False)
 | 
						|
        # check references
 | 
						|
        if any(s in str(msg_details) for s in ['esp-protocols/issues', 'BREAKING CHANGE', 'MAJOR CHANGE']):
 | 
						|
            # Closes <issue>
 | 
						|
            closes = re.findall(r'Closes ([^\d]+/(\d+))', str(msg_details), re.MULTILINE)
 | 
						|
            if closes and closes[0] is not None:
 | 
						|
                details += ', [#{}]({})'.format(closes[0][1], closes[0][0])
 | 
						|
            # Breaking changes
 | 
						|
            find_breaking = re.findall(r'BREAKING CHANGE:\s*([^\n]*)', str(msg_details), re.MULTILINE)
 | 
						|
            if find_breaking is not None and len(find_breaking) > 0:
 | 
						|
                if find_breaking[0] != '':
 | 
						|
                    items['breaking'].append('{} ([{}](https://github.com/espressif/esp-protocols/commit/{}))'.format(find_breaking[0], item_message, commit))
 | 
						|
                else:
 | 
						|
                    items['breaking'].append('{} ({})'.format(item_message, details))
 | 
						|
                details += ', !BREAKING'
 | 
						|
            # Major changes
 | 
						|
            find_major = re.findall(r'MAJOR CHANGE:\s*([^\n]*)',
 | 
						|
                                    str(msg_details), re.MULTILINE)
 | 
						|
            if find_major is not None and len(
 | 
						|
                    find_major) > 0 and find_major[0] != '':
 | 
						|
                items['major'].append('{} ([{}](https://github.com/espressif/esp-protocols/commit/{}))'.format(find_major[0], item_message, commit))
 | 
						|
        if item_type in ['fix', 'feat']:
 | 
						|
            items[item_type].append('{} ({})'.format(item_message, details))
 | 
						|
        else:
 | 
						|
            items['update'].append('{} ({})'.format(item_message, details))
 | 
						|
    # Generate changelog
 | 
						|
    changelog = '## [{}](https://github.com/espressif/esp-protocols/commits/{})\n'.format(
 | 
						|
        new_ref, new_tag)
 | 
						|
    for section, item in items.items():
 | 
						|
        if len(item) > 0:
 | 
						|
            changelog += '\n### {}\n\n'.format(sections[section])
 | 
						|
            for it in item:
 | 
						|
                changelog += '- {}\n'.format(it)
 | 
						|
    changelog += '\n'
 | 
						|
    filename = os.path.join(root_path, 'components', component, 'CHANGELOG.md')
 | 
						|
    # Check if the changelog file exists.
 | 
						|
    if not os.path.exists(filename):
 | 
						|
        # File does not exist, create it
 | 
						|
        with open(filename, 'w') as file:
 | 
						|
            file.write('# Changelog\n\n')
 | 
						|
    # insert the actual changelog to the beginning of the file, just after the title (2nd line)
 | 
						|
    with open(filename, 'r') as orig_changelog:
 | 
						|
        changelog_title = orig_changelog.readline(
 | 
						|
        )  # expect # Changelog title on the first line
 | 
						|
        changelog_nl = orig_changelog.readline()
 | 
						|
        orig_items = orig_changelog.read()
 | 
						|
    with open(filename, 'w') as updated_changelog:
 | 
						|
        updated_changelog.write(changelog_title)
 | 
						|
        updated_changelog.write(changelog_nl)
 | 
						|
        updated_changelog.write(changelog)
 | 
						|
        updated_changelog.write(orig_items)
 | 
						|
    git.add(filename)
 | 
						|
 | 
						|
    # write the current changelog entry to a local text file (removing links, captions and extra newlines)
 | 
						|
    changelog = re.sub(r'\[([^\]]+)\]\([^\)]+\)', r'\1', changelog)
 | 
						|
    changelog = re.sub(r'\#\#[\#\s]*(.+)', r'\1', changelog)
 | 
						|
    changelog = re.sub(r'\n\n', '\n', changelog)
 | 
						|
    with open(os.path.join(root_path, 'release_notes.txt'), 'w') as release_notes:
 | 
						|
        release_notes.write(changelog)
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    main()
 |