Continuous integration with Github Actions
Continuous Integration
Continuous Integration (CI) is a software development practice where developers integrate code into a shared repository frequently, ideally several times a day! Among the benefits of this practice is that you can detect errors quickly and resolve them more easily. Watch this 6 mins video for an intro to CI.
Build Pipeline
tip
A build pipeline is a set of steps that move code from development to production.
In modern software development, the build pipeline is often automated. That means, for instance, when you commit and push your code into the repository, a cascade of actions will be triggered that include "compiling the code," "executing tests," etc., which eventually result in deploying (software) artifacts. Automated build pipelines are great for implementing continuous integration workflows for software.
In this reading, we'll look at building a simple build pipeline using Github Actions.
Github Actions
Previously, we used Travis CI as our cloud-based continuous integration tool in this class. However, Github released Github Actions in November 2019 to public. Github Actions "is an API for cause and effect on GitHub: orchestrate any workflow, based on any event, while GitHub manages the execution, provides rich feedback, and secures every step along the way." Since Github Actions is integrated directly into Github, is easy/starightforward to set up, and offers lots of automationa flexibility, we focus on it in the class but feel free to explore other alternatives such as Travis.
Creating a Build Pipeline with Github Actions
In order to utilize Github Actions, you need to setup a .yml
configuration file. Create a folder named .github
in the root of your project. Then, create a subdirectory inside it named workflows
. Inside workflows
folder, create a file named main.yml
and paste the following content in it:
In this file, we specify a set of events and triggers. In our case, we are inetersted in push
es to as well as pull requests
on the master
branch. Upon either of these events, a set of jobs
are triggered where each job in return is comprised of actions. These are listed under steps
. We first checkout the content of the repo so that it is available to our workflow. Then, we set up a Java environment in the requested Github runner machine (i.e. ubuntu). Next, we make sure gradlew
is executable by running chmod +x gradlew
before using it to build a fresh fat-jar file out of our project. Once, the jar file is produced, we commit the workspace back to our repo and finally we deploy to Heroku from there.
Furthermore, we need to authorize Github so that it can deploy to our Heroku account on our behalf. This is done by setting up a Github secret: First, go to your Heroku account and go to Account Settings. Scroll to the bottom until you see API Key. Copy this key and go to your project's repository on GitHub. In your repo, go to Settings -> Secrets and click on New Secret. Then enter HEROKU_API_KEY
as the name and paste the copied API Key as the value. Also, make sure the heroku app name as well as your heroku email are set correctly in the yaml file.
Procfile
Since we are not using Gradle-Heroku plugin to deploy the app, we must tell Heroku how to run our application after it is deployed by Github Actions. To this aim, you need to add a file named Procfile
to the root of your application directory with the following content:
Now, try making a new push to your repo. If things are set up correctly and work as expected, upon the push, the Github Actions should execute all the steps and push a fresh build to Heroku.