Gitversion always increment Patch not Minor version - azure-devops

I'm using Azure Devops Server and yaml pipeline for my Microservices deployment.
I have a requirement to do semantic versioning as below,
increment minor value when feature branch merge into main
increment patch when hotfix branch merge into main
I'm using Gitversion Extension 0.9.15.22102819 (Latest) for semantic versioning. Whenever I do any merge from feature or Hotfix branch, only patch value increments.
Could you please advice on the issue ?
Pipeline Yaml file:
trigger:
main
pool:
name: default
stages:
stage: One
variables:
#preventing git shallow clone
Agent.Source.Git.ShallowFetchDepth: 0
#. . rest of your pipeline
jobs:
job: DisplayGitversion
steps:
task: gitversion/execute#0
script: echo current version is $(GitVersion.MajorMinorPatch)
displayName: 'Dispaly calculated version'
task: PowerShell#2
inputs:
targetType: 'inline'
script: 'echo ##vso[build.updatebuildnumber]$(GitVersion.MajorMinorPatch)'
Gitversion.yml:
mode: Mainline
assembly-versioning-scheme: MajorMinorPatch
increment: Inherit
update-build-number: true
branches:
main:
regex: ^main$
is-mainline: true
feature:
mode: ContinuousDelivery
regex: ^features?[/-]
tag: useBranchName
increment: Minor
tracks-release-branches: false
is-release-branch: false
prevent-increment-of-merged-branch-version: false
hotfix:
mode: ContinuousDelivery
regex: ^(bugfix|hotfix(es)?)[/-]
tag: useBranchName
increment: Patch
ignore:
sha: []
merge-message-formats: {}
I confiugred the Gitversion.yml and pipeline to ger Semantic versioning,
But whatever branch it merge to main, it increments only patch value.

Related

Can an Azure pipeline have multiple pipeline resources referencing the same source?

I'm using the pipeline resource to trigger a second pipeline from a first pipeline. The two pipelines are in different repositories. They may even be in different projects.
This is the pipeline resource definition in the second pipeline.
resources:
pipelines:
- pipeline: xyz_build
source: company.xyz_source
trigger:
enabled: true
branches:
include:
- develop
- release/*
I want the second pipeline to take different actions, based on whether it was triggered by a build on the develop branch or a release branch. If an Azure pipeline can handle multiple pipeline resources which reference the same source, then I can rewrite my pipeline resources like this, and then choose different execution paths based on the value of $(Resources.TriggeringAlias).
resources:
pipelines:
- pipeline: xyz_develop_build
source: company.xyz_source
trigger:
enabled: true
branches:
include:
- develop
- pipeline: xyz_release_build
source: company.xyz_source
trigger:
enabled: true
branches:
include:
- release/*
Does this work in Azure Pipelines? Does Azure Pipelines support this?
EDITED TO ADD: It runs when I trigger it manually. I guess we'll find out what happens when somebody runs a build on xyz.source.
Update:
You can still capture the branch of the source resource from the different repo or even different project. But you can't set conditions at compile time to erase unnecessary tasks at the beginning of compilation(in the same repo, you can).
You can determine conditions at runtime to achieve the purpose of 'skip' tasks.
I provide an example here which have pipelines from two different projects, one for ProjectA and the other for ProjectB:
ProjectA
trigger:
- none
pool:
vmImage: ubuntu-latest
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
ProjectB
resources:
pipelines:
- pipeline: ProjectA
project: ProjectA
source: ProjectA
trigger:
enabled: true
branches:
include:
- develop
- release
trigger:
- none
pool:
vmImage: ubuntu-latest
jobs:
- job:
displayName: Handle ProjectA develop branch
condition: eq(variables['resources.pipeline.ProjectA.sourceBranch'],'refs/heads/develop')
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
# Write your PowerShell commands here.
Write-Host "Hello World"
Write-Host $(resources.pipeline.ProjectA.sourceBranch)
- job:
displayName: Handle ProjectA release branch
condition: eq(variables['resources.pipeline.ProjectA.sourceBranch'],'refs/heads/release')
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
# Write your PowerShell commands here.
Write-Host "Hello World"
Write-Host $(resources.pipeline.ProjectA.sourceBranch)
Original Answer:
For example, pipeline A trigger PipelineB
PipelineA
trigger:
- none
pool:
vmImage: ubuntu-latest
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
PipelineB
resources:
pipelines:
- pipeline: PipelineA
project: xxx
source: PipelineA
trigger:
enabled: true
branches:
include:
- develop
- release
trigger:
- none
pool:
vmImage: ubuntu-latest
steps:
- ${{ if eq(variables['Build.SourceBranch'],'refs/heads/develop') }}:
- script: echo "this is develop branch"
- ${{ if eq(variables['Build.SourceBranch'],'refs/heads/release') }}:
- script: echo "this is release branch"
Please make sure both branches have the above YML file(Pipeline will looking for the same name YML file in every branches).

Manually triggering Devops pipeline with pipeline resource should use latest resource pipeline run for that branch

I have 2 pipelines in the same repo:
Build
Deploy
The Build pipeline is declared as a pipeline resource in the Deploy pipeline:
resources:
pipelines:
- pipeline: Build
source: BuildPipelineName
trigger: true
When I run the Build pipeline, the Deploy pipeline is correctly triggered on the same branch. However, when I run the Deploy pipeline manually, it does not use the latest pipeline run from same branch.
I tried adding a couple of variations of the line below to the to the pipeline resource, but the variable does not expand:
branch: ${{ variables.Build.SourceBranchName }}
Is there any way to make this work?
Workaround that achieves the result I am looking for, but is not very elegant:
- ${{ if ne(variables['Build.Reason'], 'ResourceTrigger') }}:
- task: DeleteFiles#1
displayName: 'Remove downloaded artifacts from pipeline resource'
inputs:
SourceFolder: $(Pipeline.Workspace)
- task: DownloadPipelineArtifact#2
displayName: 'Download artifacts for branch'
inputs:
source: 'specific'
project: 'myProject'
pipeline: <BuildPipelineId>
runVersion: 'latestFromBranch'
runBranch: $(Build.SourceBranch)
For example, if I have a build pipeline named 'BuildPipelineAndDeployPipeline',
then the below YAML definition can get the latest build pipeline run from a specific branch:
resources:
pipelines:
- pipeline: BuildPipelineAndDeployPipeline
project: xxx
source: BuildPipelineAndDeployPipeline
trigger:
branches:
- main
pool:
vmImage: 'windows-latest'
steps:
- task: CmdLine#2
inputs:
script: |
echo Write your commands here
echo Hello world
echo $(resources.pipeline.BuildPipelineAndDeployPipeline.runID)

Is it possible to set a condition based on System.PullRequest.TargetBranch for a stage in a pipeline template?

I have a solution where a git branch is directly related to an environment (this has to be this way, so please do not discuss whether this is good or bad, I know it is not best practice).
We have the option to run a verification deployment (including automatic tests) towards an environment, without actually deploying the solution to the environment. Because of this, I would like to set up a pipeline that runs this verification for an environment, whenever a pull request is opened towards that environment's branch. Moreover, I am using a template for the majority of the pipeline. The actual pipeline in the main repository is just a tiny solution that points towards the template pipeline in another repository. This template, in turn, has stages for each respective environment.
I have, in the main pipeline, successfully added a solution that identifies the current branch, which for pull requests should be the target branch:
variables:
- name: currentBranch
${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
value: $(System.PullRequest.TargetBranch)
${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
value: $(Build.SourceBranch)
I would like to send this variable currentBranch down to the template through a parameter, as my template pipeline has different stages depending on the branch. My solution was to use the pipeline like this:
extends:
template: <template-reference>
parameters:
branch: $(currentBranch)
...and then for a stage in my pipeline do this:
- stage: TestAndDeployBranchName
condition: eq('${{ parameters.branch }}', 'refs/heads/branchName')
jobs:
- job1... etc.
Basically, the stage should run if the current branch is either "branchName", or (for pull requests) when the target branch is "branchName", which comes from the "branch" parameters that is sent to the template.
However, I see here that System.PullRequest.TargetBranch is not available for templates and further here that the parameters are not available for templates (the variable is empty) when the template is expanded. Thus my pipeline does not work as expected (the condition does not trigger when it should, ie. when there is a match on the branch name).
Is there any way that I can use System.PullRequest.TargetBranch in a condition within a template, or should I look for another solution?
After investigating this further I concluded that what I am trying to do is not possible.
In short, System.PullRequest.TargetBranch (and I assume at least some other variables within System.PullRequest are not available in compile time for template, which is when conditions are evaluated. Thus, using these variables in a condition in a template is not possible.
As my goal was to have certain steps run for pull requests only, based on the target branch of the pull request, I solved this by creating duplicate pipelines. Each pipeline is the same and references the same template, except for that the input parameter for the template is different. I then added each "PR pipelines" to run as part of the branch policy each respective branch this was applicable.
This works great, however it requires me to create a new pipeline if I have the same requirement for another branch. Moreover, I have to maintain each PR pipeline separately (which can be both good and bad).
Not an ideal solution, but it works.
Reference PR pipeline:
trigger: none # no trigger as PR triggers are set by branch policies
#This references the template repository to reuse the basic pipeline
resources:
repositories:
- repository: <template repo>
type: git # "git" means azure devops repository
name: <template name> # Syntax: <project>/<repo>
ref: refs/heads/master # Grab latest pipeline template from the master branch
stages:
- stage: VerifyPullRequest
condition: |
and(
not(failed()),
not(canceled()),
eq(variables['Build.Reason'], 'PullRequest')
)
displayName: 'Verify Pull Request'
jobs:
- template: <template reference> # Template reference
parameters:
image: <image>
targetBranch: <targetBranch> # Adjust this to match each respective relevant branch
The targetBranch parameter is the used in relevant places in the template to run PR verification.
Example of branch policy:
(Set this up for each relevant branch)
Picture of branch policy set up
After checking your script, we find we can not use the
variables:
- name: currentBranch
${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
value: $(System.PullRequest.TargetBranch)
${{ if ne(variables['Build.Reason'], 'PullRequest') }}:
value: $(Build.SourceBranch)
in the variables.
The variables will duplicate the second value to first one.
This will cause your issue.
So, on my side, I create a work around and hope this will help you. Here is my main yaml:
parameters:
- name: custom_agent
displayName: Use Custom Agent
type: boolean
default: true
- name: image
type: string
default: default
resources:
repositories:
- repository: templates
type: git
name: Tech-Talk/template
trigger: none
pool:
vmImage: windows-latest
# vmImage: ubuntu-20.04
stages:
- stage: A
jobs:
- job: A1
steps:
- task: PowerShell#2
name: printvar
inputs:
targetType: 'inline'
script: |
If("$(Build.Reason)" -eq "PullRequest"){
Write-Host "##vso[task.setvariable variable=currentBranch;isOutput=true]$(System.PullRequest.TargetBranch)"
}
else{
Write-Host "##vso[task.setvariable variable=currentBranch;isOutput=true]$(Build.SourceBranch)"
}
- stage: B
condition: eq(dependencies.A.outputs['A1.printvar.currentBranch'], 'refs/heads/master')
dependsOn: A
jobs:
- job: B1
variables:
varFromA: $[ stageDependencies.A.A1.outputs['printvar.currentBranch'] ]
steps:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
# Write your PowerShell commands here.
Write-Host "$(varFromA)"
- template: temp.yaml#templates
parameters:
branchName: $(varFromA)
agent_pool_name: ''
db_resource_path: $(System.DefaultWorkingDirectory)
Please Note:
If we use this, we need to modified your temp yaml.
We need to move the condition to the main yaml and make the temp yaml only steps is left.

Azure DevOps yaml pipeline trigger

My pipeline trigger in Azure DevOps does not fire.
Enviroment:
PipelineA (branch dev)
PipelineB (branch dev)
PipelineB should be fired if PipelineB was running successfully
Here is my current code of PipelineB.yaml
trigger: none
resources:
pipelines:
- pipeline: build_pipeline
source: PipelineA
branch: dev
trigger:
branches:
- dev
steps:
- task: Bash#3
inputs:
targetType: 'inline'
script: |
echo 'Hello world'
It worked in the past, but suddenly it stopped
Here's the document of Pipeline Triggers, please check this statement:
However, if the two pipelines use different repositories, then the triggered pipeline will use the latest version of the code from its default branch.
Cause of your issue:
The triggered pipeline is PipelineB in your scenario, and the default branch is always the master. Since the pipeline trigger for dev branch of PipelineA is defined in your dev branch instead of the default master branch, it's expected behavior that the pipeline trigger won't fire.
To make the pipeline trigger work:
1.You can choose to define the pipeline trigger for dev of PipelineA in default master of PipelineB.
2.Or you can change the Default branch for manual and scheduled builds of PipelineB (Change it from master to dev). You can find detailed steps about how to find this setting from #2 of this answer.
Both two choices above can resolve your issue and make the pipeline trigger work.
I just created almost identical pipeline
trigger: none
resources:
pipelines:
- pipeline: build_pipeline
source: kmadof.devops-manual (14)
branch: master
trigger:
branches:
- master
steps:
- task: Bash#3
inputs:
targetType: 'inline'
script: |
echo 'Hello world'
and all works fine. Are you sure you run PipelineA on dev branch?

Azure DevOps Pipeline Environment GitVersion name

The 'Status' value in Azure DevOps Pipelines Environments is using the initial value of the build number before it is transformed during build using gitversion.yml
My build pipeline YAML starts with:
name: $(GITVERSION_MAJOR).$(GITVERSION_MINOR).$(GITVERSION_PATCH).$(Build.BuildId)$(GITVERSION_PRERELEASELABEL)
When the build starts Azure DevOps temporarily displays it is:
#$(GITVERSION_MAJOR).$(GITVERSION_MINOR).$(GITVERSION_PATCH).64890$(GITVERSION_PRERELEASELABEL)
During build, first task that runs is a GitVersion task:
- task: gittools.gitversion.gitversion-task.GitVersion#4
displayName: GitVersion
inputs:
updateAssemblyInfo: true
preferBundledVersion: false
Using following gitversion.yml that is checked into repo:
mode: ContinuousDeployment
continuous-delivery-fallback-tag: ''
branches:
master:
mode: ContinuousDeployment
tag: '-dev'
increment: Minor
track-merge-target: true
tracks-release-branches: true
is-release-branch: false
prevent-increment-of-merged-branch-version: false
release:
regex: release?[/]
mode: ContinuousDeployment
increment: Minor
tag: ''
is-release-branch: true
prevent-increment-of-merged-branch-version: true
feature:
regex: feature?[/]
mode: ContinuousDeployment
increment: Inherit
tag: '-alpha'
is-release-branch: false
prevent-increment-of-merged-branch-version: true
pull-request:
mode: ContinuousDeployment
tag: '-pr'
ignore:
sha: []
After this runs, the build in progress name is automatically updated to:
1.24.0.64890-alpha
However, in the 'Environments' section of Azure DevOps, this change is not picked up and the status remains as:
Deployment by $(GITVERSION_MAJOR).$(GITVERSION_MINOR).$(GITVERSION_PATCH).64878$(GITVERSION_PRERELEASELABEL)
I would expect the 'Status' to be set to '1.24.0.64890-alpha' same as what shows in the Pipelines 'Last run' column.
Edit - 2020/06/13
I never found a solution to this, but found an alternative implementation which works in the native Azure DevOps YAML without using GitVersion:
# Generate build name - see variables section below
name: '$(Version.MajorMinor).$(Version.Revision)$(Version.Suffix)'
variables:
Version.MajorMinor: 1.0 # Major = non-backward compatible version increment, Minor = backward compatible version increment
Version.Revision: $[counter(variables['Version.MajorMinor'],0)] # Increments automatically every build, resets if Version.MajorMinor is changed
# Set the suffix of the version number depending on whether this is master, pr or other branch
${{ if eq(variables['Build.SourceBranch'], 'refs/heads/master') }}:
Version.Suffix: '' # master
${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
Version.Suffix: '-pr' # pull request
${{ if and(ne(variables['Build.SourceBranch'], 'refs/heads/master'), ne(variables['Build.Reason'], 'PullRequest')) }}:
Version.Suffix: '-pre' # pre-release
The version number generated is then in format:
1.0.0 (master branch)
1.0.0-pr (Pull request)
1.0.0-pre (another other branch)
The revision number is auto incremented every time a build is run.