Google Cloud Build 与 Bitbucket 的集成

Google Cloud Build integration with Bitbucket

我们使用 Bitbucket 作为我们的版本控制工具。 构建和部署正在 Google Cloud Platform 上执行。

所有构建都是通过 Google Cloud docs 中指定的构建触发器触发的。 这很好用,但我们希望获得 Bitbucket 中特定分支的构建状态反馈,或者最好是根据拉取请求。

我做了一些研究,但没有发现任何关于这个特定主题的有用信息。 Google Cloud docs 中有一个注释考虑了基于拉取请求的构建,这并没有给我们太多希望:

"Whether based on branch commits or tag commits, builds are only triggered on pushes to the remote origin. Builds do not trigger on local changes, pre-submits, or pull requests."

GitHub 似乎与支持构建状态反馈的 Google Cloud Build 集成得很好。

拉取 request/remote 推送时可以在 Bitbucket 中获得 Google Cloud Build 状态反馈,如果是,如何? 你是如何处理这个问题的?

这里我们使用了开箱即用的 integration between Google Cloud Build and Google Pub/Sub. Connected into this default topic cloud_builds we have a Google Cloud Function responsible for making an HTTP request into Bitbucket REST API。此 API 有一个当前的 2.0 版本,但几个例子仍然提到了过去的版本 1.0,因此请注意潜在的问题。

@Moacir Rosa 谢谢你的回答。 根据该建议,我们构建了以下 GCP Cloud Function:

const axios = require('axios');

/**
 * Triggered from a message on a Cloud Pub/Sub topic.
 *
 * @param {!Object} event Event payload.
 * @param {!Object} context Metadata for the event.
 */
exports.processPubSubMessage = (event, context) => {
  const pubsubMessage = event.data;
  const dataString = Buffer.from(pubsubMessage, 'base64').toString();
  const message = JSON.parse(dataString);
  const commitSha = message.sourceProvenance.resolvedRepoSource.commitSha;
  const repoName = message.sourceProvenance.resolvedRepoSource.repoName;
  const [bitbucket, username, repo_slug] = repoName.split('_');
  // Build Bitbucket payload data.
  const payload = {
      type: 'string',
      created_on: message.createTime,
      description: `Status: ${message.status}`,
      key: 'string',
      name: 'Google Cloud Build',
      refname: `buildTriggerId: ${message.buildTriggerId}`,
      state: getBitbucketState(message.status),
      updated_on: message.finishTime,
      url: message.logUrl,
      uuid: message.id,
  }
  // Send request to Bitbucket.
  const token = process.env.BITBUCKET_TOKEN;
  const url = getBuildUrl(username, repo_slug, commitSha);
  axios.post(url, payload, {
      headers: { Authorization: `Basic ${token}` }
  })
      .then(function(response){
          console.log(response);
      })
      .catch(function(error){
          console.log(error);
      });


  /**
   * See: https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Busername%7D/%7Brepo_slug%7D/commit/%7Bnode%7D/statuses/build
   * 
   * @param {string} username
   * @param {string} repo_slug
   * @param {string} commitSha 
   */
  function getBuildUrl(username, repo_slug, commitSha) {
      const baseUrl = 'https://api.bitbucket.org/2.0/repositories';
      return `${baseUrl}/${username}/${repo_slug}/commit/${commitSha}/statuses/build`;;
  }

  /**
   * Translates states from Google Cloud Build Message to Bitbucket.
   * See: https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Busername%7D/%7Brepo_slug%7D/commit/%7Bnode%7D/statuses/build
   * 
   * @param {string} status 
   */
  function getBitbucketState(status) {
      switch(status.toLowerCase()) {
          case 'success':
              return 'SUCCESSFUL';
          case 'queued':
          case 'working':
              return 'INPROGRESS';
          default:
              return 'FAILED';
      }
  }
};

参见:https://github.com/honest-food-company/gcp-cloud-build-function-bitbucket

我使用不支持 Bitbucket 令牌的 Bitbucket Cloud。我分叉了 Honest Food Company 的优秀回购并对其进行了修改以支持 Bitbucket Cloud 的应用程序密码。

https://github.com/dgallegos/gcp-cloud-build-function-bitbucket