This should be simple right? Even with the new yaml
pipeline editor, you should be able to do the old ‘build and push’ and fire a few arguments in. Nope. Doesn’t work. Here’s how you can do it…
The background around this problem is that I want to add in some custom logic around Assembly Info in our build pipeline, so we have a .sh
file that will edit the .csproj
file and update the AssemblyVersion
elements. (I know there are possibilities for doing this with wildcards etc… but I want to do it this way, for reasons)
The script is very simple
#!/bin/sh
echo "Running version updater..."
while getopts 'm:n:b:r:' flag
do
case ${flag} in
m) MAJOR=${OPTARG};;
n) MINOR=${OPTARG};;
b) BUILD=${OPTARG};;
r) REVISION=${OPTARG};;
esac
done
PROJECTPATH="./API/my-api-project.csproj"
TOREPLACE="0.0.0.0"
REPLACEMENT="${MAJOR}.${MINOR}.${BUILD}.${REVISION}"
echo "Major: ${MAJOR}"
echo "Minor: ${MINOR}"
echo "Build: ${BUILD}"
echo "Revision: ${REVISION}"
echo "Replacement: ${REPLACEMENT}"
sed -i "s/$TOREPLACE/$REPLACEMENT/" $PROJECTPATH
echo "Completed version updater..."
It will take 4 arguments, and use that to create our AssemblyVersion
attribute. This attribute is processed when you build a dotnet project to create an auto generated AssemblyInfo.cs
file. It just lives in a PropertyGroup
of our project file (I have it set to all zeros to make easy to replace with sed
)
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<LanguageVersion>9.0</LanguageVersion>
<!-- This is updated as part of dev ops pipelines -->
<AssemblyVersion>0.0.0.0</AssemblyVersion>
</PropertyGroup>
As we host our webapps in containers, this is run from within our dockerfile
, so we push those in as dockerfile
ARGS
then we run our script before we do build/publish etc. The changes happen to the source in the intermediate build environment container that is disposed, so our source in git
is never changed.
...
ARG major
ARG minor
ARG build
ARG revision
RUN sh ./updateVersion.sh -m $major -n $minor -b $build -r $revision
...
So, I used the autocomplete in azure’s yaml editor to add the args, as you would expect (and totally didn’t go through about 20 iterations of how to correctly format these arguments).
This is how the azure pipeline yaml
looks for that step. The values exist as variables in the Pipeline so they are accessed with the standard $(VariableName)
format.
- task: Docker@2
displayName: 'Build and Push Docker Image'
inputs:
containerRegistry: 'MY Container Registry'
repository: 'my-repo/my-image'
Dockerfile: dockerfile.api
tags: |
latest
$(Build.BuildId)
arguments: '--build-arg major=$(BuildMajor) --build-arg minor=$(BuildMinor) --build-arg build=$(Build.BuildId) --build-arg revision=$(BuildRevision)'
Awesome right, I’ll tag it with the build id, latest, build it and push it up. Autocomplete gave me the various options, so it should just work!?
Jokes it doesn’t work.
After many many builds I finally logged out what I was actually getting, and the .sh
file is showing that it’s not getting any arguments passed in? How can this be? It works on my machine at the command line!
Well.. the crux of it is, that Azure DevOps’ “Build and Push
” task doesn’t accept arguments, even though it will happily suggest it, and won’t throw any errors. The solution is to split out the Build and Push steps into separate tasks, as only the build task will accept arguments.
Now the yaml looks like this:
- task: Docker@2
displayName: 'Build'
inputs:
command: build
containerRegistry: 'MY Container Registry'
repository: 'my-repo/my-image'
Dockerfile: dockerfile.api
tags: |
latest
$(Build.BuildId)
arguments: '--build-arg major=$(BuildMajor) --build-arg minor=$(BuildMinor) --build-arg build=$(Build.BuildId) --build-arg revision=$(BuildRevision)'
- task: Docker@2
displayName: Push
inputs:
command: push
containerRegistry: 'MY Container Registry'
repository: 'my-repo/my-image'
tags: |
latest
$(Build.BuildId)
Boom! The API now has all the details that I pass in baked into the assembly info of the API.
I am aware this is a long way to write “Split it out into separate tasks” but I figured it wouldn’t hurt to have a few bits and bobs to copy/paste.
All the best.
Hearty thanks for sharing this; no idea how much further down the troubleshooting rabbit hole I’d have found this.
LikeLiked by 1 person
Glad to help mate, it was a bit of a pain finding it
LikeLike
This is what I was looking for
LikeLike