Prevent Lazy GitHub Practices in 10 minutes using AWS Lambdas
April 08, 2018Rob Cronin5 min read
"Can't you name all your pull requests in the right format?"
"...Oops I just merged into production"
Using AWS lambdas can be a cool and useful way to improve your workflow with GitHub.
Blocking merges when tests fail on your branch is common, but GitHub status checks can be pushed much further.
Combining GitHub's API and Lambdas provides this opportunity.
Turns out we can use a Github Webhook Listener to POST to an AWS lambda after any specified events(pushes, commits, forks, pull requests etc).
In response, lambdas can in turn POST back to a Pull Request and create/update a status check.
Or they can just POST at specified times.
To test this out and get it up and running, we could impose two checks:
- A required format for pull request titles
- Specific times where merging to production is prohibited
For a full in-depth guide on setting all this up for your project see my github-lambda-status-checks repo.
First we set up a lambda which can react to a JSON of information about a pull request.
After deploying the lambda via serverless we are given an endpoint which, using GitHub webhooks, can automatically be hit on every pull request action(create, edit, …)
The webhook provides the lambda with a large amount of information about the PR.
An abridged version of some of the information sent to the lambda is shown below:
Amongst this, we are given a
statuses_url to which we can send a POST request back to the GitHub API to create/update a status.
For example, sending the following created the fake CI status in the title image:
We can add any logic based on say, the pull request title, to send back a status result ('success', 'failure', 'pending').
These will appear, as in the title image, depending on the state sent.
In github-lambda-status-checks you can add any logic to gitWebhookListener.js from line 78 to tweak your status responses.
After any status check(which are unique by their
context) has run at least once in a repo, it can be chosen as a Required status check on any protected branches(settings -> branches).
This will prevent the PR being merged unless the status check has a
success state (see title image).
Lambdas can also be setup to trigger at set times in the day.
Using the GitHub API the lambda can say, GET all the pull requests from a given repo merging into the
At 4pm it could then send a
pending state to all of these pull requests. If this check is set as Required, it would then block accidental merging at inappropriate times.
You could then trigger another lambda at 8am to unblock all these PRs.
If you set this status to 'Required' then any new pull request can not be merged until it passes this check, which won't be until 8am the next day…
To overcome this you can check the time in the pull request event listener so that any new pull request can pass/fail the time check as expected.
What we did
We wanted to move a long running project from merging to production twice a week, to continuously deploying with every ticket.
The lambdas in this article came about to address some concerns we had about this.
Our release notes (linked directly to pull request titles) needed to accurately reflect what was in production at a given time (as opposed to random commit titles).
Devs/stakeholders needed to be able to quickly associate a pull request title to a team, ticket number and user story:
(A-TEAM 123) AAC I love this product
This was implemented similar to gitWebhookListener.js with simple JS/regex.
Our team had become accustomed to merging a validated ticket to a
master branch would then be merged/deployed into
production twice a week.
The worry with continuous deployment (eliminating
master) was that a ticket may accidentally be merged to
production (after validation) too late in the day (when bugs can't be monitored/fixed).
Thus the timed lambda in githubTimeStatus.js (and the gotcha in githubWebhookListener.js) was implemented.
As we have seen, the response from GitHub provides a lot of information about the PR, so you could adapt this to any need you may have.
For a full in-depth guide on setting this up for your project see mygithub-lambda-status-checks repo.