Ejemplo n.º 1
0
def delete_branch(ctx: GithubContext, pr_json: LazyJson, dry_run: bool = False) -> None:
    ref = pr_json["head"]["ref"]
    if dry_run:
        print(f"dry run: deleting ref {ref}")
        return
    name = pr_json["base"]["repo"]["name"]
    token = ctx.github_password
    deploy_repo = ctx.github_username + "/" + name
    doctr_run(
        [
            "git",
            "push",
            f"https://{token}@github.com/{deploy_repo}.git",
            "--delete",
            ref,
        ],
        token=token.encode("utf-8"),
    )
    # Replace ref so we know not to try again
    pr_json["head"]["ref"] = "this_is_not_a_branch"
Ejemplo n.º 2
0
def push_repo(session_ctx, fctx, feedstock_dir, body, repo, title, head, branch,
              fork=False, organization='nsls-ii-forge'):
    """
    Push a repository up to GitHub

    Parameters
    ----------
    session_ctx: MigratorSessionContext
        Context for GitHub interaction/authentication
    fctx: FeedstockContext
        Attributes of the feedstock from the dependency graph
    feedstock_dir: str
        The feedstock directory
    body: str
        The PR body
    repo: github3.Repository
        Object for GitHub API call
    title: str
        The PR title
    head: str
        Head branch name and user/org (ex. 'nsls-ii-forge:v1.0.1_h58425')
    branch: str
        The branch name (same one in head)
    fork: bool, optional
        Change deploy repository if fork was made. Default is False.
    organization: str, optional
        GitHub organization to deploy changes to. Default is nsls-ii-forge.

    Returns
    -------
    pr_json: dict
        The dict representing the PR, can be used with `from_json`
        to create a PR instance.
    """
    with indir(feedstock_dir), env.swap(RAISE_SUBPROC_ERROR=False):
        # Setup push from doctr
        # Copyright (c) 2016 Aaron Meurer, Gil Forsyth
        token = session_ctx.github_password
        if fork:
            deploy_repo = f'{session_ctx.github_username}/{fctx.feedstock_name}-feedstock'
        else:
            deploy_repo = f'{organization}/{fctx.feedstock_name}-feedstock'
        if session_ctx.dry_run:
            repo_url = f"https://github.com/{deploy_repo}.git"
            print(f"dry run: adding remote and pushing up branch for {repo_url}")
        else:
            doctr_run(
                [
                    "git",
                    "remote",
                    "add",
                    f"{organization}_remote",
                    f"https://{token}@github.com/{deploy_repo}.git",
                ],
                token=token.encode("utf-8"),
            )

            doctr_run(
                ["git", "push", "--set-upstream", f"{organization}_remote", branch],
                token=token.encode("utf-8"),
            )
    # lastly make a PR for the feedstock
    print(f"Creating {organization} feedstock pull request...")
    if session_ctx.dry_run:
        print(f"dry run: create pr with title: {title}")
        return None
    else:
        pr = repo.create_pull(title, "master", head, body=body)
        if pr is None:
            print(f"Failed to create pull request for {feedstock_dir}-feedstock!")
            return None
        else:
            print(f"Pull request created at {pr.html_url}")
    # Return a json object so we can remake the PR if needed
    pr_dict = pr.as_dict()
    return pr_dict
Ejemplo n.º 3
0
def deploy(args):
    """Deploy the graph to github"""
    if args.dry_run:
        print("(dry run) deploying")
        return

    # TODO: have function construct this
    BUILD_URL = os.environ.get(BUILD_URL_KEY, "")

    # pull changes, add ours, make a commit
    try:
        _run_git_cmd("git pull -s recursive -X theirs")
    except Exception as e:
        print(e)

    files_to_add = set()
    for dr in [
            "pr_json",
            "status",
            "node_attrs",
            "audits",
            "audits/grayskull",
            "audits/depfinder",
            "versions",
            "profiler",
            "mappings",
            "mappings/pypi",
            "ranked_hubs_authorities.json",
            "all_feedstocks.json",
    ]:
        # untracked
        files_to_add |= set(
            subprocess.run(
                f"git ls-files -o --exclude-standard {dr}",
                shell=True,
                capture_output=True,
            ).stdout.decode("utf-8").splitlines(), )

        # changed
        files_to_add |= set(
            subprocess.run(
                f"git diff --name-only {dr}",
                shell=True,
                capture_output=True,
            ).stdout.decode("utf-8").splitlines(), )

        # modified and staged but not deleted
        files_to_add |= set(
            subprocess.run(
                f"git diff --name-only --cached --diff-filter=d {dr}",
                shell=True,
                capture_output=True,
            ).stdout.decode("utf-8").splitlines(), )

    n_added = 0
    for file in files_to_add:
        if file and os.path.exists(file):
            try:
                print(f"committing: {file}", flush=True)
                _run_git_cmd(f"git add {file}")
                n_added += 1
            except Exception as e:
                print(e)

    if n_added > 0:
        try:
            _run_git_cmd(f'git commit -am "Update Graph {BUILD_URL}"')
        except Exception as e:
            print(e)

        # make sure the graph can load, if not we will error
        try:
            gx = load_graph()
            # TODO: be more selective about which json to check
            for node, attrs in gx.nodes.items():
                attrs["payload"]._load()
            graph_ok = True
        except Exception:
            graph_ok = False

        status = 1
        num_try = 0
        while status != 0 and num_try < 10 and graph_ok:
            try:
                if num_try == 9:
                    print(
                        "\n\n>>>>>>>>>>>> git unshallow for try %d\n\n" %
                        num_try,
                        flush=True,
                    )
                    _run_git_cmd("git fetch --unshallow")
                print("\n\n>>>>>>>>>>>> git pull try %d\n\n" % num_try,
                      flush=True)
                _run_git_cmd("git pull -s recursive -X theirs")
            except Exception as e:
                print(
                    "\n\n>>>>>>>>>>>> git pull try %d failed: %s \n\n" %
                    (num_try, e),
                    flush=True,
                )
                pass
            print("\n\n>>>>>>>>>>>> git push try %d\n\n" % num_try, flush=True)
            with sensitive_env() as env:
                status = doctr_run(
                    [
                        "git",
                        "push",
                        "https://{token}@github.com/{deploy_repo}.git".format(
                            token=env.get("PASSWORD", ""),
                            deploy_repo="regro/cf-graph-countyfair",
                        ),
                        "master",
                    ],
                    token=env.get("PASSWORD", "").encode("utf-8"),
                )
            num_try += 1

        if status != 0 or not graph_ok:
            print("\n\n>>>>>>>>>>>> failed deploy - pushing to branch\n\n",
                  flush=True)
            if not graph_ok:
                print("\n\n>>>>>>>>>>>> git unshallow graph bad\n\n",
                      flush=True)
                _run_git_cmd("git fetch --unshallow")
            _branch = "failed-circle-run-%s" % os.environ["CIRCLE_BUILD_NUM"]
            _run_git_cmd(f"git checkout -b {_branch}")
            _run_git_cmd("git commit --allow-empty -am 'help me!'")

            with sensitive_env() as env:
                status = doctr_run(
                    [
                        "git",
                        "push",
                        "--set-upstream",
                        "https://{token}@github.com/{deploy_repo}.git".format(
                            token=env.get("PASSWORD", ""),
                            deploy_repo="regro/cf-graph-countyfair",
                        ),
                        _branch,
                    ],
                    token=env.get("PASSWORD", "").encode("utf-8"),
                )

            raise RuntimeError("bot did not push its data! stopping!")
    else:
        print("no files to commit!", flush=True)
Ejemplo n.º 4
0
def push_repo(
    session_ctx: MigratorSessionContext,
    fctx: FeedstockContext,
    feedstock_dir: str,
    body: str,
    repo: github3.repos.Repository,
    title: str,
    head: str,
    branch: str,
) -> Union[dict, bool, None]:
    """Push a repo up to github

    Parameters
    ----------
    feedstock_dir : str
        The feedstock directory
    body : str
        The PR body

    Returns
    -------
    pr_json: dict
        The dict representing the PR, can be used with `from_json`
        to create a PR instance.
    """
    with indir(feedstock_dir), env.swap(RAISE_SUBPROC_ERROR=False):
        # Setup push from doctr
        # Copyright (c) 2016 Aaron Meurer, Gil Forsyth
        token = session_ctx.github_password
        deploy_repo = (session_ctx.github_username + "/" +
                       fctx.feedstock_name + "-feedstock")
        if session_ctx.dry_run:
            repo_url = f"https://github.com/{deploy_repo}.git"
            print(
                f"dry run: adding remote and pushing up branch for {repo_url}")
        else:
            doctr_run(
                [
                    "git",
                    "remote",
                    "add",
                    "regro_remote",
                    f"https://{token}@github.com/{deploy_repo}.git",
                ],
                token=token.encode("utf-8"),
            )

            doctr_run(
                ["git", "push", "--set-upstream", "regro_remote", branch],
                token=token.encode("utf-8"),
            )
    # lastly make a PR for the feedstock
    print("Creating conda-forge feedstock pull request...")
    if session_ctx.dry_run:
        print(f"dry run: create pr with title: {title}")
        return False
    else:
        pr = repo.create_pull(title, "master", head, body=body)
        if pr is None:
            print("Failed to create pull request!")
            return False
        else:
            print("Pull request created at " + pr.html_url)
    # Return a json object so we can remake the PR if needed
    pr_dict: dict = pr.as_dict()
    return pr_dict