If you want to skip ahead to the workaround, click here

Earlier today, I tried automating Github releases in Azure Pipelines. It should be easy because they already have a Task for it, but I encountered this annoying error in my builds:

Error: Invalid Github service connection scheme: Token. Only OAuth and Github personal access token connections are allowed.

I checked if my service connection exists and if it’s a token, they’re all there! I’ve set it up by creating a Github Personal Access Token, and adding it to Azure’s “Service Connections”, so I shouldn’t be encountering this error. What’s weird is that my authentication scheme is being detected as Token, instead of Github personal access token! This is a potential bug, so I scoured Github Issues if someone has reported it.

There is an Issue for it, but it’s been open for almost three months!

Luckily, the conversation thread discovered a workaround: create the service token via an API request. There’s some cURL magic happening, and the thread has left out some important parts, so I hope the following tutorial can walk you through the steps in detail.

The Workaround

Just three (3) steps:

  1. Create a personal access token (PAT)
  2. Prepare token for the request
  3. Send a POST request

First, create a personal access token (PAT) for sending requests to the Azure Devops REST API. You can do so by following the instructions here. Some notes on my case:

  • The minimal scope for the token can be: Service Connections (Read, query, & manage). Be sure to click the “other 27 scopes” so this category would appear.
  • I didn’t need to change the token expiry. Since you’re going to use this once, you’re free to set it at a nearer date.

After creating the token you need to prepare it for the request by (1) base64 encoding it and (2) copy-pasting it in your request body. In my case, I just used Postman rather than the usual cURL since the former does step 1 automatically. For Postman, simply go to the “Authorization” tab and fill-in your Username and Password (the generated token)

Then, you can now send a POST request to this endpoint: https://dev.azure.com/<TODO-ORGANIZATION>/<TODO-PROJECT>/_apis/serviceendpoint/endpoints?api-version=5.1-preview.2. The Content-Type of the request should be application/json, and must contain the following payload:

{
  "name": "release",
  "type": "github",
  "url": "https://github.com",
  "authorization": {
    "scheme": "PersonalAccessToken",
    "parameters": {
      "accessToken": "<TODO-GITHUB-PERSONAL-ACCESS-TOKEN>"
    }
  }
}

After sending the request, you should be able to verify that the Service Connection has indeed been created. Note that it should say using personalaccesstoken and not using Personal Access Token or using Github Access Token. It’s really weird.

Hope it helps!

Update: I made a PR!

Good thing, the source code for the Github Release Task is open-source. At first, I got intimidated by Typescript, but upon checking the code, it seems that a fix is possible. What I need to do is add another statement to include Token, alongside PersonalAccessToken:

if (!!githubEndpointObject) {
    tl.debug("Endpoint scheme: " + githubEndpointObject.scheme);
    
    if (githubEndpointObject.scheme === 'PersonalAccessToken') {
        githubEndpointToken = githubEndpointObject.parameters.accessToken
    } else if (githubEndpointObject.scheme === 'OAuth'){
        // scheme: 'OAuth'
        githubEndpointToken = githubEndpointObject.parameters.AccessToken
    } else if (githubEndpointObject.scheme === 'Token'){
        // scheme: 'Token' (this is the line I added)
        githubEndpointToken = githubEndpointObject.parameters.AccessToken
    } else if (githubEndpointObject.scheme) {
        throw new Error(tl.loc("InvalidEndpointAuthScheme", githubEndpointObject.scheme));
    }
}

It all made sense now! That’s why we’re sending the scheme PersonalAccessToken in the payload because that’s the only thing being detected. I made a Pull Request here, hoping this gets reviewed and merged pretty soon.

Final thoughts

Creating Github Releases from a Continuous Delivery pipeline is one of the most common tasks in open-source software dev’t. However, this simple bug in Azure Pipelines can prove to be very frustrating for developers, it was for me! Ideally, we shouldn’t be doing these steps (i.e., making cURL requests and whatnot). I hope that this bug will be fixed soon, but for now, you can just follow this workaround!