7

I am trying to build my .net core app using Docker. And I want to override my app version during build. To display it somewhere later in runtime.

I have my Docker file looks like this:

FROM microsoft/dotnet:2.2-sdk AS build-env
WORKDIR /src

RUN apt-get update && \
    apt-get install -y libgit2-dev && \
    ln -s /usr/lib/x86_64-linux-gnu/libgit2.so /lib/x86_64-linux-gnu/libgit2-15e1193.so

COPY ..

WORKDIR /src/API

RUN dotnet restore

RUN dotnet tool install -g GitVersion.Tool --version=5.0.0-beta1-72

RUN export PATH="$PATH:/root/.dotnet/tools" && \
    version="$(dotnet gitversion /output json /showvariable NuGetVersion)" && \
    dotnet build --no-restore /property:Version=$version  && \
    dotnet publish --output "/app" --no-build

FROM microsoft/dotnet:2.2-aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app .
ENTRYPOINT ["dotnet", "API.dll"]

When I tried the same commands like in RUN instructions on my Windows machine - everything is OK. I also tried to run the same commands on WSL (Ubuntu 18) and it's also fine - I have assembly version from my build command. But I can't figure out why it is not working inside Docker.

I've also tried to remove all my GitVersion magic and use just this:

FROM microsoft/dotnet:2.2-sdk AS build-env
WORKDIR /src

RUN apt-get update && \
    apt-get install -y libgit2-dev && \
    ln -s /usr/lib/x86_64-linux-gnu/libgit2.so /lib/x86_64-linux-gnu/libgit2-15e1193.so

COPY ..

WORKDIR /src/API

RUN dotnet restore

RUN dotnet build --no-restore /property:Version=1.1.1.0-beta1
RUN dotnet publish --output "/app" --no-build

FROM microsoft/dotnet:2.2-aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app .
ENTRYPOINT ["dotnet", "API.dll"]

Anyway, my results are the same.

I use this code to check:

public static void Main(string[] args)
{
    Console.WriteLine(typeof(Program).Assembly.GetName());
}

Every time my build is a success but I have version defined in .csproj file without override.

Alex Lyalka
  • 1,484
  • 8
  • 13
  • 1
    Can you be more specific than "not working"? What **precise** behavior are you encountering? – Daniel Mann Feb 25 '19 at 21:25
  • Every time my build is a success but I have version defined in .csproj file without override. – Alex Lyalka Feb 25 '19 at 21:26
  • Looks like the expected argument is `-p` for properties to pass to msbuild as opposed to `/property`. The handling of these may be different between the linux and windows command line perhaps? – Eric Damtoft Feb 25 '19 at 21:48
  • I believe both are allowed here. I've just checked with -p in my dockerfile and I have the same results. I used \p as in MS docs. If flags that are not allowed is present dotnet build will throw an error. I also checked it on Linux (WSL) and both are OK. – Alex Lyalka Feb 25 '19 at 22:10
  • Have you tried using `VersionSuffix` instead: https://github.com/dotnet/cli/issues/3778 ? – omajid Feb 25 '19 at 22:14
  • It is not acceptable in my case I need to override all version data. VesrionSuffix will be just `-beta1` in my example. – Alex Lyalka Feb 25 '19 at 22:19
  • I will try and let you know – Alex Lyalka Feb 25 '19 at 22:20
  • It is not working either. I checked it is not reflected in assebly version and in {System.Reflection.AssemblyInformationalVersionAttribute} also. I bet it will change my version if I ran it in PowerShell. – Alex Lyalka Feb 25 '19 at 22:35
  • @AlexLyalka was this problem somehow solved? I bet it happens because of some optimization for docker, but how to override them? – Vladimir Dec 15 '19 at 14:35

3 Answers3

7

Yes, it should be a trivial task but I also ran into a few issues before I finally could do it. Spent a few hours to solve the issue, hope you can save time. I recommend to read this post it helped.

My final solution was to use a Docker ARG, you must be declare it before the first FROM:

#Declare it at the beginning of the Dockerfile
ARG BUILD_VERSION=1.0.0
...
#Publish your project with "-p:Version=${BUILD_VERSION}" it works also with "dotnet build"
RUN dotnet publish "<xy.csproj>" -c Release -o /app/publish --no-restore -p:Version=${BUILD_VERSION}

One very important thing to Note: is if you are using multistage build (multiple FROM in your file) you have to "re-declare" the ARG in that stage. See a similar question here.

Finally you can call your Docker build with:

docker build --build-arg BUILD_VERSION="1.1.1.1"
Bernard Vander Beken
  • 4,848
  • 5
  • 54
  • 76
Major
  • 5,948
  • 2
  • 45
  • 60
  • Why don't just put ARG command right before the line variable used without any "re-declare"? – SerG Jan 20 '21 at 10:53
4

I encountered the same problem, after a long time of debugging I managed to figure out the cause.

RUN dotnet build --no-restore /property:Version=1.1.1.0-beta1 -o &&
RUN dotnet publish --output "/app" --no-build

In example, assemblies created by dotnet build have the correct Version number -1.1.1.0-beta1. Hovewer the command dotnet publish overrides the desired Version number by value taken from the .csproj file.

This is the reason, why Major answer works. Properties are set to dotnet publish.

RUN dotnet publish "<xy.csproj>" -c Release -o /app/publish --no-restore -p:Version=${BUILD_VERSION}
Natan
  • 180
  • 7
1

In order for GitVersion to work correctly, it needs more information from the git repository which isn't available inside your Docker image.

You could try, inside of your docker image, cloning the single branch from the git repo being built:

git clone -b <branch> <remote-repo>

However, when doing this, DO NOT use the --single-branch parameter. The command above, in addition to cloning a specific branch from a remote repository, also fetches all the heads of other branches, which GitVersion requires in order for it to perform its version calculations. (See the Agent Setup heading in the TeamCity Setup documentation for GitVersion which explains this).

fourpastmidnight
  • 4,032
  • 1
  • 35
  • 48