0

I have a .NET 6.0 Web API and want it to know its version. To publish the Docker images I use Github Actions docker/build-push-action@v3.1.0. I tried using MinVer which would exactly meet my needs as it is using the latest git version tag and adds the number of commits since that version as last digit. But as the docker/build-push-action@v3.1.0 does not have the full Git environment, Minver can not extract the version number of the Git tags while the image is built. It would be possible to use a CLI tool to extract the version before creating the Docker image:

    - name: install minver-cli
      run: dotnet tool install --global minver-cli

    - name: get version
      run: echo "MINVERVERSIONOVERRIDE=$(minver --tag-prefix v --verbosity e)" >> $GITHUB_ENV 

    - name: echo environementvariable
      run: echo ${{ env.MINVERVERSIONOVERRIDE }}

If MINVERVERSIONOVERRIDE does exist as environment variable at build time, MinVer does not try to extract the version of the git history but just use that version. But it does not look like this environment variable exists in the docker/build-push-action@v3.1.0.

Is there any other way to use version numbers based on the git tags when creating a Docker image?

Adam Ralph
  • 29,453
  • 4
  • 60
  • 67
Patrick
  • 173
  • 9

3 Answers3

3

Your issue is that the Github Actions checkout action uses 1 as the default value for the fetch-depth argument which means that your workflow has only the latest commit available. If the latest tag is not on this commit, minver will not find it.

The solution is to set fetch-depth to 0 (for fetching all commits in the repo) or any other appropriate value. See here for more details.

Edited on Aug 26th 2022 as per the below comments:

First, you write that if MINVERBUILDMETADATA is set, MinVer will not try to calculate the version again. This is wrong. It's the MINVERVERSIONOVERRIDE environment variable which has to be set for this purpose.

Said this, this is how you can pass the calculated version value into the container image:

Put this step somewhere above the docker/build-push-action action in your workflow yml file:

- name: Calculate version
  uses: thefringeninja/action-minver@2.0.0-preview1
  id: version
  with:
    tag-prefix: v

Then pass the version as a build argument to the docker file like this:

- name: Build and push Docker image
  uses: docker/build-push-action@v3
  with:
    build-args: MINVERVERSIONOVERRIDE=${{ steps.version.outputs.version }}

Finally use the value in your Dockerfile by adding the following line between the FROM and where you build your project:

ARG MINVERVERSIONOVERRIDE

Background:
ARG sets an environment variable which is available when building the docker image.

TOG
  • 106
  • 9
  • This is already done and extracting the version with CLI is already working. Also creating an environment variable is working but this variable is not existent inside the docker build and push action – Patrick Aug 24 '22 at 15:04
  • Sorry, I think I missread your question. I will update my answer accordingly. – TOG Aug 26 '22 at 06:21
  • As there is no update to `thefringeninja/action-minver@2.0.0-preview1` and [Github will disable the `set-output` command](https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/) on 31st May: Is there any alternative for that? – Patrick May 14 '23 at 14:17
  • @Patrick I asked this here: https://github.com/thefringeninja/action-minver/issues/20 Personally I moved away from using the `thefringeninja/action-minver` (in a way that I do not need to evaluate the version in the workflow again). – TOG May 15 '23 at 15:11
  • I added a new answer below, where I resolved it using the minver CLI. – Patrick May 15 '23 at 19:09
1

As thefringeninja/action-minver@2.0.0-preview1 mentioned in https://stackoverflow.com/a/73472371/8587966 uses set-output which will be disabled on 31st May 2023 I now use the following:

steps:
- name: Checkout
  uses: actions/checkout@v3
  with:
    fetch-depth: 0

- name: Setup dotnet
  uses: actions/setup-dotnet@v2
  with:
    dotnet-version: '7.0.x'

- name: Install minver CLI
  run: dotnet tool install --tool-path ./minver minver-cli --version 4.3.0
      
- name: Calculate version using minver CLI
  id: version
  run: |
      echo "version=$(./minver/minver --default-pre-release-identifiers alpha --tag-prefix v)" >> "$GITHUB_ENV"

- name: Build and push Docker Image
  uses: docker/build-push-action@v4
  with:
    build-args: MINVERVERSIONOVERRIDE=${{ env.version }}
    file: ./projectName/Dockerfile
    platforms: linux/amd64,linux/arm64,linux/arm/v7
    push: true
    tags: user/imagename:latest
Patrick
  • 173
  • 9
  • Good idea. Thanks for sharing. Maybe I'll use this approach as well in the future. – TOG May 17 '23 at 04:58
0

2023 Update:

It became easier with dotnet publish being able to build and push container images without Dockerfile.

First, add a package reference for container build:

<PackageReference Include="Microsoft.NET.Build.Containers" Version="7.0.302"/>

Keep in mind that there will be new versions, so you can just add the NuGet package using dotnet CLI or your IDE.

Then, add this section, so it runs after MinVer:

<Target Name="Container" AfterTargets="MinVer">
    <PropertyGroup>
        <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
        <ContainerImageName>foo/bar</ContainerImageName>
        <ContainerImageTags>$(MinVerVersion);latest</ContainerImageTags>
        <ContainerRegistry>registry.hub.docker.com</ContainerRegistry>
    </PropertyGroup>
</Target>

Run publish:

dotnet publish --runtime linux-x64 -p:PublishProfile=DefaultContainer --self-contained

You can also put the container runtime as a property to the same property group like this, my example doesn't have it as I build for different architectures and push the combined manifest manually using Docker.

<ContainerRuntimeIdentifier>linux-x64</ContainerRuntimeIdentifier>
Alexey Zimarev
  • 17,944
  • 2
  • 55
  • 83