If you’re familiar with the deployment process, chances are you’re familiar with the set of repeated steps that have to be completed before you push to production. It’s not a process that would be described as “fun”, but it’s an important one nonetheless.
But what if we could deploy and release an application with the push of a real button? In this post, we’ll go over how to make your own “ship it” button to deploy a new release.
To follow along with this tutorial, you’ll need:
*Note: This service charges you for the data you use. You can also use a virtual dash button service from your mobile phone. And the code from our guide can be connected to any application—not just AWS._
Once you’ve finished setting up all of the prerequisites, get started with the rest of the setup process.
Use Node.js to call the GitHub API and the Octokit/rest.js library to wrap API calls. Octokit works like any other library and uses the GitHub REST API endpoints—but it also allows us to use await, async, promise, and callback wrappers all contained. Plus, we can authenticate at the beginning, then perform our calls.
Let’s take a look at the index.js file we’ll create.
At the top of the file, we require our Octokit npm package:
const octokit = require('@octokit/rest')()
Then we authenticate with GitHub using our newly created personal access token:
octokit.authenticate({
type: 'token',
token: process.env.GH_TOKEN
})
To use AWS Lambda, we need a handler to understand what to do when the button is clicked. We add the wrapper:
exports.handler = (event, context, callback) => {
console.log(`Received event: ${event}`)
let tag_name
const owner = process.env.GH_LOGIN
const repo = process.env.GH_REPO
}
Inside the exports.handler
function, you’ll find releases. The GitHub Releases API is a hidden gem housed under the Repository API. You can create a draft, prerelease, set up the branch to release from, and more from one API call.
For this scenario we’ll get the latest release and increment it by one. Then we’ll publish a new release each time the button is clicked.
Both of the methods below are Promises
and will create a new release once the latest release has been retrieved. To do so, we need our GitHub username, the repo we want to release to, and a tag_name
when creating it. There are several optional details we can add, but here are the basics:
octokit.repos.getLatestRelease({
owner,
repo
}).then(result => {
tag_name = (parseInt(result.data.tag_name) + 1.0).toString() + '.0'
octokit.repos.createRelease({
owner,
repo,
tag_name
}, (error, result) => {
if (error) throw new Error()
if (result) console.log(`Created Release: ${JSON.stringify(result)}`)
})
})
In addition to creating a release, we’re going to start a deployment by calling upon the GitHub Deployments API. We can do this by specifying the login, repo, branch we want to deploy from, and optionally, a description:
octokit.repos.createDeployment({
owner,
repo,
ref: 'master',
description: `Deploying ${tag_name} version`
}, (error, result) => {
if (error) throw new Error()
if (result) console.log(`Created Deployment: ${JSON.stringify(result)}`)
})
Once the release and deployment methods are inside the event handler, the code is almost set. We’re using Node.js, so make sure to run npm init
and npm install @octokit/rest
to ensure the environment is setup.
A repository has been created with the entire setup process and you can find the link in Step 3 when we need to call on the code. To actually run the code, let’s first configure the new AWS IoT button.
To set up the button, follow the AWS quickstart guide or download the AWS IoT Button Dev app, available on iOS or Android.
Once your button is configured with WiFi, feel free to test out the example lambda functions like sending a text or email. Next we’ll create a new function.
Once we set up our lambda function, we’re ready to release! Navigate to the AWS Lambda Function Console.
In orange, you’ll see a “Create Function” button, whether you’re viewing your dashboard or functions. Below are detailed steps to walk through the process. If you get stuck, try watching this video walkthrough.
Once your function is created, you’ll see it has a number of different settings we can configure. We’ll edit the “Designer”, “Function Code”, and “Environment Variables” aspects of the function. Let’s begin with “Designer”.
Now that we have set up the button trigger, we need to make sure the code is correct. We’ll take the code from Step 2 and upload the zip file.
If you would like to use the code you wrote earlier, zip the package to the root of the folder with zip -r ShipItButton.zip ./*
or you’ll receive a cannot find /index.js error
. Otherwise, clone the contents of the repository with git clone https://github.com/ani6gup/ShipItButton.git
. Make sure the ShipItButtonLambda.zip file is cloned with the contents.
Once you have your zip file:
GH_LOGIN
, GH_REPO
, and GH_TOKEN
for your environment variables and add your login, the repository you want to release to, and the personal access token you created in the prerequisites.Now we’re ready to test our button with the following steps:
When you click Test you should be able to see new releases on your repository as they are created and the logs with Created Deployment
and Created Release
. Note: The release will only work if there is already a release present in a number format (1.0, for example).
You can check to see if your new release was created at your repositoryURL/release. Check the logs to make sure no errors were thrown. If you are seeing {message: not found}
or {message: bad credentials}
check your Personal Access Token permissions.
Now return to the “Configure Trigger Stage” and make sure your button is set. You should be able to click the button and get the same results you got when you tested it.
Next we’ll go into more detail on how to incorporate the GitHub events you just triggered within different workflows.
Clicking the button will trigger a release and deployment—but what do you do with this information? At this point, you can configure it to your workflow or deployment process. The diagram below outlines how to communicate between the button or “Tooling”, GitHub, and our server.
+---------+ +--------+ +-----------+ +-------------+
| Tooling | | GitHub | | 3rd Party | | Your Server |
+---------+ +--------+ +-----------+ +-------------+
| | | |
| Create Deployment | | |
|--------------------->| | |
| | | |
| Deployment Created | | |
|<---------------------| | |
| | | |
| | Deployment Event | |
| |---------------------->| |
| | | SSH+Deploys |
| | |-------------------->|
| | | |
| | Deployment Status | |
| |<----------------------| |
| | | |
| | | Deploy Completed |
| | |<--------------------|
| | | |
| | Deployment Status | |
| |<----------------------| |
| | | |
There are several deployment services and providers to choose from. At GitHub we use Heaven to deploy directly with our chat bot, Hubot. Some companies have even adapted it into their flow. There are also applications in GitHub Marketplace that specifically help developers with fast and easy deployment.
In order to deploy an application, we use Probot, a tool for creating GitHub Apps and automating your workflow in a quick and easy way. In this case, it acts as a third party to listen for deployment events and send back deployment statuses by creating issues.
The application is based on the GitHub delivering deployments guide but modified to Node.js in order to use Probot.
In this scenario, the bot listens for particular GitHub events, meaning when someone presses the button to create a deployment, the application knows to create and push the new build—and provide a deployment status. The button deploys to Heroku—their Build and Release API allows us to push the GitHub release package and deploy instantly from a single POST request.
If you want to take a look or try it yourself, learn more in the Deployment Status Bot repository.
While you might not physically click a button to deploy your application to product regularly, you can always trigger these GitHub events to mix up a repetitive deployment process.
If you need any additional resources or help, feel free to go through the Building a GitHub App quickstart guide. Or sign up for the GitHub Developer Program, and post on the GitHub Platform Forum.