Requirements

If you have below requirements:

  • I want to show github Deployment Status in my site
  • I want to show Issue Details in my blog
  • I want to display detailed Commit History of a project in official website

Now let's rock with Github API

Implementation

REST API

// Create a personal access token at https://github.com/settings/tokens/new?scopes=repo
const octokit = new Octokit({ auth: `personal-access-token123` });

const response = await octokit.request("GET /orgs/{org}/repos", {
  org: "octokit",
  type: "private",
});

See @octokit/request for full documentation of the .request method.

Restful API is fine that you may get everything you want.

But I recommand to use GraphQL API

GraphQL API

Why GraphQL?

  • Strongly Typed
  • Extensible
  • Pick the column you desired
  • Popular
  • Solve the over-fetching and under-fetching problem

Example

const octokit = new Octokit({ auth: `personal-access-token123` });

const response = await octokit.graphql(
  `query ($login: String!) {
    organization(login: $login) {
      repositories(privacy: PRIVATE) {
        totalCount
      }
    }
  }`,
  { login: "octokit" }
);

See @octokit/graphql for full documentation of the .graphql method.

Compose a Github GraphQL Query

The Github GraphQL API documentation is obscure. 😒

  1. Get your PAT first
  2. Determine if you want a Query or a Mutation
  3. Find your query/mutation
  4. Check the return type
  5. Write it to your code

Step by Step Guide

Get your PAT

https://github.com/settings/tokens/new?scopes=repo

Make sure you checked the desired data.

Otherwise the specific field will got null in client side.

Determine if you want a Query or a Mutation

https://docs.github.com/en/graphql/reference

  • For query data you may need a Query
  • For add/update/delete data you may need a Mutation

Find your query

https://docs.github.com/en/graphql/reference/queries#repository

I use repository query and it accepts 2 args:

{
  repository(owner: "${owner}", name: "${repo}") {
    ...
  }
}

Check the return type

https://docs.github.com/en/graphql/reference/objects#repository

We have deployments available in repository object.

And deployments is a DeploymentConnection.

And check deployments, you can add the field you need to your query.

{
  repository(owner: "${owner}", name: "${repo}") {
    deployments(last: 1) {
      nodes {
        id
        createdAt
        updatedAt
        environment
        state
      }
    }
    name
    ref(qualifiedName: "refs/heads/master") {
      target {
        ... on Commit {
          YTDCommits: history(since: "${moment().clone().startOf("year").toISOString()}") {
            totalCount
          }
          monthlyCommits: history(since: "${moment().clone().startOf("month").toISOString()}") {
            totalCount
          }
        }
      }
    }
  }
}

I added 2 custom field YTDCommits & monthlyCommits to generate the MTD and YTD history count.

Debug your query

https://docs.github.com/en/graphql/overview/explorer

Full code

async (): Promise<void> => {
  try {
    const octokit = new Octokit({ auth: accessToken });

    const { repository } = await octokit.graphql(
      `
        {
          repository(owner: "${owner}", name: "${repo}") {
            deployments(last: 1) {
              nodes {
                id
                createdAt
                updatedAt
                environment
                state
              }
            }
            name
            ref(qualifiedName: "refs/heads/master") {
              target {
                ... on Commit {
                  YTDCommits: history(since: "${moment().clone().startOf("year").toISOString()}") {
                    totalCount
                  }
                  monthlyCommits: history(since: "${moment().clone().startOf("month").toISOString()}") {
                    totalCount
                  }
                }
              }
            }
          }
        }
      `,
      {
        headers: {
          authorization: `token ${accessToken}`,
        },
      },
    );



    setStatus(repository?.deployments?.nodes[0]?.state || "PENDING");
    setCreateAt(repository?.deployments?.nodes[0]?.createdAt);
    setMonthlyCommits(repository?.ref?.target?.monthlyCommits?.totalCount);
    setYTDCommits(repository?.ref?.target?.YTDCommits?.totalCount);

  } catch (errorMessage) {
    logger({ type: "error", message: errorMessage });
  }
}