def build(): """Build the code to prepare for release. """ # Check that long-description.txt is a valid ReST file (otherwise, the PyPI # page won't display correctly). readme = 'doc/long-description.txt' error_start = 'Docutils System Messages\n' with open(readme, 'r') as rstfile: parsed = publish_string(rstfile.read()) if error_start in parsed: print("Errors in " + readme) util.delayed_exit() # Run other setup tests. if setup.check('-rms').exit_code: print("The setup.py check failed.") util.delayed_exit() # Get the new version number. commit = git('rev-list', '--tags', '--max-count=1').stdout.rstrip() lastversion = git.describe('--tags', commit).stdout.rstrip().lstrip('v') # This is simpler but doesn't always return the latest tag: # lastversion = git.describe('--tag', abbrev=0).stdout.rstrip() version = raw_input("Enter the version number (last was %s): " % lastversion) # Tag the version (will prompt for message). git.tag('-af', 'v' + version) # Update the version number. # In CHANGES.txt: date = strftime('%Y-%-m-%-d') rpls = [(r'TBD.*( -- Updates:)', r'v{v}_ ({d})\1'.format(v=version, d=date)), (r'v%s_ \(.+\)( -- Updates:)' % version, r'v{v}_ ({d})\1'.format(v=version, d=date)), (r'(.. _)vx\.x\.x(.+)vx\.x\.x(\.zip)', r'\1v{v}\2v{v}\3'.format(v=version))] util.replace('CHANGES.txt', rpls) # Note that versioneer automatically handles the version number in # natu/__init__.py. # Build, install, and test the code. setup.build() os.system('sudo python setup.py install') os.system('sudo python3 setup.py install') os.system('python setup.py test') os.system('python3 setup.py test') # Create a tarball and zip (*.tar.gz and *.zip). setup.sdist(formats='gztar,zip')
def main(): """Script body""" app_dir = join(dirname(abspath(__file__)), '..') sys.path.append(app_dir) from carto_renderer import version # pylint: disable=import-error cur_version = version.SEMANTIC if not cur_version.endswith('-SNAPSHOT'): raise ValueError('Not a SNAPSHOT version!') default_release = cur_version.replace('-SNAPSHOT', '') pytest.main(app_dir) release_version = prompt( 'Release version [{ver}]: '.format(ver=default_release), r'^\d+[.]\d+[.]\d+$', 'Release version should be Major.Minor.Patch!', default_release) split_version = [int(i) for i in release_version.split('.')] split_version[2] += 1 default_next = '.'.join([str(s) for s in split_version]) + '-SNAPSHOT' next_version = prompt( 'Next version [' + default_next + ']: ', r'^\d+[.]\d+[.]\d+-SNAPSHOT$', 'Not a valid SNAPSHOT version!', default_next) ver_file = join(app_dir, 'carto_renderer', 'version.py') set_version(ver_file, cur_version, release_version) git.add(ver_file) git.commit('-m', 'Setting version to ' + release_version) git.tag('v' + release_version) set_version(ver_file, release_version, next_version) git.add(ver_file) git.commit('-m' 'Setting version to ' + next_version) do_push = prompt('Push changes to the remote repository (y/n)? [y]: ', '.*', None, 'y') if do_push.lower().startswith('y'): print(git.push()) print(git.push('--tags'))
def _get_next_tags(): maxv=[0,0,0] rever=re.compile(r'^\s*v(\d+)\.(\d+)\.(\d+)\s*$') for tag in git.tag(l='v*.*.*'): ver = rever.match(tag) if ver: maxv = max(maxv,map(int,ver.groups())) maxv[2] += 1 return maxv
def main(): """Script body""" app_dir = join(dirname(abspath(__file__)), '..') sys.path.append(app_dir) from carto_renderer import version # pylint: disable=import-error cur_version = version.SEMANTIC if not cur_version.endswith('-SNAPSHOT'): raise ValueError('Not a SNAPSHOT version!') default_release = cur_version.replace('-SNAPSHOT', '') pytest.main(app_dir) release_version = prompt( 'Release version [{ver}]: '.format(ver=default_release), r'^\d+[.]\d+[.]\d+$', 'Release version should be Major.Minor.Patch!', default_release) split_version = [int(i) for i in release_version.split('.')] split_version[2] += 1 default_next = '.'.join([str(s) for s in split_version]) + '-SNAPSHOT' next_version = prompt('Next version [' + default_next + ']: ', r'^\d+[.]\d+[.]\d+-SNAPSHOT$', 'Not a valid SNAPSHOT version!', default_next) ver_file = join(app_dir, 'carto_renderer', 'version.py') set_version(ver_file, cur_version, release_version) git.add(ver_file) git.commit('-m', 'Setting version to ' + release_version) git.tag('v' + release_version) set_version(ver_file, release_version, next_version) git.add(ver_file) git.commit('-m' 'Setting version to ' + next_version) do_push = prompt('Push changes to the remote repository (y/n)? [y]: ', '.*', None, 'y') if do_push.lower().startswith('y'): print(git.push()) print(git.push('--tags'))
def delete(self): git.tag('-d', self.tag_name)
def patch(version, dry_run, gitlab): project = gitlab.projects.get("acts/acts-core") version = split_version(version) milestone = find_milestone(version, project.milestones.list(state="active")) assert (milestone is not None ), f"Didn't find milestone for {version}. Is it closed already?" branches = get_branches() release_branch = "release/v{:d}.{:>02d}.X".format(*version) version_file = Path() / "version_number" tag_name = format_version(version) if release_branch not in branches: print("Release branch", release_branch, "does not exist. I'm bailing") print("Will make new patch version tag %s from milestone %s on branch %s" % (format_version(version), milestone.title, release_branch)) if click.confirm("Do you want to run local preparation?"): with Spinner( text=f"Checkout and update release branch {release_branch}"): if not dry_run: git.checkout(release_branch) assert current_branch() == release_branch git.pull() with Spinner(text=f"Bumping version to {format_version(version)}"): if not dry_run: assert current_branch() == release_branch with version_file.open("w") as fh: fh.write(".".join(map(str, version))) with Spinner( text= f"Committing bumped version on release branch {release_branch}" ): if not dry_run: git.add(str(version_file)) git.commit(message="Bump version to %s" % ".".join(map(str, version))) with Spinner( text=f"Creating local tag {tag_name} on {release_branch}"): if not dry_run: git.tag(tag_name) print(f"You might want to run 'git push REMOTE {tag_name}'") if click.confirm(f"Do you want me to try to push {release_branch}?"): with Spinner(text=f"Pushing {release_branch}"): if not dry_run: git.push() if click.confirm(f"Do you want me to close %{milestone.title}?"): with Spinner(text=f"Closing milestone %{milestone.title}"): if not dry_run: milestone.state_event = "close" milestone.save()
def get_module_tags(path): os.chdir(path) res = git.tag('--points-at', 'HEAD') assert res.exit_code == 0 lines = res.stdout.split('\n') return lines[0]
def tag(obj, tag_name, remote, yes): current_branch = get_current_branch() remote_url = git.remote("get-url", remote).strip() gh, repo = obj tag = split_version(tag_name) tag_name = format_version(tag) major, minor, fix = tag with Spinner(f"Checking for milestone for tag {tag_name}"): tag_milestone = None for ms in repo.get_milestones(state="all"): if ms.title == tag_name: tag_milestone = ms break assert tag_milestone is not None, "Did not find milestone for tag" release_branch_name = f"release/v{major}.{minor:>02}.X" with Spinner("Refreshing branches"): git.fetch(all=True, prune=True) if fix == 0: # new minor release with Spinner(f"Checking out and updating {default_branch_name}"): git.checkout(default_branch_name) git.pull() assert not check_branch_exists( release_branch_name ), "For new minor: release branch CANNOT exist yet" with Spinner(f"Creating {release_branch_name}"): git.checkout("-b", release_branch_name) else: assert check_branch_exists( release_branch_name), "For new fix: release brunch MUST exist" with Spinner(f"Checking out {release_branch_name}"): git.checkout(release_branch_name) # we are not on release branch version_file = Path("version_number") assert version_file.exists(), "Version number file not found" current_version_string = version_file.read_text() print(f"Current version: [bold]{current_version_string}[/bold]") if fix == 0: assert current_version_string == "9.9.9", "Unexpected current version string found" else: assert current_version_string != f"{major}.{minor}.{fix-1}", "Unexpected current version string found" version_string = f"{major}.{minor}.{fix}" with Spinner( f"Bumping version number in '{version_file}' to '{version_string}'" ): with version_file.open("w") as fh: fh.write(version_string) with Spinner("Comitting"): git.add(version_file) git.commit(m=f"Bump version number to {version_string}") with Spinner(f"Creating tag {tag_name}"): git.tag(tag_name) print( f"I will now: push tag [bold green]{tag_name}[/bold green] and branch [bold green]{release_branch_name}[/bold green] to [bold]{remote_url}[/bold]" ) if not confirm("Continue?", yes=yes): raise SystemExit("Aborting") with Spinner(f"Pushing branch {release_branch_name}"): git.push("-u", remote, release_branch_name) with Spinner(f"Pushing tag {tag_name}"): git.push(remote, tag_name)
def push(remote_name, remote_branch, to_be_pushed_branch, commit_hash_list): git.status() current_branch = get_stdout(git('symbolic-ref', '--short', '-q', 'HEAD'))[0:-1] mark_message = '***mark***' # 校验是否tag已存在 tag_name = f"merging({current_branch}-->{remote_name}/{remote_branch})" code, output = subprocess.getstatusoutput(f"git tag | grep '^{tag_name}$'") if code == 0: print(f"错误,tag:{tag_name} 已存在") exit(-1) # 校验远程分支是否存在 code, output = subprocess.getstatusoutput('git fetch') if code != 0: print(output) print("fetch 失败") exit(-1) code, output = subprocess.getstatusoutput( f"git branch -r | cat | grep '^ *{remote_name}/{remote_branch}'") if code != 0: print("错误,远程分支%s不存在" % remote_branch) exit(-1) # 如果工作区不干净,mark提交 res = git.status() is_clean = re.match(".*nothing to commit, working tree clean.*", get_stdout(res), re.S) if not is_clean: print('工作区不干净,mark提交...') git.add('--all') git.commit('-a', '-m', mark_message) # 检出到远程临时分支 tmp_branch = f'tmp/local_{remote_name}_{remote_branch}' print(f'检出到远程临时分支"{tmp_branch}"...') git.checkout('-b', tmp_branch, f'{remote_name}/{remote_branch}') # cherry-pick try: print('开始cherry-pick...') res = git('cherry-pick', commit_hash_list) except sh.ErrorReturnCode_1: print(get_stderr(res)) print("请解决冲突,然后选择后续操作...") while True: operation = input('请输入处理方式') if operation == 0: print('execute: git cherry-pick --continue...') code, output = subprocess.getstatusoutput( 'git cherry-pick --continue') print(output) if code != 0: continue else: print('解决冲突成功') break elif operation == 1: print('退出,停在当前位置') git('check-pick', '--abort') exit(-1) elif operation == 2: print('撤销,回到起点...') git('check-pick', '--abort') # 切换会原来的分支,并去掉mark提交 git.switch(current_branch) git.branch('-D', tmp_branch) de_mark_commit(current_branch, mark_message) exit(-1) else: print('输入不合法,请重新输入') except ErrorReturnCode: print(get_stderr(res)) exit(-1) print('推送中...') git.push('-f', remote_name, f'HEAD:{to_be_pushed_branch}') # 切换会原来的分支,并去掉mark提交 print('切换会原来的分支,并去掉mark提交') git.switch(current_branch) git.branch('-D', tmp_branch) de_mark_commit(current_branch, mark_message) print(f'添加tag"{tag_name}"...') git.tag('-a', tag_name, '-m', "nothing") print('完成!')