def finish(name): """ USAGE git-finish [-n/--name= <name>] DESCRIPTION Set the current branch's upstream to point to old, then rename it, substituting the "feature" prefix for "old", so it no longer appears in "git features". """ buf = StringIO() if not name: name = str(git.branch("--show-current")).strip() if re.match("^feature/", name): new_name = re.sub("^feature", "finished", name) click.echo(f"Finishing {name} by renaming it to {new_name}") try: git.branch(u="old", _err_to_out=True, _out=buf) git.branch("-m", name, new_name, _err_to_out=True, _out=buf) git.checkout("master") except sh.ErrorReturnCode: click.echo("Something went wrong!") click.echo(buf.getvalue()) return 1 else: click.echo('Branch name does not start with "feature/"') return 1 return 0
def pull_update(): # Force pull update try: git.branch('-D', 'temp') except GitError: pass git.checkout('-b', 'temp', "origin/deploy") git.branch('-M', 'deploy') os._exit(0)
def _cut_stable_release(layer_list, charm_list, ancillary_list, filter_by_tag, dry_run): """ This will force push each layers master onto the stable branches. PLEASE NOTE: This step should come after each stable branch has been tagged and references a current stable bundle revision. layer_list: YAML spec containing git repos and their upstream/downstream properties charm_list: YAML spec containing git repos and their upstream/downstream properties """ layer_list = yaml.safe_load(Path(layer_list).read_text(encoding="utf8")) charm_list = yaml.safe_load(Path(charm_list).read_text(encoding="utf8")) ancillary_list = yaml.safe_load( Path(ancillary_list).read_text(encoding="utf8")) new_env = os.environ.copy() for layer_map in layer_list + charm_list + ancillary_list: for layer_name, repos in layer_map.items(): downstream = repos["downstream"] if not repos.get("needs_stable", True): continue tags = repos.get("tags", None) if tags: if not any(match in filter_by_tag for match in tags): continue log.info( f"Releasing :: {layer_name:^35} :: from: master to: stable") if not dry_run: downstream = f"https://{new_env['CDKBOT_GH_USR']}:{new_env['CDKBOT_GH_PSW']}@github.com/{downstream}" identifier = str(uuid.uuid4()) os.makedirs(identifier) for line in git.clone(downstream, identifier, _iter=True): log.info(line) git_rev_master = git("rev-parse", "origin/master", _cwd=identifier).stdout.decode() git_rev_stable = git("rev-parse", "origin/stable", _cwd=identifier).stdout.decode() if git_rev_master == git_rev_stable: log.info( f"Skipping :: {layer_name:^35} :: master == stable") continue git.config("user.email", "*****@*****.**", _cwd=identifier) git.config("user.name", "cdkbot", _cwd=identifier) git.config("--global", "push.default", "simple") git.branch("-f", "stable", "master", _cwd=identifier) for line in git.push("-f", "origin", "stable", _cwd=identifier, _iter=True): log.info(line)
def feature(ticket, project_directory, name): """ USAGE git-feature <ticket> <project folder> <name> DESCRIPTION Create a new GIT branch, tracking master, and setting upstream, named following the pattern 'feature/<ticket>__<project folder>__<name>'. Other git-tools tools will look for names following this pattern. Spaces in <name> will be replaced with dashes. """ name__interspersed_dashes = "-".join(re.split(r"\s+", name)) br_name = f"feature/{ticket}__{project_directory}__{name__interspersed_dashes}" click.echo(f"Calling git-feature to create {br_name}") try: print(git.checkout("master", _err_to_out=True)) print(sh.jira.view(ticket)) print(git.checkout("-t", "-b", br_name, _err_to_out=True)) print(git.branch("--set-upstream-to=master", _err_to_out=True)) except sh.ErrorReturnCode as e: click.echo(f"Something went wrong!\n\nException: {e}") return 1 return 0
# All configuration values have a default; values that are commented out # serve to show the default. from subprocess import call from sh.contrib import git import urllib.request from urllib.error import HTTPError from recommonmark.parser import CommonMarkParser import sys import re import os, subprocess import shlex import guzzle_sphinx_theme git_branch = [ re.sub(r'origin/', '', x.lstrip(' ')) for x in str( git.branch('-r', '--contains', 'HEAD')).rstrip('\n').split('\n') ] git_branch = [x for x in git_branch if 'HEAD' not in x] print('git_branch = {}'.format(git_branch[0])) try: filename, _ = urllib.request.urlretrieve( 'https://s3-us-west-2.amazonaws.com/xgboost-docs/{}.tar.bz2'.format( git_branch[0])) call( 'if [ -d tmp ]; then rm -rf tmp; fi; mkdir -p tmp/jvm; cd tmp/jvm; tar xvf {}' .format(filename), shell=True) except HTTPError: print('JVM doc not found. Skipping...') # If extensions (or modules to document with autodoc) are in another directory,
# autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. from subprocess import call from sh.contrib import git import urllib.request from urllib.error import HTTPError from recommonmark.parser import CommonMarkParser import sys import re import os, subprocess import shlex import guzzle_sphinx_theme git_branch = [re.sub(r'origin/', '', x.lstrip(' ')) for x in str(git.branch('-r', '--contains', 'HEAD')).rstrip('\n').split('\n')] git_branch = [x for x in git_branch if 'HEAD' not in x] print('git_branch = {}'.format(git_branch[0])) try: filename, _ = urllib.request.urlretrieve('https://s3-us-west-2.amazonaws.com/xgboost-docs/{}.tar.bz2'.format(git_branch[0])) call('if [ -d tmp ]; then rm -rf tmp; fi; mkdir -p tmp/jvm; cd tmp/jvm; tar xvf {}'.format(filename), shell=True) except HTTPError: print('JVM doc not found. Skipping...') # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__))) libpath = os.path.join(curr_path, '../python-package/') sys.path.insert(0, libpath) sys.path.insert(0, curr_path)
# Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. from subprocess import call from sh.contrib import git import urllib.request from recommonmark.parser import CommonMarkParser import sys import re import os, subprocess import shlex import guzzle_sphinx_theme git_branch = [re.sub(r'origin/', '', x.lstrip(' ')) for x in str(git.branch('-r', '--contains', 'HEAD')).rstrip('\n').split('\n')] git_branch = [x for x in git_branch if 'HEAD' not in x] print('git_branch = {}'.format(git_branch[0])) filename, _ = urllib.request.urlretrieve('https://s3-us-west-2.amazonaws.com/xgboost-docs/{}.tar.bz2'.format(git_branch[0])) call('if [ -d tmp ]; then rm -rf tmp; fi; mkdir -p tmp/jvm; cd tmp/jvm; tar xvf {}'.format(filename), shell=True) # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__))) libpath = os.path.join(curr_path, '../python-package/') sys.path.insert(0, libpath) sys.path.insert(0, curr_path) # -- mock out modules import mock
def sync_branches(self, repo, bitbucket_account_id, bitbucket_access_token, github_account_id, github_access_token): repo_name = repo['name'] prefixed_repo_name = self.prefix + repo_name github_link = repo['github_link'] bitbucket_link = repo['bitbucket_link'] # Boolean: whether the repo is a new migration to GitHub new_migration = repo['new_migration'] # Use this instead of setting the authenticated link as a new remote. # Remote links get stored in git config github_link_domain = github_link.split("//")[1] authenticated_github_link = f"https://{github_account_id}:{github_access_token}@{github_link_domain}" bitbucket_link_domain = bitbucket_link.split("//")[1] authenticated_bitbucket_link = f"https://{bitbucket_account_id}:{bitbucket_access_token}@{bitbucket_link_domain}" # Set remote to bitbucket git.remote('set-url', 'origin', bitbucket_link) self.log.debug("Syncing branches. Set origin to Bitbucket", repo_name=repo_name, bitbucket_link=bitbucket_link) # Fetch branches from origin (bitbucket) self.log.info("Fetching refs (branches) from origin", repo_name=repo_name) # git.fetch('origin') git.fetch(authenticated_bitbucket_link) self.log.debug("Fetched refs (branches) from BitBucket", result="SUCCESS", repo_name=repo_name) # List remote branches remote_branches = git.branch("-r").split("\n") remote_branches = [ remote.lstrip().rstrip() for remote in remote_branches if (remote and not re.match("^.*/HEAD -> .*$", remote)) ] try: # if master exists on origin, move that to the start of the array # pushing 'master' first makes it the default branch on github remote_branches.remove('origin/master') remote_branches = ['origin/master'] + remote_branches except Exception: # 'master' did not exist on origin pass success_branches = [] failed_branches = [] # Push changes to each branch individually, log error if any fails and continue to next branch for remote in remote_branches: [remote_name, branch_name] = remote.split('/', 1) self.log.info("Syncing branch for repository", repo_name=repo_name, branch_name=branch_name) if (remote_name == 'origin'): # Different way to handle master branches, support prefixing. if (branch_name == "master"): master_branch_refspecs = [] prefix_exists = self.master_branch_prefix != "" if (prefix_exists): # Order is IMPORTANT, 'master' should be added before prefixed_master. # Default branch is the first branch that is pushed to GitHub if (new_migration): master_branch_refspecs.append( f"refs/remotes/origin/{branch_name}:refs/heads/{branch_name}" ) prefixed_master_branch_name = self.master_branch_prefix + branch_name master_branch_refspecs.append( f"refs/remotes/origin/{branch_name}:refs/heads/{prefixed_master_branch_name}" ) else: master_branch_refspecs.append( f"refs/remotes/origin/{branch_name}:refs/heads/{branch_name}" ) for branch_refspec in master_branch_refspecs: target_branch_name = branch_refspec.split('/')[-1] try: self.log.info( "Pushing branch for repository", repo_name=prefixed_repo_name, repo_prefix=self.prefix, branch_name=branch_name, target_branch_name=target_branch_name) git.push(authenticated_github_link, branch_refspec) # Success on syncing current branch self.log.debug( "Successfully synced branch for repository", result="SUCCESS", repo_name=prefixed_repo_name, repo_prefix=self.prefix, branch_name=branch_name, target_branch_name=target_branch_name) success_branches.append(branch_name) except ErrorReturnCode as e: # Redact or remove the access token before logging stderr = utils.StringUtils.redact_error( e.stderr, github_access_token, "<ACCESS-TOKEN>") self.log.error( "Failed to push changes to origin branch", result="FAILED", repo_name=prefixed_repo_name, repo_prefix=self.prefix, branch_name=branch_name, target_branch_name=target_branch_name, exit_code=e.exit_code, stderr=stderr) failed_branches.append(branch_name) continue # Continue to the next master_branch_refspec continue # Continue to the next branch branch_refspec = f"refs/remotes/origin/{branch_name}:refs/heads/{branch_name}" try: self.log.info("Pushing branch for repository", repo_name=prefixed_repo_name, repo_prefix=self.prefix, branch_name=branch_name, target_branch_name=branch_name) git.push(authenticated_github_link, branch_refspec) # Success on syncing current branch self.log.debug("Successfully synced branch for repository", result="SUCCESS", repo_name=prefixed_repo_name, repo_prefix=self.prefix, branch_name=branch_name, target_branch_name=branch_name) success_branches.append(branch_name) except ErrorReturnCode as e: # Redact or remove the access token before logging stderr = utils.StringUtils.redact_error( e.stderr, github_access_token, "<ACCESS-TOKEN>") self.log.error("Failed to push changes to origin branch", result="FAILED", repo_name=prefixed_repo_name, repo_prefix=self.prefix, branch_name=branch_name, target_branch_name=branch_name, exit_code=e.exit_code, stderr=stderr) failed_branches.append(branch_name) continue else: continue all_remote_branches = [ branch_name.split('origin/')[1] for branch_name in remote_branches ] branches_sync_success = set(all_remote_branches) == set( success_branches) return branches_sync_success, all_remote_branches, failed_branches