Beispiel #1
0
async def get_channels_info(slack_access_token):
    """
    Get channel information from slack

    Args:
        slack_access_token (str): Used to authenticate with slack

    Returns:
        dict: A map of channel names to channel ids
    """
    client = ClientWrapper()
    # public channels
    resp = await client.post("https://slack.com/api/channels.list",
                             data={"token": slack_access_token})
    resp.raise_for_status()
    channels = resp.json()['channels']
    channels_map = {channel['name']: channel['id'] for channel in channels}

    # private channels
    resp = await client.post("https://slack.com/api/groups.list",
                             data={"token": slack_access_token})
    resp.raise_for_status()
    groups = resp.json()['groups']
    groups_map = {group['name']: group['id'] for group in groups}

    return {**channels_map, **groups_map}
Beispiel #2
0
async def get_pull_request(*, github_access_token, org, repo, branch):
    """
    Look up the pull request for a branch

    Args:
        github_access_token (str): The github access token
        org (str): The github organization (eg mitodl)
        repo (str): The github repository (eg micromasters)
        branch (str): The name of the associated branch

    Returns:
        dict: The information about the pull request
    """
    endpoint = "https://api.github.com/repos/{org}/{repo}/pulls".format(
        org=org,
        repo=repo,
    )

    client = ClientWrapper()
    response = await client.get(
        endpoint,
        headers=github_auth_headers(github_access_token),
    )
    response.raise_for_status()
    pulls = response.json()
    pulls = [pull for pull in pulls if pull['head']['ref'] == branch]
    if not pulls:
        return None
    elif len(pulls) > 1:
        # Shouldn't happen since we look up by branch
        raise Exception(
            "More than one pull request for the branch {}".format(branch))

    return pulls[0]
Beispiel #3
0
async def create_pr(*, github_access_token, repo_url, title, body, head, base):  # pylint: disable=too-many-arguments
    """
    Create a pull request

    Args:
        github_access_token (str): A github access token
        repo_url (str): The URL of the repository to create the PR in
        title (str): The title of the PR
        body (str): The body of the PR
        head (str): The head branch for the PR
        base (str): The base branch for the PR
    """

    org, repo = get_org_and_repo(repo_url)
    endpoint = "https://api.github.com/repos/{org}/{repo}/pulls".format(
        org=org,
        repo=repo,
    )

    client = ClientWrapper()
    resp = await client.post(endpoint,
                             headers=github_auth_headers(github_access_token),
                             data=json.dumps({
                                 'title': title,
                                 'body': body,
                                 'head': head,
                                 'base': base,
                             }))
    resp.raise_for_status()
Beispiel #4
0
async def get_issue(*, github_access_token, org, repo, issue_number):
    """
    Look up information about an issue

    Args:
        github_access_token (str): The github access token
        org (str): An organization
        repo (str): A repository
        issue_number (int): The github issue number

    Returns:
        Issue: Information about the issue
    """
    endpoint = f"https://api.github.com/repos/{org}/{repo}/issues/{issue_number}"
    client = ClientWrapper()
    response = await client.get(
        endpoint, headers=github_auth_headers(github_access_token))
    response.raise_for_status()
    response_json = response.json()
    if 'pull_request' in response_json:
        return

    return Issue(
        title=response_json['title'],
        number=response_json['number'],
        org=org,
        repo=repo,
        status=response_json['state'],
        updatedAt=parse(response_json['updated_at']),
        url=response_json['html_url'],
    )
Beispiel #5
0
async def create_pr(*, github_access_token, repo_url, title, body, head, base):  # pylint: disable=too-many-arguments
    """
    Create a pull request

    Args:
        github_access_token (str): A github access token
        repo_url (str): The URL of the repository to create the PR in
        title (str): The title of the PR
        body (str): The body of the PR
        head (str): The head branch for the PR
        base (str): The base branch for the PR

    Returns:
        PullRequest: Info about the new pull request
    """

    org, repo = get_org_and_repo(repo_url)
    endpoint = f"https://api.github.com/repos/{org}/{repo}/pulls"

    client = ClientWrapper()
    resp = await client.post(
        endpoint,
        headers=github_auth_headers(github_access_token),
        data=json.dumps({
            "title": title,
            "body": body,
            "head": head,
            "base": base,
        }),
    )
    resp.raise_for_status()
Beispiel #6
0
async def get_channels_info(slack_access_token):
    """
    Get channel information from slack

    Args:
        slack_access_token (str): Used to authenticate with slack

    Returns:
        dict: A map of channel names to channel ids
    """
    client = ClientWrapper()
    # public channels
    channels = {}

    async for channel in iterate_cursor(
            client.post,
            "channels",
            "https://slack.com/api/conversations.list",
            data={
                "token": slack_access_token,
                "types": "public_channel,private_channel",
            }):
        channels[channel['name']] = channel['id']

    return channels
Beispiel #7
0
async def get_pull_request(*, github_access_token, org, repo, branch, all_prs):
    """
    Look up the most recently created pull request for a branch

    Args:
        github_access_token (str): The github access token
        org (str): The github organization (eg mitodl)
        repo (str): The github repository (eg micromasters)
        branch (str): The name of the associated branch
        all_prs (bool):
            If True, look through open and closed PRs. The most recent PR for that branch will be returned.
            If False, look only through open PRs.

    Returns:
        dict: The information about the pull request
    """
    state = "all" if all_prs else "open"
    endpoint = f"https://api.github.com/repos/{org}/{repo}/pulls?state={state}&head={org}:{branch}&per_page=1"

    client = ClientWrapper()
    response = await client.get(
        endpoint,
        headers=github_auth_headers(github_access_token),
    )
    response.raise_for_status()
    pulls = response.json()
    return pulls[0] if pulls else None
Beispiel #8
0
async def get_channels_info(slack_access_token):
    """
    Get channel information from slack

    Args:
        slack_access_token (str): Used to authenticate with slack

    Returns:
        dict: A map of channel names to channel ids
    """
    client = ClientWrapper()
    # public channels
    channels = {}

    async for channel in iterate_cursor(
            client.post,
            "channels",
            # see https://api.slack.com/methods/conversations.list
            "https://slack.com/api/conversations.list",
            data={
                "token": slack_access_token,
                "types": "public_channel,private_channel",
                "limit": 200,  # increase from default of 100
                "exclude_archived": "true",
            },
    ):
        channels[channel["name"]] = channel["id"]

    return channels
async def fetch_release_hash(hash_url):
    """Fetch the hash from the release"""
    client = ClientWrapper()
    response = await client.get(hash_url)
    response.raise_for_status()
    release_hash = response.content.decode().strip()
    if len(release_hash) != 40:
        raise Exception(
            f"Expected release hash from {hash_url} but got: {release_hash}"
        )
    return release_hash
Beispiel #10
0
async def get_doofs_id(slack_access_token):
    """
    Ask Slack for Doof's id

    Args:
        slack_access_token (str): The slack access token
    """
    client = ClientWrapper()

    async for member in iterate_cursor(client.post,
                                       "members",
                                       "https://slack.com/api/users.list",
                                       data={"token": slack_access_token}):
        if member['name'] == 'doof':
            return member['id']

    raise Exception("Unable to find Doof's user id")
Beispiel #11
0
async def delete_label(*, github_access_token, repo_url, pr_number, label):
    """
    Set labels on a pull request, replacing other labels currently on that pull request.

    Args:
        github_access_token (str): A Github access token
        repo_url (str): The repository git URL
        pr_number (int): A pull request number
        label (str): The label text
    """
    org, repo = get_org_and_repo(repo_url)
    endpoint = f"https://api.github.com/repos/{org}/{repo}/issues/{pr_number}/labels/{quote(label)}"
    client = ClientWrapper()
    response = await client.delete(
        endpoint, headers=github_auth_headers(github_access_token))
    if response.status_code != 404:
        response.raise_for_status()
Beispiel #12
0
async def add_label(*, github_access_token, repo_url, pr_number, label):
    """
    Add a label to a pull request, replacing other labels currently on that pull request.

    Args:
        github_access_token (str): A Github access token
        repo_url (str): The repository git URL
        pr_number (int): A pull request number
        label (str): The label text
    """
    org, repo = get_org_and_repo(repo_url)
    endpoint = f"https://api.github.com/repos/{org}/{repo}/issues/{pr_number}/labels"
    client = ClientWrapper()
    payload = {"labels": [label]}
    response = await client.post(
        endpoint,
        json=payload,
        headers=github_auth_headers(github_access_token))
    response.raise_for_status()
Beispiel #13
0
async def get_labels(*, github_access_token, repo_url, pr_number):
    """
    Get a list of labels for a pull request

    Args:
        github_access_token (str): A Github access token
        repo_url (str): The repository git URL
        pr_number (int): A pull request number

    Returns:
        list of str: A list of labels
    """
    org, repo = get_org_and_repo(repo_url)
    endpoint = f"https://api.github.com/repos/{org}/{repo}/issues/{pr_number}/labels"
    client = ClientWrapper()
    response = await client.get(
        endpoint, headers=github_auth_headers(github_access_token))
    response.raise_for_status()
    return [item["name"] for item in response.json()]
Beispiel #14
0
async def run_query(*, github_access_token, query):
    """
    Run a query using Github graphql API

    Args:
        github_access_token (str): A github access token
        query (str): A graphql query to run

    Returns:
        dict: The results of the query
    """
    endpoint = "https://api.github.com/graphql"
    query = json.dumps({"query": query})
    client = ClientWrapper()
    resp = await client.post(
        endpoint,
        data=query,
        headers={"Authorization": "Bearer {}".format(github_access_token)})
    resp.raise_for_status()
    return resp.json()
Beispiel #15
0
async def get_status_of_pr(*, github_access_token, org, repo, branch):
    """
    Get the status of the PR for a given branch

    Args:
        github_access_token (str): The github access token
        org (str): The github organization (eg mitodl)
        repo (str): The github repository (eg micromasters)
        branch (str): The name of the associated branch

    Returns:
        str: The status of the PR. If any status is failed this is failed,
            if any is pending this is pending. Else it's good.
    """
    endpoint = "https://api.github.com/repos/{org}/{repo}/commits/{ref}/statuses".format(
        org=org,
        repo=repo,
        ref=branch,
    )
    client = ClientWrapper()
    resp = await client.get(
        endpoint,
        headers=github_auth_headers(github_access_token),
    )
    if resp.status_code == 404:
        statuses = []
    else:
        resp.raise_for_status()
        statuses = resp.json()

    # Only look at PR builds
    statuses = [
        status for status in statuses
        if status['context'] == 'continuous-integration/travis-ci/pr'
    ]

    if len(statuses) == 0:
        # This may be due to the PR not being available yet
        return NO_PR_BUILD

    return statuses[0]['state']