Github

Github Add/Update/Delete File(s) on Branch with GraphQL

In input contents is base64 encoded and expectedHeadOid must match with last commit on branch referenced and operation will fails on mismatch: { "input": { "branch": { "repositoryNameWithOwner": "gliptak/githubapitest1", "branchName": "my_branch" }, "message": { "headline": "Hello from GraphQL!" }, "fileChanges": { "additions": [ { "path": "graphql.txt", "contents": "SGVsbG8gZnJvbSBHcmFwaFFMIQo=" } ], "deletions": [ { "path": "README.md" } ] }, "expectedHeadOid": "74512c01ecaec77e38497d448d391065c07ce973" } } Mutation below updates branch with fileChanges listed: mutation ($input: CreateCommitOnBranchInput!

Github Create Branch with GraphQL

First gather some context: { repository(owner: "gliptak", name: "githubapitest1") { id defaultBranchRef { name target { oid } } } } Substitute repositoryId and oid from above and use the name of the to be created branch: { "input": { "clientMutationId": "1234", "name": "refs/heads/<BRANCH_NAME>", "oid": "<OID>", "repositoryId": "<REPOSITORY_ID" } } mutation AddBranch($input: CreateRefInput!) { createRef(input: $input) { ref { name } clientMutationId } } Success returns { "data": { "createRef": { "ref": { "name": "my_branch" }, "clientMutationId": "1234" } } } And in case of error, relevant details are returned

Github List Files Recursively with GraphQL

At this point GraphQL doesn’t seem to provide the right constructs to list files folders of unconstrained depth. Instead, users will make multiple calls into the API. So let’s get started: { "owner": "gliptak", "name": "aws-cdk-python", "rev": "" } query DefaultBranch($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { name defaultBranchRef { name } } } returns { "data": { "repository": { "name": "aws-cdk-python", "defaultBranchRef": { "name": "master" } } } } Subtitute the default branch from above into the query variables with : appended (master: for our example or other syntax HEAD:) and run:

Github List Repositories Paginated with GraphQL

One of the Github GraphQL operations supporting pagination is searching/listing repositories. Below queries utilize query variables running in GitHub’s GraphQL Explorer. { "query": "org:gliptak is:all", "pageSzie": 2, "after": "" } Below setup has 2 for pagination size for demonstration purposes, larger window to be used in real queries. The initial query: query ListRepos($query: String!, $pageSize: Int!) { search(query: $query, type: REPOSITORY, first: $pageSize) { edges { node { ... on Repository { name defaultBranchRef { name } } } } pageInfo { startCursor endCursor hasNextPage } } } returns repo details and cursor values:

Github Create Pull Request with GraphQL

GraphQL API allows for query and mutation (update) operations which can be executed in GitHub’s GraphQL Explorer. Below example creates a PR. First, find the repository id: { repository(owner: "gliptak", name: "githubapitest1") { id } } The repository id returned to be used to create the pull request: { "data": { "repository": { "id": "R_kgDOGS1otA" } } } The mutation (update) creates a new PR from an existing branch (additional details could have been submitted):

Github GraphQL Example

While Github GraphQL offers detailed documentation and an API Explorer, it doesn’t have (Python) code samples. Below is a basic GQL example. The query can be developed/tested in Explorer from gql import gql, Client from gql.transport.requests import RequestsHTTPTransport import click @click.command() @click.option('--githubtoken', envvar="GITHUB_TOKEN", prompt=True, hide_input=True, help='Github token') @click.option('--owner', help='Repository owner', required=True) @click.option('--repository', help='Repository name', required=True) def gh_query_repo(githubtoken, owner, repository): transport=RequestsHTTPTransport( url='https://api.github.com/graphql', use_json=True, headers={ "Authorization": f"Bearer {githubtoken}", }, #verify=False, retries=3, ) client = Client( transport=transport, fetch_schema_from_transport=True, ) query_repo = ''' query Repository($owner: String!