Defining workflow using Github Actions — Part 2
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:
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
The API expects few value inputs like repo name and owner, followed by the PR number. There are few steps to achieve this:
- Get the PR number:
PR_NUMBER=$(jq ".number" $GITHUB_EVENT_PATH)
- Get the owner name:
PR_OWNER=$(awk -F'/' '{print $1}' <<<$GITHUB_REPOSITORY)
- 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)
For full YAML config, please check https://github.com/itzsrikanth/github-actions-recipes/blob/master/approval-and-merge.yaml