Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger VSTS/TFS build with webhook from Bit Bucket

UPDATE: This is old question. TFS now fully support integration with Bitbucket!

Is it really not possible to trigger build in TFS/VSTS 2015 from outside with http?

I have repository on BitBucket and I want to trigger build on commit. I have searched the web and found nothing.

like image 774
hex Avatar asked Oct 30 '25 11:10

hex


2 Answers

Yes, unless you use a third party service like Zapier.

There is already a user voice submitted for this. check this link for details: https://visualstudio.uservoice.com/forums/330519-team-services/suggestions/10674648-enable-ci-build-support-for-bitbucket-git-reposito

Update: This feature is available in VSTS now. You can choose "BitBucket" as the "Srouce" and enable the trigger under "Triggers" panel.

like image 142
Eddie Chen - MSFT Avatar answered Nov 01 '25 12:11

Eddie Chen - MSFT


The trigger setting in VSTS build definition doesn't work properly with external repositories. Basically a user needs to login to the VSTS account and then the trigger checks the repository.

You can create an Azure Function and use that as your BitBucket Webhook. Then inside the Azure Function use VSTS REST API to trigger the build.

Below is the code that you can paste in your Azure Function and after setting

  • instance name
  • project name
  • definition Id(s)
  • branch name(s)
  • personal access token

it will just work the way you want -> Right after you push a commit to the repository, it will queue a build for the specified definition.

using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
  var definitionId = -1;

  dynamic data = await req.Content.ReadAsAsync<object>();
  var branch = data?.push?.changes[0]?.@new?.name;

  if(branch == "master") definitionId = 6; // TODO update the branch name and definition Id to match your settings
  else if(branch == "ci/website-staging") definitionId = 7; // TODO update the branch name and definition Id to match your settings

  if (definitionId >= 0) // Known branch
  {
      string accessToken = GetEnvironmentVariable("PersonalAccessToken"); // TODO add your personal token to your app settings or paste it here
      const string instance = "instance_name"; // TODO put the instance name
      const string project = "project_name"; // TODO put the project name
      const string version = "api-version=2.0";

      var url = $"https://{instance}.visualstudio.com/DefaultCollection/{project}/_apis/build/builds?{version}";
      var authorizationToken = Convert.ToBase64String(Encoding.ASCII.GetBytes($":{accessToken}"));
      var body = "{\"definition\" : {\"id\" : " + definitionId + "}}";

      return await PostAsync(url, body, authorizationToken);
  }

  return req.CreateResponse(HttpStatusCode.OK);
}

private static async Task<HttpResponseMessage> PostAsync(string url, string jsonBody, string authorizationToken = null)
{
  using (var client = new HttpClient())
  {
      if (!string.IsNullOrEmpty(authorizationToken))
          client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authorizationToken);
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
      client.BaseAddress = new Uri(url);
      var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
      return await client.PostAsync("", content);
  }
}

private static string GetEnvironmentVariable(string name)
{
  return Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
}

I've written a detailed blog post about it in case you need more info.

like image 23
Aboo Avatar answered Nov 01 '25 12:11

Aboo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!