Originally posted on my blog at https://elliotdenolf.com/posts/build-net-core-applications-using-gitlab-ci
GitLab CI has the ability to utilize any docker container in order to build and deploy an application. This makes it an extremely flexible tool. This article will go through building out a GitLab CI pipeline for a .NET Core application.
First, let’s build out our basic application and test suite using the dotnet CLI. Create a new directory for your project and go through the following commands:
mkdir MyApp MyApp.Tests cd MyApp dotnet new webapi cd ../MyApp.Tests dotnet new nunit cd .. dotnet new sln dotnet sln add **/*.csproj
We’ve now built out a basic application and test suite to use in our pipeline.
Before we move forward, here is our simplified project structure:
. |-- MyApp | |-- MyApp.csproj | |-- Program.cs | `-- Startup.cs |-- MyApp.Tests | |-- MyApp.Tests.csproj | `-- UnitTest1.cs `-- MyApp.sln
GitLab CI is driven by having a
.gitlab-ci.yml file at the root of the project. Create this file now. The first thing we will put into this file is our base image
This is the official dotnet core image from Microsoft. It includes the latest .NET Core SDK, which provides everything needed to build out an application. A container running this image will be where our scripts will run and application code cloned into.
Next, we define our stages. We will be building out 3 distinct stages: build, test, and release. Those are added by adding this block:
stages: - build - test - release
Now that our stages are set up, we can add build steps and associate them with our defined stages. We just happen to want a single step for each of the build and test stages.
Let’s add the build step that will build via the dotnet CLI:
build: stage: build script: - dotnet build
The top-level value can be named anything you’d like. If you only have one step per stage, keeping them the same name keeps things simple. However, the
stage value must specify one of the listed stages from above. This is how GitLab CI knows what stage to run this step on.
If the build stage succeeds, we want our unit tests to run. The following block will run the test command via the dotnet CLI:
test: stage: test script: - dotnet test
The release step will be more complex than the previous because we will be using the dotnet publish command along with capturing the generated artifacts. This is the release block:
release: stage: release only: - master artifacts: paths: - publish/ script: - dotnet publish -c Release -o ../publish MyApp/MyApp.csproj
Let’s break down each piece of this step.
onlysection specifies that this step will only run on our master branch. This is to avoid generating artifacts for feature branches
- The artifacts path points to our intended output directory
dotnet publishcommand outputs into a
publishdirectory at our project root. Make note of the
../before publish as the dotnet publish command outputs relative to the
csprojfile that is specified, so we want the artifacts to be output one directory up at the root.
.gitlab-ci.yml file should now look like this:
image : microsoft/dotnet:latest stages: - build - test - release build: stage: build script: - dotnet build test: stage: test script: - dotnet test release: stage: release only: - master artifacts: paths: - publish/ script: - dotnet publish -c Release -o ../publish MyApp/MyApp.csproj
If we commit this code and navigate to CI/CD -> Pipelines in our GitLab repository, we will be able to see a pipeline that ran for the commit. If successful, each step will have a green check and artifacts will be available for download. If there was a failure, it will be a red X that can be clicked on to see more detail.
Additional steps can be added beyond what I’ve provided, but they would differ greatly based upon your environment. This application could easily be put into a Docker image and pushed either to the GitLab image registry or your Kubernetes cluster. However, that would warrant an entire article on its own. You now have a basic CI pipeline for your .NET Core application!