Azure Sprint Series Logo

Challenge 2: Create a Build Workflow

With the code loaded, it's now time to make sure the code works! Your task is to validate the code builds correctly using GitHub Actions. DevOps concepts covered:

This challenge is focused on building an Continuous Integration (sometimes known as CI or Build) workflow that will compile your code, run unit tests and package up the code, ready for release.

Having the code working on your device is great for testing, but we need to deploy this solution so our users can also test it!

GitHub hosts build agents that can build your code and package it up ready for release. Having code built using these build agents allows code to be built in a consistent and repeatable fashion, ensuring only proper code goes into the build.

Having the compiled code packaged up at this step also helps to enforce the same code is being tested in a staging environment before it is deployed to production.

For the following exercises you may choose to collaborate on a single build workflow, or each team member can create their own build workflow:

Exercise 1

We will be creating a YAML workflow that defines the build process for our code. Manually executing a build workflow when code is updated can be tedious if your code changes often. Fortunately, GitHub Actions contain functionality to automate this process for you.

  1. Create a YAML workflow to build your code and produce artifacts for deployment.
  2. Setup a build trigger to ensure that the workflow runs when:
    • Any changes are made to the main branch

Hints

  - name: List out directory contents
    run: |
        echo "Listing the contents of the GitHub workspace directory"
        ls ${{ github.workspace }}

        echo "Recursively listing all contents of the current directory"
        ls -R

Helpful resources

Exercise 2

In order to support the GitHub flow pattern, pull requests should trigger your build workflow, that way you know the changes will be deployable before they are integrated. Automated testing to ensure code quality and integrity by running tests as part of the workflow should also be added.

  1. Set up automatic builds on the master branch and any time a pull request is made.
  2. (Optional) Add some new unit tests to the AnimalAdoption.Web.Portal.UnitTests project.
  3. Update your build workflow to have a step where unit tests are run to reduce the chance that code changes introduce bugs in the future.

Hints

Helpful resources

Exercise 3 (Optional)

You may have noticed that the web portal project contains a solution named AnimalAdoption.Common.Logic. This package holds all the important business logic required for the website to function.

Tailspin Animal Adoptions has plans to move to a microservices architecture in the future, however, they want to reuse the existing logic found in this project.

As this "Logic Library" is not in the same repository as the repository they want to use, they are unable to use that library unless they clone all the code in your repository. This also makes it a bit more complicated as they want to ensure that they test any changes to the library. This means that they can't just grab the latest master branch.

We can resolve these issues by packaging up AnimalAdoption.Common.Logic in the build process and publishing them as a NuGet package to a GitHub Packages Repository (GPR). The resulting package can be versioned and consumed as NuGet packages by other teams that have access.

  1. Add the required entries inside the <PropertyGroup> section of the logic library AnimalAdoption.Common.Logic.csproj file.
    <Version>1.0.0</Version>
    <RepositoryUrl>https://github.com/(your-organisation-name)/(your-repo-name).git</RepositoryUrl>
    <RepositoryType>git</RepositoryType>
  1. Update your build pipeline to publish the logic library to a GPR as a NuGet package.
  2. Confirm that a package was published to your organization.
  3. Optional: Update the workflow to only push your package if running on the master branch.

Hints

Helpful resources

Spoilers


Spoiler

    # Set these variables at either the step or workflow level
    env:
      GitHubPackageFeedUrl: https://nuget.pkg.github.com/(your-organisation-name)/index.json
      LogicProjectPath: ${{ github.WORKSPACE }}/AnimalAdoption.Common.Logic

    # Authenticates packages to push to GPR
    - name: Setup .NET Core @ Latest
      uses: actions/setup-dotnet@v1
      with:
        source-url: ${{ env.GitHubPackageFeedUrl }}
      env:
        NUGET_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GitHub automatically creates a GITHUB_TOKEN secret to use in your workflow

    - name: Package up project
      run: dotnet pack --configuration Release ${{ env.LogicProjectPath }}

    - name: Push package to GitHub registry
      run: dotnet nuget push ${{ env.LogicProjectPath }}/**/*.nupkg --skip-duplicate

Exercise 4

Now that we have a number of processes building, testing, publishing and releasing our code, we want to be notified of potential issues. Make sure that build email notifications are enabled. These may also be enabled by default.

One of the downfalls of email notifications is that it is hard for the rest of the team to see actions taking place as a result of the notification. GitHub also supports connecting to Microsoft Teams.

  1. Check your inbox (using the credentials you were provided) and see if you have been receiving build workflow emails: mail.office365.com.
  2. Setup a GitHub Connector in your team's channel for various types of alerts (e.g. Pull Requests, Build Failures, Issues created etc.)
  3. Trigger your workflow and test that the expected alerts are created in your team's channel.

Hints

Helpful resources

Extra for experts

Using the pre-built connectors doesn't allow you to get notifications for events such as workflow/pipeline failures or completions. To enable build success and failure notifications for your repository using this GitHub Action, complete the following steps:

  1. Create an Incoming Webhook for the channel you would like the notifications in using the instructions here.
  2. Paste the following steps at the end of your build job:
    - name: Notification for build failure
      uses: jdcargile/ms-teams-notification@v1.3
      if: failure()
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        ms-teams-webhook-uri: ${{ secrets.MS_TEAMS_WEBHOOK_URI }}
        notification-summary: BUILD FAILED
        notification-color: 'dc3545 '

    - name: Notification for build success
      uses: jdcargile/ms-teams-notification@v1.3
      if: success()
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        ms-teams-webhook-uri: ${{ secrets.MS_TEAMS_WEBHOOK_URI }}
        notification-summary: BUILD SUCCEEDED
        notification-color: '28a745'
  1. Review the instructions here for any additional steps.
  2. Commit your changes and watch the notifications appear.
  3. (Optional) Add support for deployment notification using this action