|
1 | 1 | import argparse
|
2 | 2 | import datetime
|
| 3 | +import re |
3 | 4 | from github import Github
|
4 | 5 | import json
|
5 | 6 | import os
|
@@ -174,6 +175,60 @@ def get_today_string():
|
174 | 175 | today = datetime.datetime.today()
|
175 | 176 | return '{:%d %b %Y}'.format(today)
|
176 | 177 |
|
| 178 | +def process_changelog_for_backports(source_branch_major_version, target_branch_major_version): |
| 179 | + |
| 180 | + # changelog entries can use the following format to indicate |
| 181 | + # that they only apply to newer versions |
| 182 | + some_versions_only_regex = re.compile(r'\[v(\d+)\+ only\]') |
| 183 | + |
| 184 | + output = '' |
| 185 | + |
| 186 | + with open('CHANGELOG.md', 'r') as f: |
| 187 | + |
| 188 | + # until we find the first section, just duplicate all lines |
| 189 | + while True: |
| 190 | + line = f.readline() |
| 191 | + if not line: |
| 192 | + raise Exception('Could not find any change sections in CHANGELOG.md') # EOF |
| 193 | + |
| 194 | + output += line |
| 195 | + if line.startswith('## '): |
| 196 | + line = line.replace(f'## {source_branch_major_version}', f'## {target_branch_major_version}') |
| 197 | + # we have found the first section, so now handle things differently |
| 198 | + break |
| 199 | + |
| 200 | + # found_content tracks whether we hit two headings in a row |
| 201 | + found_content = False |
| 202 | + output += '\n' |
| 203 | + while True: |
| 204 | + line = f.readline() |
| 205 | + if not line: |
| 206 | + break # EOF |
| 207 | + line = line.rstrip('\n') |
| 208 | + |
| 209 | + # filter out changenote entries that apply only to newer versions |
| 210 | + match = some_versions_only_regex.search(line) |
| 211 | + if match: |
| 212 | + if int(target_branch_major_version) < int(match.group(1)): |
| 213 | + continue |
| 214 | + |
| 215 | + if line.startswith('## '): |
| 216 | + line = line.replace(f'## {source_branch_major_version}', f'## {target_branch_major_version}') |
| 217 | + if found_content == False: |
| 218 | + # we have found two headings in a row, so we need to add the placeholder message. |
| 219 | + output += 'No user facing changes.\n' |
| 220 | + found_content = False |
| 221 | + output += f'\n{line}\n\n' |
| 222 | + else: |
| 223 | + if line.strip() != '': |
| 224 | + found_content = True |
| 225 | + # we use the original line here, rather than the stripped version |
| 226 | + # so that we preserve indentation |
| 227 | + output += line + '\n' |
| 228 | + |
| 229 | + with open('CHANGELOG.md', 'w') as f: |
| 230 | + f.write(output) |
| 231 | + |
177 | 232 | def update_changelog(version):
|
178 | 233 | if (os.path.exists('CHANGELOG.md')):
|
179 | 234 | content = ''
|
@@ -324,13 +379,7 @@ def main():
|
324 | 379 |
|
325 | 380 | # Migrate the changelog notes from vLatest version numbers to vOlder version numbers
|
326 | 381 | print(f'Migrating changelog notes from v{source_branch_major_version} to v{target_branch_major_version}')
|
327 |
| - subprocess.check_output(['sed', '-i', f's/^## {source_branch_major_version}\./## {target_branch_major_version}./g', 'CHANGELOG.md']) |
328 |
| - |
329 |
| - # Remove changelog notes from all versions that do not apply to the vOlder branch |
330 |
| - print(f'Removing changelog notes that do not apply to v{target_branch_major_version}') |
331 |
| - for v in range(int(source_branch_major_version), int(target_branch_major_version), -1): |
332 |
| - print(f'Removing changelog notes that are tagged [v{v}+ only\]') |
333 |
| - subprocess.check_output(['sed', '-i', f'/^- \[v{v}+ only\]/d', 'CHANGELOG.md']) |
| 382 | + process_changelog_for_backports(source_branch_major_version, target_branch_major_version) |
334 | 383 |
|
335 | 384 | # Amend the commit generated by `npm version` to update the CHANGELOG
|
336 | 385 | run_git('add', 'CHANGELOG.md')
|
|
0 commit comments