def check_local_repo(repository, branch, release_name, rev, **extra_kwargs): # releasing from the local clone has the advantage we can prepare the # release offline and only push and upload it when we get back online s = f"Using local repository at: {repository} !" print("\n", s, "\n", "=" * len(s), "\n", sep='') status = call(['git', 'status', '-s', '-b']) lines = status.splitlines() statusline, lines = lines[0], lines[1:] curbranch = branchname(statusline) if curbranch != branch: print(f"{branch} is not the current branch ({curbranch}). " f"Please use 'git checkout {branch}'.") exit(1) if lines: uncommited = sum(1 for line in lines if line[1] in 'MDAU') untracked = sum(1 for line in lines if line.startswith('??')) print(f'Warning: there are {uncommited:d} files with uncommitted changes and {untracked:d} untracked files:') print('\n'.join(lines)) if no('Do you want to continue?'): exit(1) ahead = call(['git', 'log', '--format=format:%H', f'origin/{branch}..{branch}']) num_ahead = len(ahead.splitlines()) print(f"Branch '{branch}' is {num_ahead:d} commits ahead of 'origin/{branch}'", end='') if num_ahead: if yes(', do you want to push?'): doechocall('Pushing changes', ['git', 'push']) else: print() if no(f"Release version {release_name} ({rev})?"): exit(1)
def update_changelog( src_documentation, build_dir, release_name, changelog_index_template=DEFAULT_CHANGELOG_INDEX_TEMPLATE): chdir(build_dir) fname = relname2fname(release_name) # create "empty" changelog for that release changes_dir = join(src_documentation, 'changes') changelog_file = join(changes_dir, fname) copy(join(changes_dir, 'template.rst.inc'), changelog_file) # include release changelog in changes.rst fpath = join(src_documentation, 'changes.rst') with open(fpath) as f: lines = f.readlines() title = f"Version {short(release_name)}" if lines[3] == title + '\n': print(f"changes.rst not modified (it already contains {title})") return this_version = changelog_index_template.format(title=title, underline="=" * len(title), fname=fname) lines[3:3] = this_version.splitlines(True) with open(fpath, 'w') as f: f.writelines(lines) with open(fpath, encoding='utf-8-sig') as f: print('\n'.join(f.read().splitlines()[:20])) if no('Does the full changelog look right?'): exit(1) echocall(['git', 'add', fpath, changelog_file])
def check_clone(build_dir, public_release, src_documentation, release_name, **extra_kwargs): chdir(build_dir) # check last commit print() print(echocall(['git', 'log', '-1'], end='\n')) print() if no('Does that last commit look right?'): exit(1) if public_release: # check release changes print(release_changes(src_documentation, release_name, build_dir)) if no('Does the release changelog look right?'): exit(1)
def update_changelog(src_documentation, build_dir, public_release, release_name, **extra_kwargs): """ Update release date in changes.rst """ if src_documentation is not None: chdir(build_dir) if not public_release: return fpath = join(src_documentation, 'changes.rst') with open(fpath) as f: lines = f.readlines() expected_title = f"Version {short(release_name)}" title = lines[3] if title != expected_title + '\n': print(f'changes.rst not modified (the version title is "{title}" and instead of "{expected_title}")') return release_date = lines[6] if release_date != "In development.\n": print(f'changes.rst not modified (the version release date is "{release_date}" ' 'instead of "In development.", was it already released?)') return lines[6] = f"Released on {date.today().isoformat()}.\n" with open(fpath, 'w') as f: f.writelines(lines) with open(fpath, encoding='utf-8-sig') as f: print() print('\n'.join(f.read().splitlines()[:20])) if no('Does the changelog look right?'): exit(1) echocall(['git', 'commit', '-m', f'update release date for {short(release_name)}', fpath])
def update_version(build_dir, release_name, package_name, module_name, **extra_kwargs): chdir(build_dir) version = short(release_name) # meta.yaml meta_file = join('condarecipe', package_name, 'meta.yaml') changes = [('version: ', f" version: {version}"), ('git_tag: ', f" git_tag: {version}")] replace_lines(meta_file, changes) # __init__.py init_file = join(module_name, '__init__.py') changes = [('__version__ =', f"__version__ = '{version}'")] replace_lines(init_file, changes) # setup.py setup_file = 'setup.py' changes = [('VERSION =', f"VERSION = '{version}'")] replace_lines(setup_file, changes) # check, commit and push print(echocall(['git', 'status', '-s'])) print(echocall(['git', 'diff', meta_file, init_file, setup_file])) if no('Do the version update changes look right?'): exit(1) doechocall('Adding', ['git', 'add', meta_file, init_file, setup_file]) doechocall('Committing', ['git', 'commit', '-m', f'bump version to {version}']) print(echocall(['git', 'log', '-1']))
def update_version_conda_forge_package(build_dir, version, main_repository, **extra_kwargs): chdir(build_dir) # compute sha256 of archive of current release url = main_repository + f'/archive/{version}.tar.gz' print(f'Computing SHA256 from archive {url}', end=' ') with request.urlopen(url) as response: sha256 = hashlib.sha256(response.read()).hexdigest() print('done.') print('SHA256: ', sha256) # set version and sha256 in meta.yml file meta_file = r'recipe\meta.yaml' changes = [('set version', f'{{% set version = "{version}" %}}'), ('set sha256', f'{{% set sha256 = "{sha256}" %}}')] replace_lines(meta_file, changes) # add, commit and push print(echocall(['git', 'status', '-s'])) print(echocall(['git', 'diff', meta_file])) if no('Does that last changes look right?'): exit(1) doechocall('Adding', ['git', 'add', meta_file]) doechocall('Commiting', ['git', 'commit', '-m', f'bump version to {version}'])
def final_confirmation(public_release, **extra_kwargs): if not public_release: return msg = """Is the release looking good? If so, the tag will be created and pushed, everything will be uploaded to the production server. Stuff to watch out for: * version numbers (executable & changelog) * changelog * doc on readthedocs """ if no(msg): exit(1)
def push_on_pypi(build_dir, public_release, **extra_kwargs): if not public_release: return chdir(build_dir) cmd = ['python', 'setup.py', 'clean', 'register', 'sdist', 'bdist_wheel', '--universal', 'upload', '-r', 'pypi'] msg = f"""Ready to push on pypi? If so, command line {' '.join(cmd)} will now be executed. """ if no(msg): exit(1) echocall(cmd)