Chained Builds with Codeship API v2

Codeship News

Reading Time: 4 minutes

The Codeship API v2 general availability release happened earlier this week, and I thought it would be useful to try out one of the main use cases listed in the feature blog post: triggered builds.

Overview

In your project, it can become necessary to trigger builds without a code commit. Typical scenarios involve some module that is included in multiple projects like an NPM package or possibly a full service in a microservice application. If a module is updated, your team may want to also test other projects to validate that nothing has broken the entire system, and potentially deploy the latest version of that module.

This is where the latest version of the API will help us out. I will cover how to set up a quick webhook using Webtask.io that will listen for notifications and kickoff any number of builds.

Project Setup

In order to keep things easy, the repos themselves are simply readme files. I named these repos project-1, project-2, and module-a.

For this example, create all of the projects that are created in Codeship by connecting the repo as a basic project and leaving everything else empty. In other words, there are not any testing or deployment steps at all.

In a real scenario, the steps themselves can be virtually anything, and I want to focus on what happens in the middle — after the module is successfully built and before the projects start a build.

Create the Webhook

I have a deep appreciation for anything that is serverless. Webtask.io is a favorite of mine to use for examples because I can use it for free and it has a quick setup. Once you sign up, simply create a new Webtask and start coding.

Create a new Webtask Function

Create a new Webtask Function, and you can create it as empty. Webtask also offers templates for other common tasks, but we are starting from scratch.

I am using the node-fetch module here. We can add that by clicking the wrench icon and selecting NPM Modules in the dropdown. The left pane will open, and you can click Add Module. Type in node-fetch and select the matching result. Once you do this, you can now use that module in the Webtask directly.

Adding an NPM module

There are also some secrets you will want to set up to match the code as well. This particular Webtask uses codeship_user, codeship_pw for the authentication and codeship_org_id.

You will want to authenticate your user using cURL or Postman first, to get your organization’s ID. For more details about the auth route, you can see the documentation.

curl --request POST \
  --url http://api.codeship.com/v2/auth \
  --header 'authorization: Basic dGVzdC11c2VyOnRoaXNpc3RvdGFsbHlmYWtl' \
  --header 'content-type: text/plain'

Adding a secret

Here is the full code you can copy and paste into the Webtask.

'use latest';
import fetch from 'node-fetch';

const chained_projects = [
  'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
  'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
]

let projects_url, auth;

module.exports = (ctx, cb) => {
  const { codeship_org_id, codeship_user, codeship_pw } = ctx.secrets;
  projects_url = `http://api.codeship.com/v2/organizations/${codeship_org_id}/projects`;
  auth = new Buffer(`${codeship_user}:${codeship_pw}`).toString('base64');

  for (var project in chained_projects) {
    start_build(chained_projects[project]);
  }

  cb(null, ctx.body);
};

function auth_codeship() {
  const options = {
    method: 'POST',
    headers: {
      Authorization: `Basic ${auth}`,
    },
  };

  return fetch('http://api.codeship.com/v2/auth', options)
    .then(res => res.json())
    .then(json => json.access_token);
}

function start_build(project_id) {
    auth_codeship().then(token => {
    const options = {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-type': 'application/json',
      },
      body: JSON.stringify({
         "ref": "heads/master"
      }),
    };

    fetch(`${projects_url}/${project_id}/builds`, options)
      .then(res => res.json())
      .then(json => {
        console.log(json);
      });
  });
}

I have my project UUIDs from the projects API response for the examples I created earlier, and I add those to the chained_projects array. I can then loop through the array and use my start_build function to start up a build on Codeship using the create build API.

At this point, you can test the webhook and see if the projects will start building. I would recommend setting up some fake projects to test, since the code above will restart the last build to the master branch.

Create the Notifications

Once the webhook is up and running, the last task is to call the Webtask when the module is done building. The easiest way to do this would be to use the Codeship notifications.

Navigate to the module project example you created earlier and go to Project Settings, then click Notifications, and finally add a Webhook notification. We only want to get notified on successful builds and when it’s on the master branch. See the image below:

Adding a webhook notification

Now when the module is successfully built, your projects that consume the module will start new builds to validate that the module works within their scope.

Conclusion

Hopefully this quick example of how to use the Codeship API to chain builds together gets you thinking of new ways to enhance your build processes. If you have any questions or comments, I would love to hear from you as well.

Subscribe via Email

Over 60,000 people from companies like Netflix, Apple, Spotify and O'Reilly are reading our articles.
Subscribe to receive a weekly newsletter with articles around Continuous Integration, Docker, and software development best practices.



We promise that we won't spam you. You can unsubscribe any time.

Join the Discussion

Leave us some comments on what you think about this topic or if you like to add something.