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 push(repository, public_release, branch, **extra_kwargs): if not public_release: return chdir(repository) doechocall('Pushing main repository changes to GitHub', ['git', 'push', 'upstream', branch, '--follow-tags'])
def build_doc(build_dir, **extra_kwargs): chdir(build_dir) chdir('doc') if sys.platform == "win32": echocall('buildall.bat') else: echocall('buildall.sh')
def tag_release(build_dir, public_release, release_name, **extra_kwargs): if not public_release: return chdir(build_dir) echocall(['git', 'tag', '-a', release_name, '-m', f'tag release {release_name}'])
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 pull(repository, public_release, build_dir, branch, **extra_kwargs): if not public_release: return # pull the changelog commits to the branch (usually master) # and the release tag (which refers to the last commit) chdir(repository) doechocall(f'Pulling changes in {repository}', ['git', 'pull', '--ff-only', '--tags', build_dir, branch])
def clone_repository(tmp_dir, branch, repository, **extra_kwargs): chdir(tmp_dir) # make a temporary clone in /tmp. The goal is to make sure we do not include extra/unversioned files. For the -src # archive, I don't think there is a risk given that we do it via git, but the risk is there for the bundles # (src/build is not always clean, examples, editor, ...) # Since this script updates files (update_changelog), we need to get those changes propagated to GitHub. I do that # by updating the temporary clone then push twice: first from the temporary clone to the "working copy clone" (eg # ~/devel/project) then to GitHub from there. The alternative to modify the "working copy clone" directly is worse # because it needs more complicated path handling that the 2 push approach. doechocall('Cloning repository', ['git', 'clone', '-b', branch, repository, 'build'])
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)
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 build_conda_packages(conda_recipe_path, build_dir, conda_build_args, **extra_kwargs): if conda_recipe_path is None: return chdir(build_dir) print() print('Building conda packages') print('=======================') # XXX: split build & upload? (--no-anaconda-upload) cmd = ['conda', 'build'] if conda_build_args: for arg_name, arg_value in conda_build_args.items(): cmd += [arg_name, arg_value] cmd += [conda_recipe_path] print(' '.join(cmd)) print(flush=True) check_call(cmd)
def update_version_in_json_used_by_menuinst(build_dir, release_name, package_name, **extra_kwargs): chdir(build_dir) version = short(release_name) menuinst_file = join('condarecipe', package_name, 'larray-editor.json') with open(menuinst_file) as mf: data = json.load(mf) menu_items = data['menu_items'] for i, menu_item in enumerate(menu_items): if 'webbrowser' in menu_item: menu_items[i][ 'webbrowser'] = f'http://larray.readthedocs.io/en/{version}' with open(menuinst_file, mode='w') as mf: json.dump(data, mf, indent=4) # check and add to next commit print(echocall(['git', 'diff', menuinst_file])) if no('Do the version update changes look right?'): exit(1) doechocall('Adding', ['git', 'add', menuinst_file])
def create_source_archive(build_dir, package_name, release_name, rev, **extra_kwargs): chdir(build_dir) archive_name = f'..\\{package_name}-{release_name}-src.zip' echocall(['git', 'archive', '--format', 'zip', '--output', archive_name, rev])
def cleanup(tmp_dir, **extra_kwargs): chdir(tmp_dir) rmtree('build')
def push_conda_forge(build_dir, branch, **extra_kwargs): chdir(build_dir) doechocall('Pushing changes to GitHub', ['git', 'push', 'origin', branch])