Defining workflow using Github Actions — Part 2

Srikanth Sharma
2 min readJul 3, 2020

--

In continuation to part 1 of the series, we will explore Github API as well, to address one issue. When we add Github Actions to our repo, we can protect merging a PR to branch by enabling the following options in Branch protection rule:

Github Branch Protection

But if we have a requirement to deploy when the review is:

  • approved
  • approved and merged.

Deploy on Approval and/or Merge

When we check the Github Actions documentation for pull_request, it has hooks for ready_for_review, review_requested & review_request_removed . But not for approved review. But I got solution to this problem in stackoverflow by Lukasz Gornicki.

But when we want to deploy on approved merge, we do not have any hooks for that. But we can take help from GitHub API for this.

Github API

Github v4 uses GraphQL. As seen in images below, we are making POST call to the API with Authorization headers to get the review and merge state of the PR raised. It should be in APPROVED and true respectively for us to trigger the deployment. Now we need to make this call using curl

GraphQL UI to hit Github API v4
Adding Auth header for Github API v4

The API expects few value inputs like repo name and owner, followed by the PR number. There are few steps to achieve this:

  1. Get the PR number:
    PR_NUMBER=$(jq ".number" $GITHUB_EVENT_PATH)
  2. Get the owner name:
    PR_OWNER=$(awk -F'/' '{print $1}' <<<$GITHUB_REPOSITORY)
  3. Get the repo name:
    PR_REPO=$(awk -F'/' '{print $2}' <<<$GITHUB_REPOSITORY)

With these values, we can finally make the call by “stringifying” the GraphQL request and substituting bash variables necessary:

RESPONSE=$(curl -s --request POST \
--url https://api.github.com/graphql \
--header "authorization: bearer ${{ secrets.GITHUB_TOKEN }}" \
--header 'content-type: application/json' \
--data "{\"query\":\"{repository(owner:\\\"$PR_OWNER\\\",name:\\\"$PR_REPO\\\"){pullRequest(number:$PR_NUMBER){reviews(last:1){edges{node{state}}}merged}}}\"}")

Here, we are adding the Github token in secrets as mentioned in part-1 of this series. We can parse the response using jq again to get approval and merge status.

VALUE=$(jq -r ".data.repository.pullRequest.reviews.edges[0].node.state" <<<$RESPONSE)
STATUS=$(jq ".data.repository.pullRequest.merged" <<<$RESPONSE)

Finally, we can check them in if condition as follows:

if [[ "$VALUE" == "APPROVED" && "$STATUS" == "true" ]]; then
echo "Approved and merged"
fi

(Note: jq is a command to parse JSON , already installed in some OS like ubuntu-18.04 which is used here)

--

--