def test_list_news_fragments(monkeypatch): """ Test that list_news_fragments(): - picks up news fragments in the root changelog directory - picks up news fragments in the changelog sub-directories - picks up misnamed news fragments - excludes ignored files """ changelog_root = PurePath(__file__).parent / 'fake_repo' / 'changelog' monkeypatch.setattr('script_utils.news_fragments.CHANGELOG_ROOT', changelog_root) absolute_paths = list_news_fragments() relative_paths = { str(path.relative_to(changelog_root)) for path in absolute_paths } assert relative_paths == { 'misnamed.fragment.feature', 'root-test.feature.md', 'adviser/adviser-test.feature.md', }
def create_release_branch(): """Create and push a release branch.""" remote = 'origin' if any_uncommitted_changes(): raise CommandError( 'There are uncommitted changes. Please commit, stash or delete them and try again.', ) subprocess.run(['git', 'fetch'], check=True) subprocess.run(['git', 'checkout', f'{remote}/develop'], check=True, capture_output=True) version = get_current_version() branch = f'release/{version}' tag = f'v{version}' if remote_tag_exists(tag): raise CommandError( f'A remote tag {tag} currently exists. It looks like version {version} has ' f'already been released.', ) news_fragment_paths = list_news_fragments() if news_fragment_paths: joined_paths = '\n'.join(str(path) for path in news_fragment_paths) raise CommandError( 'These are news fragments on origin/develop:\n\n' f'{joined_paths}\n\n' 'Is the changelog up to date?', ) if local_branch_exists(branch): raise CommandError( f'Branch {branch} already exists locally. Please delete it and try again.', ) if remote_branch_exists(branch): raise CommandError( f'Branch {branch} already exists remotely. Please delete it on GitHub and try again.', ) subprocess.run(['git', 'checkout', '-b', branch, f'{remote}/develop'], check=True) subprocess.run(['git', 'push', '--set-upstream', remote, branch], check=True) params = { 'expand': '1', 'title': f'Release {version}', 'body': PR_BODY_TEMPLATE.format(version=version, release_guide_url=RELEASE_GUIDE_URL), } encoded_params = urlencode(params) escaped_branch_name = quote(branch) webbrowser.open( f'{GITHUB_BASE_REPO_URL}/compare/master...{escaped_branch_name}?{encoded_params}', ) return branch
def prepare_release(release_type): """Bump the version, update the changelog and open a PR.""" remote = 'origin' if any_uncommitted_changes(): raise CommandError( 'There are uncommitted changes. Please commit, stash or delete them and try again.', ) subprocess.run(['git', 'fetch'], check=True) subprocess.run(['git', 'checkout', f'{remote}/develop'], check=True, capture_output=True) new_version = get_next_version(release_type) branch = f'changelog/{new_version}' pr_title = f'Prepare for release {new_version}' pr_body = f'This bumps the version and adds the changelog for version {new_version}.' commit_message = f"""{pr_title}\n\n{pr_body}""" if local_branch_exists(branch): raise CommandError( f'Branch {branch} already exists locally. Please delete it and try again.', ) if remote_branch_exists(branch): raise CommandError( f'Branch {branch} already exists remotely. Please delete it on GitHub and try again.', ) if not list_news_fragments(): raise CommandError('There are no news fragments.') subprocess.run(['git', 'checkout', '-b', branch, f'{remote}/develop'], check=True) subprocess.run(['towncrier', '--version', str(new_version), '--yes'], check=True) remaining_news_fragment_paths = list_news_fragments() if remaining_news_fragment_paths: joined_paths = '\n'.join( str(path) for path in remaining_news_fragment_paths) raise CommandError( 'These news fragments were left behind:\n\n' f'{joined_paths}\n\n' 'They may be misnamed. Please investigate.', ) set_current_version(new_version) subprocess.run(['git', 'add', VERSION_FILE_PATH], check=True) subprocess.run(['git', 'commit', '-m', commit_message], check=True) subprocess.run(['git', 'push', '--set-upstream', remote, branch], check=True) escaped_branch_name = quote(branch) params = { 'expand': '1', 'title': pr_title, 'body': pr_body, } webbrowser.open( f'{BASE_GITHUB_REPO_URL}/compare/{escaped_branch_name}?{urlencode(params)}' ) return branch