def run_append(args): # Print info and ask for confirmation. pivotal.prompt_user_to_confirm_release(args.version) # Merge, push and insert PT labels. gitflow = GitFlow() git = gitflow.git current_branch = gitflow.repo.active_branch develop = gitflow.develop_name() gitflow.name_or_current('release', args.version) release = gitflow.get_prefix('release') + str(args.version) print('') sys.stdout.write('Merging develop into ' + release + ' ... ') gitflow.checkout('release', str(args.version)) git.merge(gitflow.develop_name()) print('OK') sys.stdout.write('Pushing ' + release + ' ... ') gitflow.origin().push([release]) print('OK') sys.stdout.write('Moving back to ' + str(current_branch) + ' ... ') current_branch.checkout() print('OK') sys.stdout.write('Marking Pivotal Tracker stories ... ') pivotal.start_release(args.version) print('OK')
def run_finish(args): gitflow = GitFlow() repo = gitflow.repo git = repo.git f_prefix = gitflow.get_prefix('feature') name = gitflow.nameprefix_or_current('feature', args.nameprefix) full_name = f_prefix + name #+++ PT story stuff sys.stdout.write('Getting data from Pivotal Tracker ... ') story_id = pivotal.get_story_id_from_branch_name('feature', name) story = pivotal.Story(story_id) release = story.get_release() print 'OK' # Decide on the upstream branch. if release: # Merge into the release branch. r_prefix = gitflow.get_prefix('release') short_name = gitflow.nameprefix_or_current('release', release) upstream = r_prefix + short_name else: # Merge into the develop branch. upstream = gitflow.develop_name() # Fail as soon as possible if something is not right so that we don't # get Pivotal Tracker into an inconsistent state. rev_range = [get_feature_ancestor(full_name, upstream), repo.commit(full_name).hexsha] #+++ Git manipulation sys.stdout.write('Finishing feature branch ... upstream %s ... ' \ % upstream) gitflow.finish('feature', name, upstream=upstream, fetch=True, rebase=args.rebase, keep=True, force_delete=args.force_delete, tagging_info=None, push=(not args.no_push)) print 'OK' #+++ Review Request if not args.no_review: sys.stdout.write('Posting review ... upstream %s ... ' % upstream) review = BranchReview.from_identifier('feature', name, rev_range) review.post(story, summary_from_story=(not args.summary_from_commit)) print('OK') sys.stdout.write('Posting code review url into Pivotal Tracker ... ') comment = 'New patch was uploaded into Review Board: ' + review.get_url() story.add_comment(comment) print('OK') #+++ Finish PT story sys.stdout.write('Updating Pivotal Tracker ... ') if story.is_finished(): sys.stdout.write('story already finished, skipping ... ') else: sys.stdout.write('finishing %s ... ' % story.get_id()) story.finish() print 'OK'
def test_custom_branchnames(self): gitflow = GitFlow(self.repo).init() self.assertEquals('production', gitflow.master_name()) self.assertEquals('master', gitflow.develop_name()) self.assertEquals('origin', gitflow.origin_name()) self.assertEquals('f-', gitflow.get_prefix('feature')) self.assertEquals('rel-', gitflow.get_prefix('release')) self.assertEquals('hf-', gitflow.get_prefix('hotfix')) self.assertEquals('supp-', gitflow.get_prefix('support')) self.assertEquals('v', gitflow.get_prefix('versiontag'))
def test_gitflow_init_initializes_default_config(self): repo = create_git_repo(self) gitflow = GitFlow(repo).init() self.assertEquals('master', gitflow.master_name()) self.assertEquals('develop', gitflow.develop_name()) self.assertEquals('origin', gitflow.origin_name()) self.assertEquals('feature/', gitflow.get_prefix('feature')) self.assertEquals('hotfix/', gitflow.get_prefix('hotfix')) self.assertEquals('release/', gitflow.get_prefix('release')) self.assertEquals('support/', gitflow.get_prefix('support')) self.assertEquals('', gitflow.get_prefix('versiontag'))
def test_gitflow_init_config_with_partly_inited(self): gitflow = GitFlow(self.repo).init() # Already set in fixture, shouldn't change self.assertEquals('production', gitflow.master_name()) self.assertEquals('f-', gitflow.get_prefix('feature')) # Implicit defaults self.assertEquals('develop', gitflow.develop_name()) self.assertEquals('origin', gitflow.origin_name()) self.assertEquals('release/', gitflow.get_prefix('release')) self.assertEquals('hotfix/', gitflow.get_prefix('hotfix')) self.assertEquals('support/', gitflow.get_prefix('support')) self.assertEquals('', gitflow.get_prefix('versiontag'))
def test_gitflow_force_reinit_partly_inited(self): gitflow = GitFlow(self.repo) gitflow.init(force_defaults=True) # Implicit defaults self.assertEquals('develop', gitflow.develop_name()) self.assertEquals('origin', gitflow.origin_name()) self.assertEquals('release/', gitflow.get_prefix('release')) self.assertEquals('hotfix/', gitflow.get_prefix('hotfix')) self.assertEquals('support/', gitflow.get_prefix('support')) self.assertEquals('', gitflow.get_prefix('versiontag')) # Explicitly forced back to defaults self.assertEquals('master', gitflow.master_name()) self.assertEquals('feature/', gitflow.get_prefix('feature'))
def test_gitflow_init_with_alternative_config(self): repo = create_git_repo(self) gitflow = GitFlow(repo) prefixes = dict(feature='f-', hotfix='hf-', release='rel-', support='supp-', versiontag='ver') names = dict(origin='somewhereelse') gitflow.init(master='foo', develop='bar', prefixes=prefixes, names=names) self.assertEquals('foo', gitflow.master_name()) self.assertEquals('bar', gitflow.develop_name()) self.assertEquals('somewhereelse', gitflow.origin_name()) self.assertEquals('f-', gitflow.get_prefix('feature')) self.assertEquals('rel-', gitflow.get_prefix('release')) self.assertEquals('hf-', gitflow.get_prefix('hotfix')) self.assertEquals('supp-', gitflow.get_prefix('support')) self.assertEquals('ver', gitflow.get_prefix('versiontag'))
def _run_deploy(args): assert args.environ if args.environ in ('qa', 'client'): assert args.version gitflow = GitFlow() branches = { 'develop': gitflow.develop_name(), 'qa': gitflow.managers['release'].full_name(args.version), 'production': gitflow.master_name(), } if gitflow.is_circleci_enabled(): branches['client'] = gitflow.client_name() _deploy_circleci(gitflow, branches, args.environ) else: branches['client'] = gitflow.managers['release'].full_name(args.version) _deploy_jenkins(gitflow, branches, args.environ)
def run_start(args): gitflow = GitFlow() base = gitflow.develop_name() #+ Pivotal Tracker modifications. pivotal.prompt_user_to_confirm_release(args.version) #+ Git modifications. sys.stdout.write('Creating release branch (base being %s) ... ' \ % base) try: branch = gitflow.create('release', args.version, base, fetch=(not args.no_fetch)) except BranchExistsError: sys.stdout.write('branch already exists ... ') except (NotInitialized, BranchTypeExistsError, BaseNotOnBranch): # printed in main() raise except Exception, e: die("could not create release branch %r" % args.version, e)
def _run_deploy(args): assert args.environ if args.environ in ('qa', 'client'): assert args.version gitflow = GitFlow() branches = { 'develop': gitflow.develop_name(), 'qa': gitflow.managers['release'].full_name(args.version), 'production': gitflow.master_name(), } if gitflow.is_circleci_enabled(): branches['client'] = gitflow.client_name() _deploy_circleci(gitflow, branches, args.environ) else: branches['client'] = gitflow.managers['release'].full_name( args.version) _deploy_jenkins(gitflow, branches, args.environ)
def run_finish(args): gitflow = GitFlow() git = gitflow.git origin = gitflow.origin() version = gitflow.name_or_current('release', args.version) #+++ Check if all stories were QA'd pt_release = pivotal.Release(args.version) print('Checking Pivotal Tracker stories ... ') pt_release.try_finish() print('OK') #+++ Check all relevant review requests in Review Board, to be sure rb_release = review.Release(pt_release) print('Checking Review Board review requests ... ') rb_release.try_finish(args.ignore_missing_reviews) print('OK') #+++ Merge release branch into develop and master sys.stdout.write('Merging release branch %s ... ' % version) tagging_info = None if not args.notag: tagging_info = dict( sign=args.sign or args.signingkey, signingkey=args.signingkey, message=args.message) gitflow.finish('release', version, fetch=(not args.no_fetch), rebase=False, keep=True, force_delete=False, tagging_info=tagging_info, push=False) print('OK') #+++ Close all relevant review requests sys.stdout.write('Submitting all relevant review requests ... ') rb_release.finish() print('OK') #+++ Collect local and remote branches to be deleted sys.stdout.write('Collecting branches to be deleted ... ') local_branches = list() remote_branches = list() #+ Collect features to be deleted. origin_prefix = str(origin) + '/' feature_prefix = gitflow.get_prefix('feature') # refs = [<type>/<id>/...] refs = [str(ref)[len(origin_prefix):] for ref in origin.refs] for story in pt_release: if story.is_rejected(): continue # prefix = <feature-prefix>/<id> prefix = feature_prefix + str(story.get_id()) base_marker = gitflow.managers['feature'].base_marker_name(prefix) try: name = gitflow.nameprefix_or_current('feature', prefix) local_branches.append(feature_prefix + name) if base_marker in gitflow.repo.refs: local_branches.append(base_marker) except NoSuchBranchError: pass for ref in refs: # if <feature-prefix>/... startswith <feature-prefix>/<id> if ref.startswith(prefix) or ref == base_marker: remote_branches.append(ref) #+ Collect releases to be deleted. if not args.keep: release_branch = gitflow.get_prefix('release') + version try: gitflow.name_or_current('release', version) local_branches.append(release_branch) except NoSuchBranchError: pass if release_branch in refs: remote_branches.append(release_branch) print 'OK' #+++ Delete local and remote branches that are a part of this release sys.stdout.write('Checking out %s ... ' % gitflow.develop_name()) git.checkout(gitflow.develop_name()) print 'OK' #+ Delete local branches. print 'Deleting local branches ...' for branch in local_branches: git.branch('-D', branch) print ' ' + branch print ' OK' #+ Delete remote branches. print 'Deleting remote branches and pushing the rest ...' for branch in remote_branches: print ' ' + branch refspecs = [(':' + b) for b in remote_branches] refspecs.append(gitflow.develop_name()) refspecs.append(gitflow.master_name()) git.push(str(origin), '--tags', *refspecs) print ' OK'
def run_finish(args): gitflow = GitFlow() git = gitflow.git origin = gitflow.origin() version = gitflow.name_or_current('release', args.version) #+++ Check if all stories were QA'd pt_release = pivotal.Release(args.version) print('Checking Pivotal Tracker stories ... ') pt_release.try_finish() print('OK') #+++ Check all relevant review requests in Review Board, to be sure rb_release = review.Release(pt_release) print('Checking Review Board review requests ... ') rb_release.try_finish(args.ignore_missing_reviews) print('OK') #+++ Merge release branch into develop and master sys.stdout.write('Merging release branch %s ... ' % version) tagging_info = None if not args.notag: tagging_info = dict(sign=args.sign or args.signingkey, signingkey=args.signingkey, message=args.message) gitflow.finish('release', version, fetch=(not args.no_fetch), rebase=False, keep=True, force_delete=False, tagging_info=tagging_info, push=False) print('OK') #+++ Close all relevant review requests sys.stdout.write('Submitting all relevant review requests ... ') rb_release.finish() print('OK') #+++ Collect local and remote branches to be deleted sys.stdout.write('Collecting branches to be deleted ... ') local_branches = list() remote_branches = list() #+ Collect features to be deleted. origin_prefix = str(origin) + '/' feature_prefix = gitflow.get_prefix('feature') # refs = [<type>/<id>/...] refs = [str(ref)[len(origin_prefix):] for ref in origin.refs] for story in pt_release: if story.is_rejected(): continue # prefix = <feature-prefix>/<id> prefix = feature_prefix + str(story.get_id()) base_marker = gitflow.managers['feature'].base_marker_name(prefix) try: name = gitflow.nameprefix_or_current('feature', prefix) local_branches.append(feature_prefix + name) if base_marker in gitflow.repo.refs: local_branches.append(base_marker) except NoSuchBranchError: pass for ref in refs: # if <feature-prefix>/... startswith <feature-prefix>/<id> if ref.startswith(prefix) or ref == base_marker: remote_branches.append(ref) #+ Collect releases to be deleted. if not args.keep: release_branch = gitflow.get_prefix('release') + version try: gitflow.name_or_current('release', version) local_branches.append(release_branch) except NoSuchBranchError: pass if release_branch in refs: remote_branches.append(release_branch) print 'OK' #+++ Delete local and remote branches that are a part of this release sys.stdout.write('Checking out %s ... ' % gitflow.develop_name()) git.checkout(gitflow.develop_name()) print 'OK' #+ Delete local branches. print 'Deleting local branches ...' for branch in local_branches: git.branch('-D', branch) print ' ' + branch print ' OK' #+ Delete remote branches. print 'Deleting remote branches and pushing the rest ...' for branch in remote_branches: print ' ' + branch refspecs = [(':' + b) for b in remote_branches] refspecs.append(gitflow.develop_name()) refspecs.append(gitflow.master_name()) git.push(str(origin), '--tags', *refspecs) print ' OK'
def run_finish(args): gitflow = GitFlow() repo = gitflow.repo git = repo.git f_prefix = gitflow.get_prefix('feature') name = gitflow.nameprefix_or_current('feature', args.nameprefix) full_name = f_prefix + name #+++ PT story stuff sys.stdout.write('Getting data from Pivotal Tracker ... ') story_id = pivotal.get_story_id_from_branch_name('feature', name) story = pivotal.Story(story_id) release = story.get_release() print 'OK' # Decide on the upstream branch. if release: # Merge into the release branch. r_prefix = gitflow.get_prefix('release') short_name = gitflow.nameprefix_or_current('release', release) upstream = r_prefix + short_name else: # Merge into the develop branch. upstream = gitflow.develop_name() # Fail as soon as possible if something is not right so that we don't # get Pivotal Tracker into an inconsistent state. rev_range = [ get_feature_ancestor(full_name, upstream), repo.commit(full_name).hexsha ] #+++ Git manipulation sys.stdout.write('Finishing feature branch ... upstream %s ... ' \ % upstream) gitflow.finish('feature', name, upstream=upstream, fetch=True, rebase=args.rebase, keep=True, force_delete=args.force_delete, tagging_info=None, push=(not args.no_push)) print 'OK' #+++ Review Request if not args.no_review: sys.stdout.write('Posting review ... upstream %s ... ' % upstream) review = BranchReview.from_identifier('feature', name, rev_range) review.post(story, summary_from_story=(not args.summary_from_commit)) print('OK') sys.stdout.write( 'Posting code review url into Pivotal Tracker ... ') comment = 'New patch was uploaded into Review Board: ' + review.get_url( ) story.add_comment(comment) print('OK') #+++ Finish PT story sys.stdout.write('Updating Pivotal Tracker ... ') if story.is_finished(): sys.stdout.write('story already finished, skipping ... ') else: sys.stdout.write('finishing %s ... ' % story.get_id()) story.finish() print 'OK'