Using GitVersion with CircleCi and Docker

Sunday, January 17th 2021

Using GitVersion with CircleCi and Docker

Versioning your deliverable is important. Too often however, this requires that one remembers to update a series of files to do so, resulting in a dedicated versioning commit. Thankfully, there are ways around that such as GitVersion, a utility that leverages Git to help you version your system.

I chose to give GitVersion a try on a recent .NET project to version both the executables and the Docker images. My setup consisted of having a GitVersion.yaml file with my chosen versioning strategy which is used to create a version.json file on the CI.

mode: Mainline
increment: Patch
ignore:
  sha: []
merge-message-formats: {}
# CircleCI config.yml
version: 2.1

orbs:
  windows: circleci/windows@2.2.0
  azure-acr: circleci/azure-acr@0.2.0

workflows:
  build_and_push:
    jobs:
      - versioning
      - build_test:
          context: KOZI
          requires:
            - versioning
      - package_publish:
          context: KOZI
          filters:
            branches:
              only:
                - master
          requires:
            - build_tes
jobs:
  versioning:
    executor:
      name: windows/default
    steps:
      - checkout
      - run: dotnet tool install GitVersion.Tool --global
      - run: dotnet-gitversion > version.json
      - store_artifacts:
          path: version.json
      - persist_to_workspace:
          root: ./
          paths:
            - version.json

  build_test:
    docker:
      - image: mcr.microsoft.com/dotnet/core/sdk:3.1
        environment:
          DEBIAN_FRONTEND: noninteractive
          DOTNET_CLI_TELEMETRY_OPTOUT: 1
    steps:
      - checkout
      - attach_workspace:
          at: ./
      # run whatever builf task you have that relies on having a version
      # don't forget to preserve the version.json if there are other jobs of your workflow that would rely on its content (e.g. a publish job)
      - persist_to_workspace:
          root: ./
          paths:
            - version.json

With the file created, I can now load it up as an environment variable for use with pushing my Docker image.

  package_publish:
    docker:
      - image: mcr.microsoft.com/dotnet/core/sdk:3.1
        environment:
          DEBIAN_FRONTEND: noninteractive
    steps:
      - checkout
      - attach_workspace:
          at: ./
      - run: apt-get -yq update && apt-get -yq upgrade
      - run: apt-get -yq install bash libcurl4 jq
      - setup_remote_docker
      - docker/install-docker
      - run:
          name: Update SEM_VER Environment Variables
          command: |
            echo 'export SEM_VERSION=`jq -r .NuGetVersionV2 version.json`' >> $BASH_ENV
            source $BASH_ENV
      - azure-acr/build-and-push-image:
          checkout: false
          login-server-name: myrepo.azurecr.io
          registry-name: myregistry
          repo: myrepo
          tag: $SEM_VERSION,latest
          dockerfile: dockerfiles/MyProject.Dockerfile

With this, no more remembering to update a version file.