(+359) 888017004
pl. "Tsentralen" 1, Plovdiv, Bulgaria, 4000

Blog Details

Continuous integration and continuous delivery (Linux, Windows, Docker) – CI/CD For .Net Developers

I am writing this by the end of 2017 and I am glad that my days run behind visual studio 2017 and the new .net core 2.0. Now its more than easy for the developers to do their job and not be bother from problems that we all know like: Yesterday that was working… VS2017 now fully supports docker, and the pipeline from developing to production can be so automated, that every developer has possibilities to release enormously big projects only with a good idea in his head and a little bit of time.

In this article I will write about continues integration provided by the 2 main building process in Github universe:

I will show examples of configuration the build environments, publishing the projects to Artifacts (from AppVeyor Windows build process) and pushing to docker hub (from TravisCI Linux build process).

For the “Old School” Servers, continues delivery will be made using Web Publish Profiles. This will be carried allay after AppVeyor build process is success and will be different depending on the branch that the Pull Request is created.

For Docker based servers after the build process is success depending on the branch, the project will be published and then pushed to docker hub. After that all the servers will be updated with only one command.

This integration will completely automate the process from Creating the Pull Request in Github to Updating all needed servers and even the docker based one.

Let’s begin from Github

For start I will assume that you already know something about GitFlow, so we will directly start from 2 created branches for our repository: master and develop.

Master branch is locked for commits and the only code that is going in is merges from develop branch.

Develop branch is locked for direct commits too. The only code that is going in is from Pull Requests from features branches and bugfix branches.

You can find this settings in your repository in Github: Settings > Branches > Edit > Branch protection

Adding CI/CD with AppVeyor

For sign in you can use your existing Github account, after that you can add your project. For every project AppVeyor will configure webhooks for its repository to automatically start a build when you push the changes.

Next step is to create appveyor.yml file which is a project configuration file in YAML format that should be placed in the root of your repository. After build is triggered, the project will be published in different folders which after that will be used for creating the zip artifacts.

version: 1.0.{build}
image: Visual Studio 2017
clone_folder: C:\projects\MyProject\
  project: C:\projects\MyProject\MyProject.csproj
  verbosity: minimal
- ps: >-
    dotnet publish -c Release -o "C:\projects\MyProject\MyProjectRelease"
    dotnet publish -c Develop -o "C:\projects\MyProject\MyProjectDevelop"
- path: MyProjectRelease
  name: MyProjectRelease
- path: MyProjectDevelop
  name: MyProjectDevelop

Push the file to your repo and you will see that the Building process in AppVeyor is triggered.

Now go to Environments and add your server with Environment name – “QA”. The only important thing here is to add the correct artifact name that will be used for deployment to this server: “MyProjectDevelop”

Do the same thing for production – Environment name – “Production”, Artifact to Deploy: “MyProjectRelease”

Then just add this lines to your appveyor.yml and push the changes.

- provider: Environment
  name: QA
    branch: Develop
- provider: Environment
  name: Production
    branch: Master

Adding CI/CD with TravisCI

Like AppVeyor for sign in you can use your Github account. Once you’re signed in to Travis CI, and synchronization is done with your GitHub repositories, go to your profile page and enable the repository you want to build.

Add a .travis.yml file to your repository to tell Travis CI what to do (in root of the repo). The following example tells Travis CI that this is .NET Core 2.0.0 project, we need docker service and there is 2 scripts that will be executed for build and deployment.

language: csharp
dist: trusty
solution: MyProject.sln
mono: none
sudo: false
dotnet: 2.0.0
  - docker
  - chmod +x ./*.sh
- ./build.sh
- ./push_to_docker.sh

Then add first script “build.sh”

set -ev

dotnet publish MyProject/*.csproj -c Release -f netcoreapp2.0 -o ../myprojet_release

Then the second script “push_to_docker.sh” which uses Username (TD_DOCKER_USERNAME) and Password(TD_DOCKER_PASSWORD) for Docker hub. You should add this values to Environment Variables in TravisCI.

set -ev

docker build -t myprojet_release -f myprojet/Dockerfile .


docker tag myprojet_release MyUsernameDocker/myprojet_release:1.2.$TRAVIS_BUILD_NUMBER-$TRAVIS_BRANCH

docker push MyUsernameDocker/myprojet_release:1.2.$TRAVIS_BUILD_NUMBER-$TRAVIS_BRANCH

Finally add new file to you project root folder “Dockerfile”, without any extension:

FROM microsoft/aspnetcore:2.0
COPY myprojet_release /app
ENTRYPOINT ["dotnet", " MyProject.dll"]

This tells Docker to:

  • Build an image starting with the aspnetcore image.
  • Set the working directory to /app.
  • COPY new files or directories from “myproject_release” and adds them to the filesystem of the container at the path “/app”.
  • An ENTRYPOINT will configure a container that will run as an executable.

Push your changes and watch the magic!

That’s it!

Your CI/CD Pipeline is configured and you’re fully ready to write code and deploy with confidence. Every time when new code is pushed, the build processes will trigger, and you will know when something is broken in different operating systems and environments. Every time when new pull request is merged to Master or Develop branch, the code is checked and after success your docker cloud and your servers will be updated with the changes and you don’t have to worry about!

Leave a Reply