diff --git a/.github/update-release-branch.py b/.github/update-release-branch.py index b17cafc7a..ecde537a2 100644 --- a/.github/update-release-branch.py +++ b/.github/update-release-branch.py @@ -1,5 +1,6 @@ import argparse import datetime +import re from github import Github import json import os @@ -174,6 +175,60 @@ def get_today_string(): today = datetime.datetime.today() return '{:%d %b %Y}'.format(today) +def process_changelog_for_backports(source_branch_major_version, target_branch_major_version): + + # changelog entries can use the following format to indicate + # that they only apply to newer versions + some_versions_only_regex = re.compile(r'\[v(\d+)\+ only\]') + + output = '' + + with open('CHANGELOG.md', 'r') as f: + + # until we find the first section, just duplicate all lines + while True: + line = f.readline() + if not line: + raise Exception('Could not find any change sections in CHANGELOG.md') # EOF + + output += line + if line.startswith('## '): + line = line.replace(f'## {source_branch_major_version}', f'## {target_branch_major_version}') + # we have found the first section, so now handle things differently + break + + # found_content tracks whether we hit two headings in a row + found_content = False + output += '\n' + while True: + line = f.readline() + if not line: + break # EOF + line = line.rstrip('\n') + + # filter out changenote entries that apply only to newer versions + match = some_versions_only_regex.search(line) + if match: + if int(target_branch_major_version) < int(match.group(1)): + continue + + if line.startswith('## '): + line = line.replace(f'## {source_branch_major_version}', f'## {target_branch_major_version}') + if found_content == False: + # we have found two headings in a row, so we need to add the placeholder message. + output += 'No user facing changes.\n' + found_content = False + output += f'\n{line}\n\n' + else: + if line.strip() != '': + found_content = True + # we use the original line here, rather than the stripped version + # so that we preserve indentation + output += line + '\n' + + with open('CHANGELOG.md', 'w') as f: + f.write(output) + def update_changelog(version): if (os.path.exists('CHANGELOG.md')): content = '' @@ -324,13 +379,7 @@ def main(): # Migrate the changelog notes from vLatest version numbers to vOlder version numbers print(f'Migrating changelog notes from v{source_branch_major_version} to v{target_branch_major_version}') - subprocess.check_output(['sed', '-i', f's/^## {source_branch_major_version}\./## {target_branch_major_version}./g', 'CHANGELOG.md']) - - # Remove changelog notes from all versions that do not apply to the vOlder branch - print(f'Removing changelog notes that do not apply to v{target_branch_major_version}') - for v in range(int(source_branch_major_version), int(target_branch_major_version), -1): - print(f'Removing changelog notes that are tagged [v{v}+ only\]') - subprocess.check_output(['sed', '-i', f'/^- \[v{v}+ only\]/d', 'CHANGELOG.md']) + process_changelog_for_backports(source_branch_major_version, target_branch_major_version) # Amend the commit generated by `npm version` to update the CHANGELOG run_git('add', 'CHANGELOG.md')