Exide
Exide

Reputation: 899

How to authenticate git push to GitHub within an Azure Pipeline Bash task

Inside one of our Azure Pipelines I am attempting to push a tag to GitHub but receiving one of two errors depending on my approach.

No authentication, just a simple git push

- bash: 'git push origin $(tag)'
git push origin 2019.07.01.1
fatal: could not read Username for 'https://github.com': terminal prompts disabled

Pass AUTHORIZATION: Bearer *** as an extra header

- bash: 'git -c http.extraheader="AUTHORIZATION: Bearer $(System.AccessToken)" push origin $(tag)'
git -c http.extraheader="AUTHORIZATION: Bearer ***" push origin 2019.07.01.2
fatal: unable to access 'https://github.com/respondentinc/website/': The requested URL returned error: 400

Pass AUTHORIZATION: Bearer *** as an extra header, using environmental variables

From: https://github.com/microsoft/azure-pipelines-agent/issues/1582#issuecomment-392235276

- bash: 'git -c http.extraheader="AUTHORIZATION: Bearer $env:token" push origin $(tag)'
  env:
      token: $(System.AccessToken)
git -c http.extraheader="AUTHORIZATION: Bearer ***" push origin 2019.07.01.3
fatal: unable to access 'https://github.com/respondentinc/website/': The requested URL returned error: 400

Pass a Bash script to the credential helper

Based on bk2204's answer

- bash: 'git -c credential.helper=''!f() { echo "username=token"; echo "password=$(System.AccessToken)"; }; f'' push origin $(tag)'
git -c credential.helper='!f() { echo "username=token"; echo "password=***"; }; f' push origin 2019.07.02.9
fatal: unable to access 'https://github.com/respondentinc/website/': The requested URL returned error: 400

Pass a Bash script to the credential helper, using environmental variables

From bk2204's answer

- bash: 'git -c credential.helper=''!f() { echo "username=token"; echo "password=$env:token"; }; f'' push origin $(tag)'
  env:
      token: $(System.AccessToken)
git -c credential.helper='!f() { echo "username=token"; echo "password=$env:token"; }; f' push origin 2019.07.02.9
fatal: unable to access 'https://github.com/respondentinc/website/': The requested URL returned error: 400

Pass AUTHORIZATION: Basic *** as an extra header

Tried to mimic the way the default pipeline "Checkout" task does it.

- bash: 'git -c http.extraheader="AUTHORIZATION: basic $(System.AccessToken)" push origin $(tag)'
git -c http.extraheader="AUTHORIZATION: basic ***" push origin 2019.07.02.10
fatal: unable to access 'https://github.com/respondentinc/website/': The requested URL returned error: 400

I tried a handful of variations on the above themes with no luck.

What am I missing?

Update: 2019-07-02

All the above mechanisms are valid ways of authenticating. The issue is that the System.AccessToken isn't valid for GitHub. The documentation indicates it is for interaction with Azure Pipeline services only.

I wasn't able to find a variable for the token provided by the Azure Pipeline GitHub App. I don't think it would matter though since it's an installation token. I tried using this token with the GitHubRelease task and it still failed due to a lack of write permission.

To get this working I went with the GitHubRelease task and had to create a new service connection with a new OAuth token that had write permission.

I'm still curious how to get access to a token associated with a service connection from within the Bash task.

Upvotes: 11

Views: 6898

Answers (2)

Maxim
Maxim

Reputation: 2128

My solution is:

  1. Create Personal Access Token (PAT) on GitHub

    enter image description here

  2. Create secret variable within your pipeline which will hold PAT

    enter image description here

  3. Now you can use PAT for git push in pipeline YAML config:

    git push https://$(GitHubPAT)@github.com/<your_org_and_project>.git

Also it seems you need to do these steps before push (I'm using PowerShell script step):

Add-Content "$HOME\.git-credentials" "https://$(GitHubPAT):[email protected]"
git config --global user.email "<email>"
git config --global user.name "<name>"
git config --global --add url."[email protected]:".insteadOf "https://github.com/"

But I'm not sure what of these instructions can be omitted. But following these steps I'm able to do git push from my pipeline.

Upvotes: 1

bk2204
bk2204

Reputation: 76429

The problem here is that you're trying to use Bearer authentication. That's correct for Azure DevOps hosting, but not for GitHub, which uses Basic authentication.

The best way to handle this is to set the environment variable TOKEN to have the token that you want (like your attempt), and then run the command as follows:

git -c credential.helper='!f() { echo "username=token"; echo "password=$TOKEN"; };f' push $(tag)

Any username is acceptable if you're using a token; I just used token because you need some username, and it's an obvious choice.

By using a shell function as a credential helper and using echo, which is a shell built-in, your credentials won't appear in the logs or process output.

Upvotes: 0

Related Questions