def deploy(app_id, version, promote, quiet): # type: (str, str, bool, bool) -> None """ Deploy the app to AppEngine. Args: app_id (str): AppEngine App ID. Overrides config value app_id if given. version (str): AppEngine project version. Overrides config values if given. promote (bool): If set to **True** promote the current remote app version to the one that's being deployed. quiet (bool): If set to **True** this will pass the ``--quiet`` flag to gcloud command. """ gae_app = GaeApp.for_branch(git.current_branch().name) if gae_app is None and None in (app_id, version): msg = ("Can't find an AppEngine app setup for branch <35>{}<32> and" "--project and --version were not given.") log.err(msg, git.current_branch().name) sys.exit(1) if version is not None: gae_app.version = version if app_id is not None: gae_app.app_id = app_id gae_app.deploy(promote, quiet)
def test_calls_git_cli(p_run): util.cached_result.clear(git.current_branch) git.current_branch().name p_run.assert_called_once_with('git symbolic-ref --short HEAD', capture=True, never_pretend=True)
def finish(fast_forward: bool): """ Merge current feature branch into develop. """ pretend = context.get('pretend', False) if not pretend and (git.staged() or git.unstaged()): log.err("You have uncommitted changes in your repo!\n" "You need to stash them before you merge the feature branch") sys.exit(1) develop = conf.get('git.devel_branch', 'develop') branch = git.current_branch(refresh=True) common.assert_branch_type('feature') hooks.register.call('pre-feature-finish', branch) # Merge feature into develop common.git_checkout(develop) common.git_pull(develop) common.git_merge(develop, branch.name, no_ff=not fast_forward) # Cleanup common.git_branch_delete(branch.name) common.git_prune() common.git_checkout(develop) hooks.register.call('post-feature-finish', branch)
def merged(): """ Cleanup the release branch after it was remotely merged to master. """ develop = conf.get('git.devel_branch', 'develop') master = conf.get('git.master_branch', 'master') branch = git.current_branch(refresh=True) common.assert_branch_type('release') hooks.register.call('pre-release-merged', branch) # Pull master with the merged release common.git_checkout(master) common.git_pull(master) # Merge to develop common.git_checkout(develop) common.git_pull(develop) common.git_merge(develop, branch.name) # Cleanup common.git_branch_delete(branch.name) common.git_prune() common.git_checkout(develop) hooks.register.call('post-release-merged', branch)
def git_merge(base: str, head: str, no_ff: bool = False): """ Merge *head* into *base*. Args: base (str): The base branch. *head* will be merged into this branch. head (str): The branch that will be merged into *base*. no_ff (bool): If set to **True** it will force git to create merge commit. If set to **False** (default) it will do a fast-forward merge if possible. """ pretend = context.get('pretend', False) branch = git.current_branch(refresh=True) if branch.name != base and not pretend: git_checkout(base) args = [] if no_ff: args.append('--no-ff') log.info("Merging <33>{}<32> into <33>{}<32>", head, base) shell.run('git merge {args} {branch}'.format( args=' '.join(args), branch=head, )) if branch.name != base and not pretend: git_checkout(branch.name)
def finish(fast_forward: bool): """ Merge current feature branch into develop. """ pretend = context.get('pretend', False) if not pretend and (git.staged() or git.unstaged()): log.err("You have uncommitted changes in your repo!\n" "You need to stash them before you merge the hotfix branch") sys.exit(1) branch = git.current_branch(refresh=True) base = common.get_base_branch() prompt = "<32>Merge <33>{}<32> into <33>{}<0>?".format(branch.name, base) if not click.confirm(shell.fmt(prompt)): log.info("Cancelled") return common.assert_branch_type('task') hooks.register.call('pre-task-finish', branch, base) # Merge task into it's base feature branch common.git_checkout(base) common.git_pull(base) common.git_merge(base, branch.name, no_ff=not fast_forward) # Cleanup common.git_branch_delete(branch.name) common.git_prune() common.git_checkout(base) hooks.register.call('post-task-finish', branch, base)
def delete_remote(): """ Delete the current branch on origin. This is an equivalent of ``git push origin :<branch>``. Easy way to quickly delete the remote branch without having to type in the branch name. """ branch = git.current_branch().name shell.run('git push -u origin {}'.format(branch))
def push(): """ Push the current branch to origin. This is an equivalent of ``git push -u origin <branch>``. Mainly useful for the first push as afterwards ``git push`` is just quicker. Free's you from having to manually type the current branch name in the first push. """ branch = git.current_branch().name shell.run('git push -u origin {}'.format(branch))
def git_branch_rename(new_name: str): """ Rename the current branch Args: new_name (str): New name for the current branch. """ curr_name = git.current_branch(refresh=True).name if curr_name not in git.protected_branches(): log.info("Renaming branch from <33>{}<32> to <33>{}".format( curr_name, new_name)) shell.run('git branch -m {}'.format(new_name))
def update(): """ Update the feature with updates committed to develop. This will merge current develop into the current branch. """ branch = git.current_branch(refresh=True) develop = conf.get('git.devel_branch', 'develop') common.assert_branch_type('feature') common.git_checkout(develop) common.git_pull(develop) common.git_checkout(branch.name) common.git_merge(branch.name, develop)
def update(): """ Update the feature with updates committed to develop. This will merge current develop into the current branch. """ branch = git.current_branch(refresh=True) base_branch = common.get_base_branch() common.assert_branch_type('task') common.git_checkout(base_branch) common.git_pull(base_branch) common.git_checkout(branch.name) common.git_merge(branch.name, base_branch)
def assert_on_branch(branch_name: str): """ Print error and exit if *branch_name* is not the current branch. Args: branch_name (str): The supposed name of the current branch. """ branch = git.current_branch(refresh=True) if branch.name != branch_name: if context.get('pretend', False): log.info("Would assert that you're on a <33>{}<32> branch", branch_name) else: log.err("You're not on a <33>{}<31> branch!", branch_name) sys.exit(1)
def start(name: str): """ Start working on a new feature by branching off develop. This will create a new branch off develop called feature/<name>. Args: name (str): The name of the new feature. """ branch = git.current_branch(refresh=True) task_branch = 'task/' + common.to_branch_name(name) if branch.type not in ('feature', 'hotfix'): log.err("Task branches can only branch off <33>feature<32> or " "<33>hotfix<32> branches") sys.exit(1) hooks.register.call('pre-task-start', name) common.git_checkout(task_branch, create=True) hooks.register.call('post-task-start', name)
def merged(): """ Cleanup a remotely merged branch. """ base_branch = common.get_base_branch() branch = git.current_branch(refresh=True) common.assert_branch_type('task') hooks.register.call('pre-task-merged', branch, base_branch) # Pull feature branch with the merged task common.git_checkout(base_branch) common.git_pull(base_branch) # Cleanup common.git_branch_delete(branch.name) common.git_prune() common.git_checkout(base_branch) hooks.register.call('post-task-merged', branch, base_branch)
def merged(): """ Cleanup a remotely merged branch. """ develop = conf.get('git.devel_branch', 'develop') branch = git.current_branch(refresh=True) common.assert_branch_type('feature') hooks.register.call('pre-feature-merged', branch) # Pull develop with the merged feature common.git_checkout(develop) common.git_pull(develop) # Cleanup common.git_branch_delete(branch.name) common.git_prune() common.git_checkout(develop) hooks.register.call('post-feature-merged', branch)
def assert_branch_type(branch_type: str): """ Print error and exit if the current branch is not of a given type. Args: branch_type (str): The branch type. This assumes the branch is in the '<type>/<title>` format. """ branch = git.current_branch(refresh=True) if branch.type != branch_type: if context.get('pretend', False): log.info("Would assert that you're on a <33>{}/*<32> branch", branch_type) else: log.err("Not on a <33>{}<31> branch!", branch_type) fmt = ("The branch must follow <33>{required_type}/<name><31>" "format and your branch is called <33>{name}<31>.") log.err(fmt, required_type=branch_type, name=branch.name) sys.exit(1)
def app_version(self): # type: () -> str """ AppEngine compatible app version. This assumes git-flow branching strategy and has a few predefined ways to automatically generate the version string. """ branch = git.current_branch() if self.version is not None: return self.version elif branch.type == 'develop': return '{ver}-c{commit_nr}-{commit_id}'.format( ver=versioning.current().replace('.', '-'), commit_nr=git.latest_commit().number, commit_id=git.latest_commit().id) elif branch.type in ('feature', 'hotfix', 'task'): # We don't need version when we have the title. return branch.title.replace('_', '-') return versioning.current().replace('.', '-')
def finish(fast_forward: bool): """ Merge current release into develop and master and tag it. """ pretend = context.get('pretend', False) if not pretend and (git.staged() or git.unstaged()): log.err("You have uncommitted changes in your repo!\n" "You need to stash them before you merge the release branch") sys.exit(1) develop = conf.get('git.devel_branch', 'develop') master = conf.get('git.master_branch', 'master') branch = git.current_branch(refresh=True) common.assert_branch_type('release') hooks.register.call('pre-release-finish', branch) # Merge release into master common.git_checkout(develop) common.git_pull(develop) common.git_merge(develop, branch.name, no_ff=not fast_forward) # Merge release into develop common.git_checkout(master) common.git_pull(master) common.git_merge(master, branch.name, no_ff=not fast_forward) # Tag the release commit with version number tag(changelog()) # Cleanup common.git_branch_delete(branch.name) common.git_prune() common.git_checkout(master) hooks.register.call('post-release-finish', branch)
def test_strips_output_from_git_porcelain(): util.cached_result.clear(git.current_branch) assert git.current_branch().name == 'test'
def test_works_as_expected(p_run): git.current_branch().name() p_run.assert_called_once_with('git symbolic-ref --short HEAD', capture=True, never_pretend=True)