def push(repo, branch="master"):
    remote = repo.remotes["origin"]
    remote.credentials = pygit2.UserPass(settings.github_user,
                                         settings.github_token)
    remote.push(
        [f"refs/heads/{branch}"],
        callbacks=pygit2.RemoteCallbacks(credentials=remote.credentials))
예제 #2
0
    def test_user_pass(self):
        credentials = UserPass("libgit2", "libgit2")
        callbacks = pygit2.RemoteCallbacks(credentials=credentials)

        url = "https://bitbucket.org/libgit2/testgitrepository.git"
        remote = self.repo.create_remote("bb", url)
        remote.fetch(callbacks=callbacks)
예제 #3
0
    def test_clone_with_credentials(self):
        url = 'https://github.com/libgit2/TestGitRepository'
        credentials = pygit2.UserPass("libgit2", "libgit2")
        callbacks = pygit2.RemoteCallbacks(credentials=credentials)
        repo = clone_repository(url, self._temp_dir, callbacks=callbacks)

        assert not repo.is_empty
예제 #4
0
    def vgit_push(self, path, message, user_name_commiter, user_name_author,
                  email_commiter, email_author, branch, user_name_pusher,
                  user_passoword_pusher, log_cb):
        try:
            repo = Repository(path)
            index = repo.index
            reference = 'refs/heads/' + branch
            tree = index.write_tree()
            author = pygit2.Signature(user_name_author, email_author)
            commiter = pygit2.Signature(user_name_commiter, email_commiter)
            oid = repo.create_commit(reference, author, commiter, message,
                                     tree, [repo.head.target])
            credentials = pygit2.UserPass(user_name_pusher,
                                          user_passoword_pusher)
            remo = repo.remotes["origin"]
            remo.credentials = credentials
            aux = remo.url
            repo.remotes.set_push_url(user_name_pusher, aux)
            callbacks = pygit2.RemoteCallbacks(credentials=credentials)
            remo.push([reference], callbacks=callbacks)

        except ValueError as err:
            log_cb(str(err))
            return False
        except Exception as err:
            log_cb(str(err))
            return False

        return True
예제 #5
0
파일: main.py 프로젝트: matt-bp/PythonPull
def main():
    """Main entry point to the program"""

    target_dir = input("Please enter target dir > ")
    u_name = input("Please enter github username > ")
    pss_wrd = getpass.getpass(prompt="Please enter github password > ")
    check_interval = input(
        "Please enter desired check interval (seconds)[10] > ")

    if check_interval == "":
        check_interval = 10

    if target_dir == "" or u_name == "" or pss_wrd == "":
        print_help()
        return

    # getting set up for the pull request
    cred = pygit2.UserPass(u_name, pss_wrd)
    callback = pygit2.RemoteCallbacks(credentials=cred)
    repo = pygit2.Repository(target_dir)

    print(f"Watching {target_dir} for updates every {check_interval} seconds.")

    start_time = time.time()
    while True:
        cur_time = time.time()

        if cur_time - start_time >= check_interval:
            print(f"Checking for updates...")

            # initiate the pull
            pull(repo, credentials_callback=callback)

            # reset start time to check new interval
            start_time = time.time()
예제 #6
0
    def test_clone_with_credentials(self):
        repo = clone_repository(
            "https://bitbucket.org/libgit2/testgitrepository.git",
            self._temp_dir,
            callbacks=pygit2.RemoteCallbacks(
                credentials=pygit2.UserPass("libgit2", "libgit2")))

        self.assertFalse(repo.is_empty)
예제 #7
0
def test_keypair(tmp_path, pygit2_empty_key):
    url = 'ssh://[email protected]/pygit2/empty'
    with pytest.raises(pygit2.GitError):
        pygit2.clone_repository(url, tmp_path)

    prv, pub, secret = pygit2_empty_key

    keypair = pygit2.Keypair("git", pub, prv, secret)
    callbacks = pygit2.RemoteCallbacks(credentials=keypair)
    pygit2.clone_repository(url, tmp_path, callbacks=callbacks)
예제 #8
0
파일: git.py 프로젝트: pymor/ci_hooks_app
def _push_to_gitlab(repo, refspec, force=True):
    gl_cfg = config['gitlab']
    cred = pg.credentials.UserPass(username=gl_cfg['user'],
                                   password=gl_cfg['private_token'])
    gitlab_remote = repo.remotes['gitlab']
    callbacks = pg.RemoteCallbacks(credentials=cred)
    if force:
        gitlab_remote.push([f'+{refspec}'], callbacks=callbacks)
    else:
        gitlab_remote.push([refspec], callbacks=callbacks)
예제 #9
0
    def push(self, remote='origin', force=False):
        repo = pygit2.Repository(self.folder)
        remote = repo.remotes[remote]

        if self.credentials is None:
            raise ValueError("Credentials are None, cannot push")

        callbacks = pygit2.RemoteCallbacks(credentials=self.credentials)
        print("Pushing: ", remote.url, self.credentials,file=stderr)
        remote.push(['{}{}'.format('+' if force else '', self.repo.head.name)],
                    callbacks=callbacks)
예제 #10
0
    def __init__(self, config, global_config):
        self.global_config = global_config
        self.logger = logging.getLogger('tpf-backend')

        self.tempDirectory = tempfile.TemporaryDirectory()
        self.sshKeyTempDirectory = tempfile.TemporaryDirectory()
        self.repoUrl = config['repoUrl']
        if not self.repoUrl.startswith('https://'):
            if not bool(pygit2.features & pygit2.GIT_FEATURE_SSH):
                raise Exception(
                    'pygit2 does not have SSH support (compile with libgit2 with libssh2)'
                )

        if 'username' in config and not 'password' in config and not 'privateKey' in config:
            self.logger.debug('Using only username as credentials.',
                              extra={'username': config['username']})
            self.credentials = pygit2.credentials.Username(config['username'])
        if 'username' in config and 'password' in config:
            self.logger.debug('Using username and password as credentials.',
                              extra={'username': config['username']})
            self.credentials = pygit2.credentials.UserPass(
                config['username'], config['password'])
        if 'username' in config and 'publicKey' in config and 'privateKey' in config:
            self.logger.debug(
                'Using SSH private/public key pair as credentials.',
                extra={
                    'username': config['username'],
                    'publicKey': config['publicKey']
                })
            if 'useFileSshKeys' in config and config['useFileSshKeys']:
                ssh_key_path = '%s/id' % self.sshKeyTempDirectory.name
                ssh_pubkey_path = '%s/id.pub' % self.sshKeyTempDirectory.name
                with open(ssh_key_path, 'w+t') as f:
                    f.write(config['privateKey'])
                with open(ssh_pubkey_path, 'w+t') as f:
                    f.write(config['publicKey'])
                self.credentials = pygit2.credentials.Keypair(
                    config['username'], ssh_pubkey_path, ssh_key_path,
                    config['passphrase'] if 'passphrase' in config else None)
            else:
                self.credentials = pygit2.credentials.KeypairFromMemory(
                    config['username'], config['publicKey'],
                    config['privateKey'],
                    config['passphrase'] if 'passphrase' in config else None)

        self.callbacks = pygit2.RemoteCallbacks(credentials=self.credentials)

        self.projectsPath = config[
            'projectsPath'] if 'projectsPath' in config else 'projects/'
        if not self.projectsPath.endswith('/'):
            self.projectsPath = '%s/' % self.projectsPath

        pass
예제 #11
0
def test_keypair_from_memory(tmp_path, pygit2_empty_key):
    url = 'ssh://[email protected]/pygit2/empty'
    with pytest.raises(pygit2.GitError):
        pygit2.clone_repository(url, tmp_path)

    prv, pub, secret = pygit2_empty_key
    prv_mem = open(prv).read()
    pub_mem = open(pub).read()

    keypair = pygit2.KeypairFromMemory("git", pub_mem, prv_mem, secret)
    callbacks = pygit2.RemoteCallbacks(credentials=keypair)
    pygit2.clone_repository(url, tmp_path, callbacks=callbacks)
예제 #12
0
def fetch_repo(url, credentials):
    logging.info('fetching %s', url)
    repo_callbacks = pygit2.RemoteCallbacks(credentials=credentials)
    path = 'repositories/%s' % re.sub(r'[^a-z0-9]', '-', url.lower())
    repo = pygit2.discover_repository(path)
    if repo:
        repo = pygit2.Repository(repo)
        for remote in repo.remotes:
            remote.fetch(prune=pygit2.GIT_FETCH_PRUNE,
                         callbacks=repo_callbacks)
    else:
        repo = pygit2.clone_repository(url, path, callbacks=repo_callbacks)
    return repo
예제 #13
0
def backup_gh_repos(user,
                    backupdir,
                    token=None,
                    backup_list=None,
                    exclude_list=None):

    callbacks = None

    if token != None:
        log.info("Authenticating with Github, and pulling all repositories")
        response = requests.get(
            "https://api.github.com/user/repos?visibility=all",
            auth=(user, token))
        repos = json.loads(response.text)
        cred = pygit2.UserPass(user, token)
        callbacks = pygit2.RemoteCallbacks(credentials=cred)
    else:
        response = requests.get("https://api.github.com/users/" + user +
                                "/repos")
        repos = json.loads(response.text)

    to_backup = []

    if backup_list != None:
        for repo in repos:
            if repo["name"] in backup_list:
                to_backup.append(repo)
    else:
        if exclude_list != None:
            for repo in repos:
                if repo["name"] not in exclude_list:
                    to_backup.append(repo)
        else:
            to_backup = repos

    for repo in to_backup:
        log.info("Backing up: " + repo["name"])
        dest = backupdir / "repo" / repo["full_name"]
        localrepopath = pygit2.discover_repository(str(dest))
        if localrepopath == None:
            log.info("Cloning repo...")
            pygit2.clone_repository(repo["clone_url"],
                                    str(dest),
                                    bare=True,
                                    callbacks=callbacks)
        else:
            log.info("Fetching updates...")
            localrepo = (
                pygit2.Repository(localrepopath).remotes["origin"].fetch(
                    callbacks=callbacks))
예제 #14
0
def commit_and_push(repo_clone, commit_message):
    index = repo_clone.index
    index.add_all()
    index.write()
    author = pygit2.Signature(userName, email)
    commiter = pygit2.Signature(userName, email)
    tree = index.write_tree()
    repo_clone.create_commit('refs/heads/master', author, commiter,
                             commit_message, tree,
                             [repo_clone.head.get_object().hex])
    remote = repo_clone.remotes["origin"]
    credentials = pygit2.UserPass(repoToken, 'x-oauth-basic')
    remote.credentials = credentials
    callbacks = pygit2.RemoteCallbacks(credentials=credentials)
    remote.push(['refs/heads/master'], callbacks=callbacks)
예제 #15
0
    async def git_verify(self, ctx, filepath):
        try:
            repo = pygit2.Repository(await self.config.pipeline_base())
        except pygit2.GitError:
            return
        if not repo.diff():
            return
        if not repo.lookup_branch("master").is_checked_out():
            await send_cancellation_message(
                ctx,
                f"Hey {ctx.author.mention}, the pipeline branch is currently **not**"
                f" set to master! Please inform a sysadmin that this crud change"
                f" was only **temporarily** made!")
            return
        if any(diff for diff in repo.diff().deltas
               if diff.old_file.path != filepath):
            return await send_cancellation_message(
                ctx,
                f"Hey {ctx.author.mention}, there are currently staged changes."
                f" Please inform a sysadmin so that your changes can be"
                f" manually committed.")

        keys = await self.bot.get_shared_api_tokens("github")
        if "username" not in keys or "token" not in keys:
            return await send_cancellation_message(
                ctx, f"Github credentials unset.  Add via `{ctx.prefix}set api"
                f" github username <username> token <access token>`")

        try:
            index = repo.index
            index.add(filepath)
            index.write()
            tree = index.write_tree()
            email = await self.config.user(ctx.author).email()
            author = pygit2.Signature(str(ctx.author), email
                                      or "*****@*****.**")
            commiter = pygit2.Signature("Famiel", "*****@*****.**")
            parent, ref = repo.resolve_refish(refish=repo.head.name)
            repo.create_commit(ref.name, author, commiter, "Updating JSON",
                               tree, [parent.oid])
            upcred = pygit2.UserPass(keys['username'], keys['token'])
            remote = discord.utils.get(repo.remotes, name="origin")
            remote.push(['refs/heads/master'],
                        callbacks=pygit2.RemoteCallbacks(credentials=upcred))
        except Exception as e:
            logger.exception("Failed to push.")
            await send_cancellation_message(
                ctx, f"Failed to push to github.  Please alert a sysadmin.")
예제 #16
0
    def repo(self):
        if not os.path.exists(self.folder):
            logger.info("Cloning {} into {}".format(self.origin, self.folder))

            callbacks = pygit2.RemoteCallbacks(credentials=self.credentials)

            def init_remote(repo, name, url):
                remote = repo.remotes.create(name, url)
                return remote

            return pygit2.clone_repository(self.origin,
                                           self.folder,
                                           remote=init_remote,
                                           # checkout_branch=self.branch,
                                           callbacks=callbacks)
        else:
            return pygit2.Repository(self.folder)
예제 #17
0
def org_checkout(organization, github_url, github_token, clone_dir, verbose,
                 filter, exclude):
    """Checkout repositories from a GitHub organization."""
    logging.basicConfig(
        format="%(asctime)s: %(name)s:%(levelname)s %(message)s",
        level=(verbose and logging.DEBUG or logging.INFO))

    callbacks = pygit2.RemoteCallbacks(
        pygit2.UserPass(github_token, 'x-oauth-basic'))

    repos = []
    for r in github_repos(organization, github_url, github_token):
        if filter:
            found = False
            for f in filter:
                if fnmatch(r['name'], f):
                    found = True
                    break
            if not found:
                continue

        if exclude:
            found = False
            for e in exclude:
                if fnmatch(r['name'], e):
                    found = True
                    break
            if found:
                continue

        repo_path = os.path.join(clone_dir, r['name'])
        repos.append(repo_path)
        if not os.path.exists(repo_path):
            log.debug("Cloning repo: %s/%s" % (organization, r['name']))
            repo = pygit2.clone_repository(r['url'],
                                           repo_path,
                                           callbacks=callbacks)
        else:
            repo = pygit2.Repository(repo_path)
            if repo.status():
                log.warning('repo %s not clean skipping update')
                continue
            log.debug("Syncing repo: %s/%s" % (organization, r['name']))
            pull(repo, callbacks)
    return repos
예제 #18
0
    def clone_repo(self, repo_path, rev=''):
        try:
            repo = pygit2.clone_repository(self.repo_url, repo_path)
        except pygit2.GitError:
            username = input('Enter git username: '******'Enter git password: ')
            cred = pygit2.UserPass(username, password)
            try:
                repo = pygit2.clone_repository(self.repo_url, repo_path,
                                               callbacks=pygit2.RemoteCallbacks(credentials=cred))
            except ValueError:
                print("Invalid URL!")
                sys.exit(1)
        except Exception as e:
            print(e)
            sys.exit(1)

        return repo
예제 #19
0
def _push_to_repo(user_name, cloned_repo_directory):
    """
    :param user_name: github username
    :param cloned_repo_directory:  path/to/repo_directory
    :return:
    """
    repoclone = pygit2.Repository(cloned_repo_directory + "/.git/")
    remote = repoclone.remotes["origin"]
    username = user_name
    password = get_github_password(username, refresh=False)
    credentials = pygit2.UserPass(username, password)
    remote.credentials = credentials
    callbacks = pygit2.RemoteCallbacks(credentials=credentials)
    try:
        remote.push(['refs/heads/master'], callbacks=callbacks)
    except GitCommandError as e:
        _LOG.error(str(e))
        raise PushFailedException('Uh oh, it seems like something went'
                                  ' wrong with the push. "{0}"'.format(str(e)))
예제 #20
0
 def __init__(self, password):
     self.host_keys = paramiko.util.load_host_keys(
         os.path.expanduser("~/.ssh/known_hosts"))
     self.userpass = pygit2.UserPass("robobot", password)
     self.callbacks = pygit2.RemoteCallbacks(credentials=self.userpass)
     self.callbacks.push_update_reference = self.push_update_ref
     try:
         self.key = paramiko.RSAKey.from_private_key_file(
             os.path.join(os.environ["HOME"], ".ssh", "id_rsa"), password)
     except paramiko.ssh_exception.SSHException as e:
         print("Wrong password!")
         sys.exit(-1)
     self.sock = {
         "91": None,
         "92": None,
         "93": None,
         "94": None,
         "95": None
     }
     self.transport = {}
예제 #21
0
    def __init__(self,
                 folder='.',
                 ssh_mode=False,
                 ssh_key=os.path.join(os.environ['HOME'], '.ssh/id_rsa'),
                 db_folder=None,
                 **db_cfg):
        # self.repo_list = []
        # self.add_list(repo_list)
        self.folder = folder
        self.make_folder()  # creating folder if not existing
        self.logger = logger
        self.ssh_mode = ssh_mode  #SSH if True, HTTPS otherwise
        if ssh_mode:  # setting ssh credentials
            keypair = pygit2.Keypair('git', ssh_key + '.pub', ssh_key, '')
            self.callbacks = pygit2.RemoteCallbacks(credentials=keypair)
        else:
            self.callbacks = None

        if db_folder is None:
            db_folder = self.folder
        self.set_db(db_folder=db_folder, **db_cfg)
예제 #22
0
def get_git_repository(url: str, owner: str, name: str):
    """Clone or update a repository."""
    base_dir = config['cloning']['temporary_clone_path']
    clone_dir = os.path.join(base_dir, owner, name)

    if os.path.exists(clone_dir):
        shutil.rmtree(clone_dir)

    callbacks = None
    if 'https://' not in url:
        keypair = pygit2.Keypair(username=config['cloning']['ssh_user'],
                                 pubkey=config['cloning']['public_key'],
                                 privkey=config['cloning']['private_key'],
                                 passphrase=config['cloning']['ssh_password'])
        callbacks = pygit2.RemoteCallbacks(credentials=keypair)

    os.makedirs(clone_dir)
    repo = clone_repository(url, clone_dir, bare=True, callbacks=callbacks)
    repo = Repository(clone_dir)

    return repo
예제 #23
0
    def push(self, remote_name='origin', username=None, password=None):
        """Pushes current commits
        4/13/20 21 - seems to be working

        Args:
            remote_name (string, optional): name of the remote to push to
            username (string, optional): username of user account used for pushing
            password (string, optional): password of user account used for pushing
        """
        if username is None:
            username = Config.get('user/username')
        if password is None:
            password = Config.get('user/password')
        creds = pygit2.UserPass(username, password)
        remote = self.remotes[remote_name]
        remote.credentials = creds
        try:
            remote.push([self.head.name],
                        callbacks=pygit2.RemoteCallbacks(credentials=creds))
        except GitError as e:
            Logger.warning(e)
            Logger.warning("MEG Git Repository: Failed to push commit")
예제 #24
0
def clone_repo(repo_url, name):
    repo = None

    try:
        repo = pygit2.clone_repository(repo_url, os.getcwd() + "/" + name)
    except pygit2.GitError:
        username = input('Enter git username: '******'Enter git password: ')
        cred = pygit2.UserPass(username, password)
        try:
            repo = pygit2.clone_repository(
                repo_url,
                os.getcwd() + "/" + name,
                callbacks=pygit2.RemoteCallbacks(credentials=cred))
        except ValueError:
            print("Invalid URL!")
            sys.exit(1)
    except Exception as e:
        print(e)
        sys.exit(1)

    return repo
예제 #25
0
def stage_apk(app, overrides):
    myRepo = pygit2.Repository(repo_name(app.package_name))
    master = myRepo.lookup_branch("master")
    #	if master == None:
    #myTreeGen = myRepo.TreeBuilder()
    #	else:
    #		lastcommit = myRepo.get(master.target)
    #		lastTree = lastcommit.tree.oid
    #myTreeGen = myRepo.TreeBuilder(lastTree)
    myIndex = myRepo.index
    for sourcefile in app.sourcefile_set.all():
        logging.info("Storing " + sourcefile.file_name + "\n")
        src = (sourcefile.file_contents).encode('ascii', 'replace').replace(
            "\\n", "\n")
        contents = myRepo.create_blob(src)
        myIndex.add(
            pygit2.IndexEntry(sourcefile.file_name + ".java", contents,
                              pygit2.GIT_FILEMODE_BLOB))
    logging.info("Listo el codigo fuente")
    add_other_files(app, myRepo, myIndex, overrides)
    #myTreeGen.insert(sourcefile.file_name, contents, pygit2.GIT_FILEMODE_BLOB)
    #myTree = myTreeGen.write()
    myTree = myIndex.write_tree()
    version = app.version
    author = pygit2.Signature("Alice Author", "*****@*****.**")
    committer = pygit2.Signature("Alice Author", "*****@*****.**")
    if master == None:
        myRepo.create_commit('refs/heads/master', author, committer, version,
                             myTree, [])
    else:
        myRepo.create_commit('refs/heads/master', author, committer, version,
                             myTree, [master.target])
    myRepo.create_branch(version, myRepo.head.get_object())
    myRemote = myRepo.remotes[0]
    #myRemote.credentials = pygit2.UserPass("marvin",marvin_git_passwd)
    credentials = pygit2.UserPass("marvin", marvin_git_passwd)
    callbacks = pygit2.RemoteCallbacks(credentials=credentials)
    myRemote.push(["refs/heads/master"], callbacks=callbacks)
    myRemote.push(["refs/heads/" + version], callbacks=callbacks)
예제 #26
0
파일: serve.py 프로젝트: cawik/stackn
def push_project_to_github(project_name, user_name, user_password):
    base64_bytes = user_password.encode('ascii')
    user_password_bytes = base64.b64decode(base64_bytes)
    decoded_user_password = user_password_bytes.decode('ascii')

    g = Github(user_name, decoded_user_password)
    user = g.get_user()
    repo = user.create_repo(project_name)

    repoClone = pygit2.clone_repository(repo.git_url,
                                        '{}'.format(project_name))
    repoClone.remotes.set_url('origin', repo.clone_url)

    os.system('cp -r work/ {}/'.format(project_name))

    index = repoClone.index
    index.add_all()
    index.write()
    author = pygit2.Signature('Desislava', '*****@*****.**')
    committer = pygit2.Signature('Desislava', '*****@*****.**')
    tree = index.write_tree()

    repoClone.create_commit(
        'HEAD', author, committer,
        'Pushed project directory to GitHub through STACKn studio.', tree,
        [repoClone.head.target])

    remote = repoClone.remotes['origin']
    credentials = pygit2.UserPass(user_name, decoded_user_password)
    remote.credentials = credentials

    callbacks = pygit2.RemoteCallbacks(credentials)

    remote.push(['refs/heads/master'], callbacks)

    os.system('rm -rf {}/'.format(project_name))

    return json.dumps({'status': 'OK', 'clone_url': repo.clone_url})
예제 #27
0
파일: fetch.py 프로젝트: damithc/FETcher
def main():
    """Get the CSV file of students' names and the destination
    repository from the command line, then transfer the files.
    Afterwards, commit and push using provided credentials."""
    parser = argparse.ArgumentParser(description="Read a file of "
            "student GitHub usernames, then transfer files in their "
            "PE repositories to a given destination repository.")
    parser.add_argument("students", help="CSV or plaintext list of students")
    parser.add_argument("destination", help="destination repository, "
            "in the form owner/name (e.g. nus-cs2103-AY1920S1/pe)")
    parser.add_argument("credentials", help="credentials file - "
            "four lines of author, email, username, access token")
    args = parser.parse_args()
    students = read_student_names(args.students)

    AUTHOR, EMAIL, USERNAME, TOKEN = read_credentials(args.credentials)
    user_pass = pygit2.UserPass(USERNAME, TOKEN)
    key = pygit2.RemoteCallbacks(credentials=user_pass)

    endpoint = clone_destination(args.destination, key)
    files_path = make_files_folder(endpoint)
    print_clashes(collate_files(students, files_path))
    commit_and_push(endpoint, AUTHOR, EMAIL, "Collect PE files", key)
예제 #28
0
def clone(repo_name, internal):
    clone_directory = os.environ['git_clone_dir']
    uniq_path = hashlib.sha224(repo_name).hexdigest()

    if os.path.isdir(os.path.join(clone_directory, uniq_path)):
        shutil.rmtree(os.path.join(clone_directory, uniq_path))

    if internal:
        repo_url = '%s/%s.git' % (os.environ['int_git_url'], repo_name)
    else:
        repo_url = '%s/%s.git' % (os.environ['ext_git_url'], repo_name)

    try:
        clone_dir = clone_directory
        if not os.path.isdir(clone_dir):
            os.makedirs(clone_dir)
        repo_path = os.path.join(clone_dir, uniq_path)

        if internal == True:
            username = os.environ['int_git_user']
            password = os.environ['int_git_token']
            login_info = git.UserPass(username, password)

            #git_obj = git.clone_repository(repo_url, repo_path, credentials=login_info)
            cb = git.RemoteCallbacks(credentials=login_info)
            git_obj = git.clone_repository(repo_url, repo_path, callbacks=cb)
        else:
            #username = os.environ['ext_git_user']
            #password = os.environ['ext_git_token']
            git_obj = git.clone_repository(repo_url, repo_path)

        return repo_path
    except Exception, e:
        if str(e).find('Unexpected HTTP status code: 404'):
            log.logger.error("repo doesn't exists")
            return "Repo doesn't exists"
        log.logger.error(e)
예제 #29
0
    def provision(self,
                  destination,
                  destination_main_branch,
                  additional_branches_mapping,
                  template,
                  initialize_template_command,
                  git_credential,
                  author=None,
                  commit_message="Scaffold initialized !"):
        """Provision a newly created repository in your sccs

        Workflow:
        - Initialize git credential (git_credential)
        - Clone the new repository (destination)
        - Add the template involved to provision the destination
        - Merge the main template branch to the main destination branch
        - Init the template with a shell command provided by initialize_template_command (if required)
        - Create additional branches based on additional_branches_mapping (if required)
        - Push everything to the destination
        - Clean up

        Args:
            destination (str): git url of the destination repository
            destination_main_branch (str): the destination main branch
            additional_branches_mapping (list(str)): Mapping list between template branches and destination branches (eg: [("deploy/dev", "deploy/dev"), ("deploy/dev", "deploy/prod")]
            template (str): Template to use
            initialize_template_command (list(str)): Shell command to initialize the template on the destination
            git_credential (GitCredential): Credential to connect on the template and destination
            author (str): "User <*****@*****.**>" of the real requester
            commit_message (str): Commit message used when initialize_template_command required
        
        Returns:
            str: How to use the new repository instructions
        """
        logging.info(f"{destination}: provisioning")

        # User how_to (common steps)
        user_clone = destination
        user_path = user_clone[user_clone.rfind("/") + 1:len(user_clone) - 4]
        use_me = f'git clone {user_clone}\n'
        use_me += f'cd {user_path}\n'

        # Template required
        if template == "" or template is None:
            logging.info(f"{destination}: No template selected")
            return use_me

        # Extract information from selected template
        template_from_url = self.templates[template]["from"]["git"]
        template_from_main_branch = self.templates[template]["from"][
            "main_branch"]
        template_from_other_branches = self.templates[template]["from"].get(
            "other_branches", [])

        checkout_path = os.path.join(
            self.checkout_base_path,
            ''.join(random.choices(string.ascii_letters, k=32)))

        # Git part
        # see: https://github.com/MichaelBoselowitz/pygit2-examples/blob/master/examples.py

        # Git Credential with callbacks
        callbacks = pygit2.RemoteCallbacks(
            credentials=git_credential.for_pygit2())

        # Git clone
        logging.debug(f"{destination}: cloning")
        intermediate = pygit2.clone_repository(destination,
                                               checkout_path,
                                               callbacks=callbacks)

        # Git add template repo
        logging.debug(f"{destination}: adding template {template_from_url}")
        remote_template = intermediate.remotes.create("template",
                                                      template_from_url)
        remote_template.fetch(callbacks=callbacks)
        tpl_oid = intermediate.lookup_reference(
            f"refs/remotes/template/{template_from_main_branch}").target

        # Git create branch based on template and checkout
        logging.debug(
            f"{destination}: creating main branch '{destination_main_branch}'")
        intermediate.create_branch(destination_main_branch,
                                   intermediate.get(tpl_oid))
        intermediate.checkout(f"refs/heads/{destination_main_branch}")

        # Execute custom script
        if initialize_template_command is not None:
            logging.debug(
                f"{destination}: running cmd: {' '.join(initialize_template_command)}"
            )
            # TODO: Unsafe for now ! Needs chroot/proot to isolate execution from others
            # TODO: do not raise an exception to give us the chance to clean up all around first

            proc = subprocess.run(initialize_template_command,
                                  cwd=checkout_path)
            proc.check_returncode()

            # Create commit
            logging.debug(f"{destination}: creating commit")

            committer_signature = GitCredential.create_pygit2_signature(
                git_credential.author)
            if author is None:
                author_signature = committer_signature
            else:
                author_signature = GitCredential.create_pygit2_signature(
                    author)

            intermediate.index.add_all()
            intermediate.index.write()
            tree = intermediate.index.write_tree()
            _ = intermediate.create_commit('HEAD', author_signature,
                                           committer_signature, commit_message,
                                           tree, [intermediate.head.target])

        # additional branches
        logging.debug(f"{destination}: adding additional branches")

        additional_branches = []
        for template_branch, destination_branch in additional_branches_mapping:
            if destination_branch == destination_main_branch:
                logging.warning(
                    f"{destination}: override {destination_main_branch} is not allowed"
                )
                continue
            if template_branch not in template_from_other_branches:
                logging.warning(
                    f"{destination}: branch {template_branch} is not available for {template}"
                )
                continue

            tpl_oid = intermediate.lookup_reference(
                f"refs/remotes/template/{template_branch}").target
            intermediate.create_branch(destination_branch,
                                       intermediate.get(tpl_oid))
            additional_branches.append(destination_branch)

        # Git push to origin
        logging.debug(f"{destination}: pushing all branches to origin")

        remote_origin = None
        for repo in intermediate.remotes:
            if repo.name == "origin":
                remote_origin = repo
                break

        remote_origin.push([f"refs/heads/{destination_main_branch}"],
                           callbacks)
        for additional_branch in additional_branches:
            remote_origin.push([f"refs/heads/{additional_branch}"], callbacks)

        # Clean up
        logging.debug(f"{destination}: cleaning")
        shutil.rmtree(checkout_path)

        # Return user how-to
        use_me += f'git remote add template {template_from_url}\n'
        use_me += 'git fetch template'

        logging.info(f"{destination}: provision is done")
        return use_me
예제 #30
0
if flag != 0:
    print("Overwriting compose API")
    composeAPI = open(composeAPIPath, "wt")
    composeAPI.write(json.dumps(composeAPIObject, indent=4))
    composeAPI.close()

    print("Commiting changes to intermine-compose repo")
    index = intermineComposeRepo.index
    index.add_all()
    index.write()
    author = pygit2.Signature("Intermine Bot", "*****@*****.**")
    commiter = pygit2.Signature("Intermine Bot", "*****@*****.**")
    tree = index.write_tree()
    message = "merged openapi.json from configurator repo with openapi.json in this repo"
    oid = intermineComposeRepo.create_commit(
        "refs/heads/master", author, commiter, message, tree,
        [intermineComposeRepo.head.peel().hex])

    print("pushing changes to intermine-compose master branch")
    remote = intermineComposeRepo.remotes["origin"]
    # Create a new git user and give it write access to master branch
    gitUsername = os.environ.get("SCRIPT_GIT_USERNAME")
    gitPassword = os.environ.get("SCRIPT_GIT_PASSWORD")
    credentials = pygit2.UserPass(gitUsername, gitPassword)
    remote.credentials = credentials
    callbacks = pygit2.RemoteCallbacks(credentials=credentials)
    remote.push(['refs/heads/master'], callbacks=callbacks)
else:
    print("Nothing to commit!!")
print("Merging successful")