Github Actions : Building your first workflow

Github Actions allows to create custom workflows to automate our development processes. In this series, we will walkthrough the creation of a workflow of a Web API which was build using .Net Core.

Do note that Github supports the developers using Custom templates, but since we are attempting to learng more on the Actions, let us build it from scratch.

Workflows

Workflows are automated process which could be triggered by actions such as a Push or Pull Request (among others), and could assist us to build, test, package, and deploy any projects. They are defined using the YAML Syntax.

You could create more than one workflow for your repository. All the workflow definitions must be stored under the .github/workflows repository.

Creating your first workflow

The first step required to create the workflow is of course, create the required definition file. So let us create our workflow definition file in the path .github/workflows/firstworkflow.yml.

  • Workflow Name

The first thing a workflow need is a name to identify it. Remember, we could have multiple workflows for the repository and it would be greatly helpful if we have some identifier to recognize the workflow. The workflow name could be stated using the name key in the first line of the workflow file.

name: Web API

  • What triggers the workflow

The second question that we need to answer is what triggers the workflow. The workflow requires a trigger action, this could be

  • Push to the repository
  • Pull Request
  • A Scheduled Event
  • An external event

For the starters, we will concentrate on the first two. We will address the Scheduled and external events later.

To begin with, let us assume, we need to trigger the workflow for every Push to the repository, irrespective of the branch. You could specify this by using the following.

# Workflow Name
name: Web API

# What triggers the workflow
on: push

Most often that not, you would like the workflows to be triggered only when a push has been done in the master branch. You could specify so by using the following.

# Workflow Name
name: Web API

# What triggers the workflow
on:
  push:
    branches: [master]

The above workflow would be triggered only when there is a Push to the master branch.The square brackets [] are used to signify a list. So if you would like to trigger the workflow in more than one branch, you could specify so by mentioning the branch name within the braces along with master.

In most development cycles, instead of a push, you would like to trigger the workflows only when a Pull Request is raised on master branch.

You could specify so by altering your workflow as

# Workflow Name
name: Web API

# What triggers the workflow
on:
  pull_request:
    branches: [master]

Now, the workflow would be triggered only on a Pull Request raised against the master branch.

  • Runner

Github supports a variety of Runners covering Linux, Windows and MacOS runners. Jobs are run on a fresh instances of a virtual machine.

You could choose the runner by using the runs-on key. For example,

runs-on: ubuntu-latest

The above code specifies that our code needs to be build on a latest version of Ubuntu runner.

You could also test across multiple operating systems using the build matrix. But let us explore that on a later day, as we focus on building a basic workflow action for our Web Api. Once we equipped with the basics, we could later customize the scripts for better efficiency.

  • Jobs

Jobs groups a set of steps that executes on the same runner. Workflows could have multiple Jobs and each job could be run seqeuentially or parrellely.

jobs:
  BuildWebApi:
    name: Build Web Api

  • Checkout

You have so far set the name of work flow, specified the event on which the workflow needs to be triggered and also mentioned the environment to run it on. But where is the code ?

The next step involve retrieving your code. This is done using the checkout action, a standard action provided by the Github community to retrieve your code.

Actions are individual tasks that you combine as steps to create a job. Actions are the smallest portable building block of a workflow. You can create your own actions, use actions shared from the GitHub community, and customize public actions. To use an action in a workflow, you must include it as a step.

Let us go ahead and check out the code using the checkout action.

- uses: actions/checkout@v2

More details of the checkout action could be found here.

  • Setup .Net Core.

Of course you need .Net Core in your Runner environment to build the application. We could use an action to set up .Net Core in your runner.

- name: Setup .NET 5
  uses: actions/setup-dotnet@v1
  with:
    dotnet-version: 5.0.100-preview.6.20318.15

With the above, we have asked the setup-dotnet@v1 action to install .Net 5 cli in the runner machine.

  • Build

Once you have the code and the environment, you are all set to build your code. You can use the dotnet build to build your solution.

- name: Build Web Api
  run: dotnet build --configuration Release

  • Execute Unit Tests

Just like the Build, you could use the dotnet test command to execute the unit tests.

- name: Execute Unit Tests
  run: dotnet test --no-restore --verbosity normal

  • Conditional Execution

Ideally, you could want to execute your Unit Tests only if your build has succeeded. You could achieve this with the Job Status Check Functions.

For example, the following would return true only when none of previous step has failed or cancelled.

if: ${{ success() }}

We could integrate it with our Unit Test execution as the following.

- name: Execute Unit Tests
  if: ${{ success() }}
  run: dotnet test --no-restore --verbosity normal

We have set up the our basic workflow for our Web Api. The complete workflow looks like following.

name: .NET Core

on:
  pull_request:
    branches: [master]

jobs:
  BuildWebApi:
    name: Build Web Api
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Setup .NET Core
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: 5.0.100-preview.6.20318.15
      - name: Build Web Api
        run: dotnet build --configuration Release
      - name: Execute Unit Tests
        if: ${{ success() }}
        run: dotnet test --no-restore --verbosity normal

That’s it for now, we will explore more on Git Actions in the later blogs. Have a great day.