22

I am trying to set our build names to a format of...

$(BuildDefinitionName)_$(versionMajor).$(versionMinor).$(versionPatch)+$(SourceBranchName).$(SourceVersion) e.g. OurBigLibraryCI_1.2.3+master.10bbc577

However I coudn't find any predefined variable holding the "short" (7-digit) version of the commit hash. $(SourceVersion) holds the full SHA-1 hash.

How would one shorten that in yaml based pipeline?

Matthias Güntert
  • 4,013
  • 6
  • 41
  • 89

5 Answers5

10

You can use traditional command substitution via backticks to obtain the short git hash (SHA-1), assuming that the code is being checked out in $(Build.SourcesDirectory):

  - bash: |
      short_hash=`git rev-parse --short=7 HEAD`  ## At least 7 digits, more if needed for uniqueness
      echo ""
      echo "Full git hash:  $(Build.SourceVersion)"
      echo "Short git hash: $short_hash"
      echo "##vso[task.setvariable variable=short_hash]$short_hash"  ## Store variable for subsequent steps
    workingDirectory: $(Build.SourcesDirectory)
    displayName: Get short git hash

Output:

Full git hash:  f8d63b1aaa20cf348a9b5fc6477ac80ed23d5ca0
Short git hash: f8d63b1

The following steps in the pipeline can then use the short hash via the variable $(short_hash).

(This is better than manually trimming down the full git hash to seven characters, since this will add extra digits if needed to uniquely identify the commit, see https://stackoverflow.com/a/21015031/1447415.)

Update: Improved version

The following improved version checks that the git hashes match (that the full hash starts with the short hash) and fails the step otherwise:

  - bash: |
      short_hash=`git rev-parse --short=7 HEAD`
      echo ""
      echo "Full git hash:  $(Build.SourceVersion)"
      echo "Short git hash: $short_hash"
      echo ""
      ## Fail step if full hash does not start with short hash
      if [[ $(Build.SourceVersion) != $short_hash* ]]; then
        echo "--> Hashes do not match! Aborting."
        exit 1
      fi
      echo "--> Hashes match. Storing short hash for subsequent steps."
      ## Store variable for subsequent steps
      echo "##vso[task.setvariable variable=short_hash]$short_hash"
    workingDirectory: $(Build.SourcesDirectory)
    displayName: Get short git hash
Johan
  • 323
  • 4
  • 9
  • your edited code - why is that check important? seems redundant. – sommmen Jan 21 '22 at 14:32
  • 1
    @sommmen: It has been a while since I looked at this, but as I recall, it can happen that the git hashes (`$(Build.SourceVersion)` and `git rev-parse HEAD`) do not match. I think this for instance happens if some new code is pushed immediately after the Azure job has been started, so that the job pulls down some wrong/unexpected code. In this case I believe we want the build to fail, so that it can be restarted on the new code. – Johan Feb 04 '22 at 12:32
8
- script: |
    echo $sourceVersion
    commitHash=${sourceVersion:0:7}
    echo $commitHash
    echo "##vso[task.setvariable variable=commitHash]$commitHash" ## Set variable for using in other tasks.
  env: { sourceVersion: $(Build.SourceVersion) }
  displayName: Git Hash 7-digit
  workingDirectory: #workingDirectory

- task: Docker@2
  displayName: Build & Push image
  inputs:
    command: 'buildAndPush'
    containerRegistry: '$(myRegistry)'
    repository: $(myContainerRepository)
    Dockerfile: $(myDockerfile)
    buildContext: '$(myBuildContext)'
    tags: $(commitHash) ## The variable was defined above.

Here's example for vmImage: "ubuntu-latest". Step:

  1. Split 7-characters from Pre-defined GitHash
  2. Assign it to Pipeline variable. Don't confuse $(azure_pipeline_variable) with ${bash_shell_variable} or $bash_shell_variable.
  3. Use it by $(commitHash)

Read more:

  1. Assign variable in Azure pipeline
  2. Using script in Azure pipeline
Khoa
  • 1,738
  • 1
  • 14
  • 21
5

How would one shorten that in yaml based pipeline?

There is no out of box variable to get the 7-digit version of $(SourceVersion) in Azure Devops. Because the ShortSha is 8-digit version.

So, to resolve this issue, just like @4c74356b41 said, we have to use bash\powershell script to split long sha into short sha.

You can check my following sample for some more details:

steps:

- script: |
   echo $(Build.SourceVersion)

   set  TestVar=$(Build.SourceVersion)

   set MyCustomVar= %TestVar:~0,7%

   echo %MyCustomVar%

  displayName: 'Command Line Script'

The result:

========================== Starting Command Output ===========================
##[command]"C:\WINDOWS\system32\cmd.exe" /D /E:ON /V:OFF /S /C "CALL "C:\VS2017Agent\_work\_temp\be5f6293-77d8-41b7-a537-49e3b2e7bc6c.cmd""
cb124539c4cb7f19dc8e50e1b021f93c5ffaf226
cb12453
##[section]Finishing: Command Line Script

So, we could get the 7-digit version of $(SourceVersion) is cb12453.

Hope this helps.

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • I have a build pipeline in Azure Devops where one step is an inline powershell script to extract the 7-digit version of SourceVersion in a variable called shortCommitId. But I have not figured out how to use this variable in the next step which is "Publish Artifact". In the powershell step I set a reference name in the output variable section: ps. Then in the Publish Artifact step i use $(ps.shortCommitId) but the resulting name of the artifact uses the string $(ps.shortCommitId) instead of the value set in the powershell script. What am I missing? – erik Sep 18 '19 at 07:55
  • @erik, Since this thread is closed, I suggest you open a new thread with detailed info about your question, more community members on this forum may further look at your issue and provide more suggestions. – Leo Liu Sep 18 '19 at 07:57
2

you could use gitversion for that, it would expose shortsha under $(GitVersion.ShortSha) variable after you run the gitversion task.

on the other hand shortsha is just first 7 characters of a real sha, so you can just use some sort of bash\powershell script to split long sha into short sha

In Git, what is the difference between long and short hashes?

- task: gittools.gittools.setup-gitversion-task.gitversion/setup@0
  displayName: gitversion/setup
  inputs:
    versionSpec: 5.x
- task: gittools.gittools.execute-gitversion-task.gitversion/execute@0
  displayName: gitversion/execute

replacement for the deprecated extension

4c74356b41
  • 69,186
  • 6
  • 100
  • 141
0

As the docs say you can't use $(Build.SourceVersion) variable directly in the build name, nor is there an in-built substring Expression

But you can update the Build Number variable dynamically:

pool: 
  vmImage: 'ubuntu-latest' #'windows-latest' - works on either

steps:

- checkout: none

- powershell: |
    $shortHash = "$(Build.SourceVersion)".Substring(0, 7)
    Write-Host "##vso[task.setvariable variable=shortHash]$shortHash"
  displayName: Set Short Hash  

- powershell: Write-Host $(shortHash)
  displayName: Display Short Hash

- powershell: Write-Host "##vso[build.updatebuildnumber]$(Build.DefinitionName)_AnyOtherValues_$(shortHash)"
  displayName: Update Build Number

- powershell: Write-Host $(Build.BuildNumber)
  displayName: Display Build Number

The name updates in the UI

ste-fu
  • 6,879
  • 3
  • 27
  • 46