Rivers Agile Software Engineer, Stephen Teodori, explains Continuous Integration and how to integrate Github Actions into the process
In this article series, we will be exploring what kind of Continuous Integration can be achieved with Github Actions. In part one, we’ll look at what we are trying to achieve and how to review your project requirements. In the upcoming articles, we will use a sample project to provide an example of setting up GitHub Actions.
In our exploration, we’ll focus on using GitHub Actions for private repositories. If you have a public repository, you should be taking special steps to ensure any secrets in your repo remain secret and that someone won’t be able to run up your costs.
What is Continuous Integration?
There is a lot more to managing a project than just writing the code. Ideally you’ll have code reviews, QA process, staging environment, and more. Even at the bare minimum, a developer will need to package up a project and then deploy it to customers. Continuous Integration (CI) are processes that automate these steps.
For many projects this might seem like overkill. If you are only automating a few simple steps, it might only save 30 minutes a week – so why invest the effort? Plus the steps involved are simple and outlined in a shared document (I hope). Well, let me ask you this – in your break room, if you posted simple instructions for cleaning the coffee machine, how often do you think a mistake would be made? If your business has more than one break room would the instructions vary between the rooms? CI ensures that the same instructions are always followed and uses a clean, standardized environment on each run.
The basics of GitHub Actions
So now that we have the basics of what CI seeks to achieve, how can GitHub Actions help? Let’s start by looking at how GitHub Actions are configured.
GitHub Actions are defined by files in your code repo. Whenever a branch’s code is updated, GitHub will look for files in \.github\workflows in the root of your branch for Action definitions. This is important because it means your Actions are not tied to your repository but are primarily tied to branches. If a branch has no Actions defined then none will trigger. You’ll still have events at the repository level, but the Actions that trigger will come from individual branches or your default branch. We’ll discuss these events more in a moment.
The GitHub Action definitions in \.github\workflows are YML files that break down into 3 important parts. The name of the Action, when the Action should trigger, and what to do when it triggers.
Defining an Action’s triggers
So let’s start with when Actions should trigger. GitHub provides a list of trigger events. For basic use cases in a private repository you’ll primarily use the push and pull_request. In addition to defining the event we can also define exclusion and inclusion parameters. For example we can have special Actions that only run when your master branch is updated or we can skip an action if the branch name begins with “poc/”.
Executing commands through the Action
Next we define what the Action will do. An action can have multiple jobs. Each job defines what operating system it should run in, and then the series of commands to execute. These commands can be command line instructions sent to the OS’s shell or it can trigger another action altogether. For triggering other actions you can also trigger actions defined by 3rd parties or GitHub themselves. For example, you might use an action that will set up a database for your unit tests to run against.
Getting the results
While the action is executing GitHub will record all command line output and categorize it based on how you structured your Action. Additionally GitHub will identify when errors occur during individual steps and flag the Action as having a failure. The result is then displayed in various places of GitHubs UI or it may send email notifications to project members.
Identifying the resources you’ll need
Now we have the basics of what we want to achieve and what GitHub Actions are. Let’s start thinking about what your project would need if its processes were automated.
When planning your Action, you’ll need to consider a few things:
- Environment – Are your developers using Windows? Can your project be built in Linux?
- 3rd Party Dependencies – What testing or build tools will you need to download? Is there anything not obtained through nuget packages? Can everything be run via command line?
- 1st Party Dependencies – Are there resources not in your repo that you’ll need? Does a local SQL service need to be set up?
- GitHub Resources – What can GitHub give me out of the box? Does it have pre-existing actions that can set up resources I need such as databases or other software?
- Authentication – Do I need to authenticate with a service outside of GitHub?
The answer to these questions will vary heavily depending on your project and they should always be considered ahead of time. In the next installments of this blog we will give some basic examples that touch on these questions as well.
In the second and third installments of this series, we will discuss:
- Creating a basic GitHub Action to build and test our project
- Taking our build output and deploying it to several locations
Continuous Integration has become pretty mainstream in software development, but If you’re not using CI, remember we’re here to help. Follow our continuing blog article series or reach for ideas on how to implement Continuous Integration and streamline your development process. Contact us today.