Skip to content

Instantly share code, notes, and snippets.

@daniman
Last active April 6, 2021 05:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daniman/e53d0589d18b778878bd8ef32d2e793c to your computer and use it in GitHub Desktop.
Save daniman/e53d0589d18b778878bd8ef32d2e793c to your computer and use it in GitHub Desktop.
A shell script that takes the output of `apollo service:check` and posts it as a comment on your GitHub PRs. This is useful in cases where you can't install the Apollo GitHub app or want increased visibility into the results of schema validation in your pull requests.
#!/usr/bin/env bash
# This guide walks through posting the output of `apollo service:check` to a comment on your GitHub PRs,
# using the GitHub GraphQL API (v4) and the Apollo CLI.
#
# This guide primarily covers how to post a comment to GitHub from the command line using `curl`. If you
# are using another service provider for your code management, you will need to read their API docs
# on how to authenticate and post a comment to pull requests in their system.
#
# Getting a result from Apollo schema validation in markdown format is as easy as running:
# `apollo service:check --tag=$TAG --markdown`
#
# Manipulating this output into the correct format for `curl` and using the API of your code management
# service provider correctly is the tricky part. The rest of this guide demonstrates how to do this with
# GitHub's API specifically.
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Step 0 –– Get this file set up in your continuous integration correctly.
#
# Executing this file in CI will look something like this: './github.sh prod'
#
# In order for the `apollo service:check` command to succeed, you will need an apollo.config.js file and
# a .env file with your Engine API key. Before you proceed with this setup, make sure that
# `apollo service:check` is working as expected when run locally. Visit our guide on schema validation
# to get that set correctly: https://www.apollographql.com/docs/platform/schema-validation
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Step 1 –– Get an authentication token for the GitHub API.
#
# You can use a personal authentication token or authenticate as a GitHub app:
# https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line
# https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-a-github-app
#
# Your token will need full `repo` access so that it can post comments on your pull requests.
#
# If you're using GitHub Enterprise, we recommend using a service account. From your service account,
# create an OAuth app and generate an API token to be used specifically for comments from schema validation.
# Use this API token to authenticate your requests to the GitHub API.
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
TOKEN="aa_YOUR_TOKEN_HERE_zz"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Step 2 –– Identify the URL of the pull reuqest to update on GitHub.
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
URL="https://YOUR_URL_HERE.com"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Step 3 –– Run schema validation against a specified tag and passing the `--markdown` option.
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
TAG=$1
CHANGES=$(apollo service:check --markdown --tag=$TAG || true)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Congrats, your part is done!
#
# Below is code that you do not need to edit.
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# The result of apollo service:check --markdown will contain new line characters. We use `sed` to escape
# these new lines so that when we insert the $CHANGES variable in our curl command, we still have valid JSON.
# Failing to escape these new line characters will result in us having invalid JSON for our curl.
CHANGES=$(echo "$CHANGES" | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g')
## Exit safely if there are no schema changes, because we don't want to post a comment in that case.
if [[ $CHANGES == *"**0 schema changes**"* ]]; then
exit 0
fi
# We use the URL of our pull request to find the pull requests's resource ID, which we use as an
# input argument to our mutation to post our comment on our pull request.
RESPONSE=$(
curl -s \
-X POST \
-H "User-Agent: Apollo Service Check" \
-H "Authorization: bearer $TOKEN" \
-d '{
"query": "query findPRNodeId($url: URI!) { resource(url: $url) { ... on PullRequest { id } } }",
"variables": {
"url": "'"$URL"'"
}
}' \
https://api.github.com/graphql
)
echo "$RESPONSE"
# Our response comes back in JSON format and we need to extract our ID in order to use it properly.
# We use python ƒor simplicity, but any JSON parsing method will work.
PR_ID=$(echo "$RESPONSE" | python -c 'import sys, json; print json.load(sys.stdin)["data"]["resource"]["id"]')
# Now we have everything we need: 1. the ID of our pull request in GitHub's system, and 2. the result of
# validation that we want to post in our comment. We use the API's `addComment` mutation to post our comment.
curl -s \
-X POST \
-H "User-Agent: Apollo Service Check" \
-H "Authorization: bearer $TOKEN" \
-d '{
"query" : "mutation addComment($subjectId: ID!, $clientMutationId: String, $body: String!) { addComment(input: {subjectId: $subjectId, clientMutationId: $clientMutationId, body: $body}) { subject { id } } }",
"variables" : {
"clientMutationId": "Apollo Schema Validation",
"subjectId": "'"$PR_ID"'",
"body": "'"$CHANGES"'"
}
}' \
https://api.github.com/graphql
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment