Azure-pipelines-agent: Cannot call git tag/push in yaml build

Created on 25 May 2018  路  22Comments  路  Source: microsoft/azure-pipelines-agent

  - powershell: |
      Write-Host "git tag $env:tag"
      git tag $env:tag
      Write-Host "git push origin $env:tag"
      git push origin $env:tag
    displayName: Git Tag
    workingDirectory: $(Build.SourcesDirectory)
    env:
      tag: '$(PACKAGE_VERSION)'
      SYSTEM_ACCESSTOKEN: $(system.accesstoken)
    ignoreLASTEXITCODE: false
    errorActionPreference: Stop
    failOnStderr: true

This command freezes forever no matter what permissions I add. I'm able to call the same command from the UI build and it works without any issues, this is only a problem in yaml builds.

Most helpful comment

For the sake of completeness:
We had a similar issue with git failing. Here is how re resolved it! 馃帀

  1. Our build agent had the standard permissionset, but as we enabled custom policies on our branch (such as disallowing direct pushes without a PR), the agent needed additional permissiosn:
  2. bypass policies when pushing
  3. and bypass policies when completing pull requests

  4. Then, we did not have to pass the bearer token using git -c .... as described above. Rather, we just had to add a task checkout with persistCretentials:true.

  5. Finally, there was one more important step: We had a powershell inline script which was essentially calling

git tag $(GitVersion.NuGetVersion)
git push --tags

this ALWAYS failed with the error code 1 as it is described above in this thread.
The only way we could get rid of this error was to split those comands into two separate powershell scripts

So for you guys, here is the essential parts of our yaml file:

# run on PRs and whenever a feature branch is pushed
trigger:
- master
- feature/*

pool:
  vmImage: 'windows-latest'

variables:
  solution: 'Sample.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:

# NOTE: You need tos pecify 'persistCredentials:true' to allow your build agent to has access to git commands for pull/tag/push
# see https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/git-commands?view=azure-devops&tabs=yaml
- checkout: self
  persistCredentials: true
  clean: true

# create semantic version
- task: GitVersion@5
  inputs:
    runtime: 'full'

# ...
# ... run all your crazy build stuff here 
# ...

# tag the current branch with the version number
- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
      git tag $(GitVersion.NuGetVersion)
      Write-Host "Successfully created tag $(GitVersion.NuGetVersion)" 

# push created tag to origin
# NOTE: you need to set 'persistCredentials: true' in the checkout task. Otherwise git will fail with error code 1.
# NOTE: You cannot run both "git tag xyz" AND "git push --task" in the same powershell command. If you do, git will fail with error code 1
# NOTE: IF you get an error from this git command, make sure, that your build user has the required permissions!
#       In our case, the build agent needs the additional permissions for "bypass policies when pushing" and "bypass policies when completing pull requests"
#       because we have a custom policy in place. (See: https://opti-q.visualstudio.com/<your_project_name>/_settings/repositories)
- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
      git push --tags
      Write-Host "Successfully pushed tag $(GitVersion.NuGetVersion) to origin"      


All 22 comments

@AceHack you didn't feed in credential to git, it freezes since it is trying to prompt for credential.

@TingluoHuang Please elaborate. How would I do that? My understanding was OAuth token is always there in yaml builds.

@AceHack it's available in ENV for yaml build for now, we are working on repository checkout option for preserver git credential, for now, i guess you need to run
git -c http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)" tag MyTag

so that command shows up already in the build under the automatic step "Get sources"

2018-05-25T22:35:00.9346747Z ##[command]git -c http.extraheader="AUTHORIZATION: bearer *" fetch --tags --prune --progress --no-recurse-submodules origin

I tried several different combinations with the following command

- powershell: |
    Write-Host "git tag $env:tag"
    git -c http.extraheader="AUTHORIZATION: bearer $env:SYSTEM_ACCESSTOKEN" tag $env:tag
    Write-Host "git push origin $env:tag"
    git -c http.extraheader="AUTHORIZATION: bearer $env:SYSTEM_ACCESSTOKEN" push origin $env:tag
  displayName: Git Tag
  workingDirectory: $(Build.SourcesDirectory)
  env:
    tag: '$(PACKAGE_VERSION)'
    SYSTEM_ACCESSTOKEN: $(system.accesstoken)
  ignoreLASTEXITCODE: false
  errorActionPreference: Stop
  failOnStderr: true

trying the token on the tag line, push line, both.

Just the tag line, still freezes
Either just the push line or both tag line and push line fail with:

To https://xxx.visualstudio.com/xxx/_git/SampleProject

That's it, no more error message, just that.

Did you give permission to the service account? It doesn't have push permissions by default.

https://docs.microsoft.com/en-us/vsts/build-release/actions/scripts/git-commands?view=vsts

Yes, I did that to get git tag working in UI build. UI builds can git tag this repo with no issues.

make sure you are using git 2.9 or higher. the windows agent bundles git, linux does not. try adding git --version to your script to be sure.

@ericsciple I don't expect the git version is the issue since it works fine with UI builds but here is the results.

git version 2.14.3.windows.1

@AceHack can you share your log file?


Starting: Git Tag

**************************

Task : PowerShell
Description : This is an early preview. Run a PowerShell script on Windows, macOS, or Linux.
Version : 2.129.0
Author : Microsoft Corporation

Help : More Information

Generating script.
"C:WindowsSystem32WindowsPowerShellv1.0powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command ". 'c:agent_b_work_tempbfc03e29-cf01-436d-a174-1a2fc271af62.ps1'"
git version 2.14.3.windows.1
git tag 2.5.20-ci.2018.149.1.master
git push origin 2.5.20-ci.2018.149.1.master


Starting: Post Job Cleanup


Cleaning any cached credential from repository: Platform.DotNet (Git)
To https://itron.visualstudio.com/CloudServicesPlatform/_git/Platform.DotNet


Finishing: Git Tag


Also for reference here is the exact command I ran:

- powershell: |
    git --version
    Write-Host "git tag $env:tag"
    git -c http.extraheader="AUTHORIZATION: bearer $env:SYSTEM_ACCESSTOKEN" tag $env:tag
    Write-Host "git push origin $env:tag"
    git -c http.extraheader="AUTHORIZATION: bearer $env:SYSTEM_ACCESSTOKEN" push origin $env:tag
  displayName: Git Tag
  workingDirectory: $(Build.SourcesDirectory)
  env:
    tag: '$(PACKAGE_VERSION)'
    SYSTEM_ACCESSTOKEN: $(system.accesstoken)
  ignoreLASTEXITCODE: false
  errorActionPreference: Stop
  failOnStderr: true

And the line

To https://itron.visualstudio.com/CloudServicesPlatform/_git/Platform.DotNet

Shows up in red, everything is is normal color.

@AceHack instead of Write-Host "git tag $env:tag", can you change it to Write-Host "git -c http.extraheader="AUTHORIZATION: bearer $env:SYSTEM_ACCESSTOKEN" tag $env:tag"

@AceHack BTW, git use STDERR to report progress information, so i don't think you want to failOnStderr: true, instead, you should check return code of each git command.

@TingluoHuang FYI, I've included my command as I did previously and you can see I'm already doing what you suggested.

- powershell: |
    git --version
    Write-Host "git tag $env:tag"
    **git -c http.extraheader="AUTHORIZATION: bearer $env:SYSTEM_ACCESSTOKEN" tag $env:tag**
    Write-Host "git push origin $env:tag"
    git -c http.extraheader="AUTHORIZATION: bearer $env:SYSTEM_ACCESSTOKEN" push origin $env:tag
  displayName: Git Tag
  workingDirectory: $(Build.SourcesDirectory)
  env:
    tag: '$(PACKAGE_VERSION)'
    SYSTEM_ACCESSTOKEN: $(system.accesstoken)
  ignoreLASTEXITCODE: false
  errorActionPreference: Stop
  failOnStderr: true

Also as I've stated earlier I've tried every combination of adding -c http.extraheader="AUTHORIZATION: bearer $env:SYSTEM_ACCESSTOKEN", only on the tag, only on the push, on both the tag and push and on neither the tag nor push. They all fail in some way.

I will try turning off failOnStderr and report back.

Thanks.

failOnStderr: false fixed the issue

Thanks for all the help

  - powershell: |
      Write-Host "git tag $env:tag"
      git tag $env:tag
      Write-Host "git push origin $env:tag"
      git push origin $env:tag
    displayName: Git Tag
    workingDirectory: $(Build.SourcesDirectory)
    env:
      tag: '$(PACKAGE_VERSION)'
      SYSTEM_ACCESSTOKEN: $(system.accesstoken)
    ignoreLASTEXITCODE: false
    errorActionPreference: Stop
    failOnStderr: true

This command freezes forever no matter what permissions I add. I'm able to call the same command from the UI build and it works without any issues, this is only a problem in yaml builds.

Hi Aaron how did you do that from the UI Build?
I want to tag my commits when the build and all test are ok.
But I just got create a tag but not push it

Hi, i still the same issue only with git push origin . Every thing else like git pull, git push, git tag, git fetch are working great. I'm using Azure DevOps Build pipeline, Powershell task(version 2.0) and git version is git version 2.17.1.windows.2.

Issue: Pipeline waiting for longtime.

For the sake of completeness:
We had a similar issue with git failing. Here is how re resolved it! 馃帀

  1. Our build agent had the standard permissionset, but as we enabled custom policies on our branch (such as disallowing direct pushes without a PR), the agent needed additional permissiosn:
  2. bypass policies when pushing
  3. and bypass policies when completing pull requests

  4. Then, we did not have to pass the bearer token using git -c .... as described above. Rather, we just had to add a task checkout with persistCretentials:true.

  5. Finally, there was one more important step: We had a powershell inline script which was essentially calling

git tag $(GitVersion.NuGetVersion)
git push --tags

this ALWAYS failed with the error code 1 as it is described above in this thread.
The only way we could get rid of this error was to split those comands into two separate powershell scripts

So for you guys, here is the essential parts of our yaml file:

# run on PRs and whenever a feature branch is pushed
trigger:
- master
- feature/*

pool:
  vmImage: 'windows-latest'

variables:
  solution: 'Sample.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:

# NOTE: You need tos pecify 'persistCredentials:true' to allow your build agent to has access to git commands for pull/tag/push
# see https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/git-commands?view=azure-devops&tabs=yaml
- checkout: self
  persistCredentials: true
  clean: true

# create semantic version
- task: GitVersion@5
  inputs:
    runtime: 'full'

# ...
# ... run all your crazy build stuff here 
# ...

# tag the current branch with the version number
- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
      git tag $(GitVersion.NuGetVersion)
      Write-Host "Successfully created tag $(GitVersion.NuGetVersion)" 

# push created tag to origin
# NOTE: you need to set 'persistCredentials: true' in the checkout task. Otherwise git will fail with error code 1.
# NOTE: You cannot run both "git tag xyz" AND "git push --task" in the same powershell command. If you do, git will fail with error code 1
# NOTE: IF you get an error from this git command, make sure, that your build user has the required permissions!
#       In our case, the build agent needs the additional permissions for "bypass policies when pushing" and "bypass policies when completing pull requests"
#       because we have a custom policy in place. (See: https://opti-q.visualstudio.com/<your_project_name>/_settings/repositories)
- task: PowerShell@2
  inputs:
    targetType: 'inline'
    script: |
      git push --tags
      Write-Host "Successfully pushed tag $(GitVersion.NuGetVersion) to origin"      


failOnStderr: false fixed the issue

Thanks for all the help

I believe that powershell interprets the standard messages from GIT as errors. Hence why this fixes it

UPDATE: Redirecting git stderr to stdout is error-prone because it hides errors and progress, and modifies output of git commands. It's better to rely on failOnStderr like others pointed out.

OK. Apparently git writes progress to stderr... (just test/google it for more info)

But failOnStderr: false is like trying to kill a fly with a bazooka.

And there is an environment variable called GIT_REDIRECT_STDERR.

You could add it in your powershell:

$env:GIT_REDIRECT_STDERR` = '2>&1'

Or in the variables section of your pipeline (which also injects it in the environment):

variables:
  GIT_REDIRECT_STDERR: 2>&1

Thanks for helpful conversation.
Found this on https://stackoverflow.com/a/58492632/880524

Just for reference, there's another way of doing this...

- checkout: self
  persistCredentials: true

## Rest of pipeline ##

- script: |
     git tag $(GitVersion.NugetVersionV2)
     git push origin $(GitVersion.NugetVersionV2)
  workingDirectory: $(Build.SourcesDirectory)

The persistCredentials allows the token to be automatically passed to other git commands. Note the assignment of workingDirectory, otherwise I had an error that the location was not a git repository.

For an annotated tag rather than lightweight tag, the syntax would look like this...

- script: |
     git tag -a <tagname> -m <message>

To get a user/date against it you need to set the user name/email as well e.g.

- script: |
    git config --global user.name "BuildService"
    git config --global user.email "[email protected]"
    git tag -a <tagname> -m <message>

For this to work, the Project Collection Build Server account (not the Project Build Service Accounts group) needs to be allocated the Contribute permission for the Repositories

Was this page helpful?
0 / 5 - 0 ratings