Recently Micronaut 2.1 was published with yet another feature that makes us "end-developers" work even less. It's called "Gradle Docker Plugin" and you can check it out here. Micronaut has adopted this feature and Graeme (creator of Micronaut) posted this YouTube video explaining some features including how to use this Gradle plugin with Micronaut.
Prerequisites
I assume that you've setup Container Registry in Azure and have all connections set up properly to communicate between Azure DevOps and registry.
Also I hope you have a project with Micronaut 2.1 or greater version because this feature is only available starting from 2.1.0
Pipeline setup
My first reaction to this was "nice" and then I thought "Well how can use this to tag images with other than latest default tag while using Azure Pipelines". Thing is that in order to make a custom tag I did something like this
dockerBuild {
images = ["myproject:$project.version","myproject:latest"]
}
but azure-pipelines.yaml will contain by default something like this as a task for deploying
- task: Docker@2
displayName: Build and push an image to container registry
inputs:
command: buildAndPush
repository: $(imageRepository)
dockerfile: $(dockerfilePath)
containerRegistry: $(dockerRegistryServiceConnection)
tags: |
$(tag)
but that $(tag) variable is hard-coded to read from something like '$(Build.BuildId)' which is not something very useful to tag your own images with because you probably want to track your own versions. Top of your pipeline yaml should have something like below config
variables:
# Container registry service connection established during pipeline creation
dockerRegistryServiceConnection: 'some-uuid-some-uuid'
imageRepository: 'yourAzureImageRepository'
containerRegistry: 'yourAzureIMageRepoistory.azurecr.io'
dockerfilePath: '$(Build.SourcesDirectory)'
tag: '$(Build.BuildId)'
# Agent VM image name
vmImageName: 'ubuntu-latest'
You can remove that tag: ... part, as we are trying to put our own info in there, and the dockerfilePath as we will build image with gradle so we don't need the Dockerfile.
Instead let's make a script that will extract version from our build.gradle file. Add a bash task before task buildDocker task. Something like this should give you version:
#!/usr/bin/env bash
version=$(grep '^version[[:space:]]*"\(.\)\+"$' build.gradle | awk '{print $2}')
echo "##vso[task.setvariable variable=version]$version"
then your task may look like this:
- task: Bash@3
inputs:
targetType: 'inline'
script: |
#!/usr/bin/env bash
version=$(grep '^version[[:space:]]*"\(.\)\+"$' build.gradle | awk '{print $2} | sed 's/"//g'')
echo "##vso[task.setvariable variable=version]$version"
Windows pipelines?
I made a script which should give you same result when your running your pipelines on Windows platform
$versionVal = Get-Content .\build.gradle | Select-String -Pattern '^version\s*\"(?<version>.+)\"$' | % { $_.Matches[0].Groups["version"].Value }
Write-Host "##vso[task.setvariable variable=version]$version"
I'm not 100% sure that it works I just tested it in PowerShell and I got the version number printed out so I guess it works :D.
Maven?
Well just check this link and adjust it accordingly. This is also a way to get some credits to the person who posted that answer as I saw this answer while looking out how to set up variable in Azure Pipeline from bash.
Tag the image
Because image was built inside Azure pipelines we need to tag it to make push command know where to push the image. Easy way to do it on Linux pipeline is using bash.
- task: Bash@3
inputs:
targetType: 'inline'
script: 'docker tag $(imageRepository):$(tag) $(containerRegistry)/$(imageRepository):$(tag)'
Sometimes you want your image to be tagged with latest because a lot people will configure (or leave by default) triggers that get activated only on this tag. So let's say you want your development to be the latest version but main or master to be specific version. Below task will activate only if branch name was 'development'.
- task: Bash@3
inputs:
targetType: 'inline'
script: 'docker tag $(imageRepository):$(tag) $(containerRegistry)/$(imageRepository):latest'
condition: eq(variables['Build.SourceBranch'], 'development')
You can read more about it here if you need to configure it differently
Push the image
- task: Docker@2
displayName: Build and push an image to container registry
inputs:
command: push
repository: $(imageRepository)
containerRegistry: $(dockerRegistryServiceConnection)
buildContext: $(containerRegistry)
tags: |
$(tag)
latest
If you didn't tag the image with the latest tag the whole pipeline will fail as there is no conditional statement. If you don't need it remove it completely.
Latest tag (optional)
If you need latest tag conditional this line should help.
${{ if eq(variables['Build.SourceBranchName'], 'development') }}:
tags: |
$(tag)
latest
${{ if ne(variables['Build.SourceBranchName'], 'development') }}:
tags: |
$(tag)
So task could look like this replacing branchNameGoesHeere with whatever your branch name should be:
- task: Docker@2
displayName: Build and push an image to container registry
inputs:
command: push
repository: $(imageRepository)
containerRegistry: $(dockerRegistryServiceConnection)
buildContext: $(containerRegistry)
${{ if eq(variables['Build.SourceBranchName'], 'development') }}:
tags: |
$(tag)
latest
${{ if ne(variables['Build.SourceBranchName'], 'development') }}:
tags: |
$(tag)
This should be it hope it work :D
Updates:
I've switched the logic for tagging images with latest as in most cases "latest" version is not the one to deploy nor keep on master/main branches. Obvious reason should be that deploying new code on push should only happen in development/testing environments while there must be a "manual" trigger to fetch the latest TESTED version that works properly and deploy it. Also prior example didn't actually work when having multiple tags and was missing tagging part so it's added now.
Top comments (0)