I recently had an issue that Coveralls did not support the output from the Codeship build webhook. So I needed to send data from the Codeship webhook to an intermediary, change the format of the json, and then send it to Coveralls.

There are a lot of services that can do similar things, like Zapier or IFTT. But what I needed was incredibly simple, and a Google Cloud function, with a few lines of code suits this use case quite well.

The payload from the webhook from Codeship generally looks like this:

{
  "build": {
    "uuid": "20b4a690-6a03-0145-d6ec-0000000000",
    "project_uuid": "7b3596c0-560e-0135-5b18-000000000000",
    "organization_uuid": "721cea10-b695-0134-5b94-000000000000",
    "ref": "heads/master",
    "commit_sha": "575a1521fff1466c3ed9fae9d390e0ffffffffff",
    "status": "success",
    "username": "dennisnewel",
    "commit_message": "Update to API documentation",
    "finished_at": "2017-08-23T07:26:01.877Z",
    "allocated_at": null,
    "queued_at": "2017-08-23T07:24:41.327Z",
    "links": {
      "pipelines": "https://api.codeship.com/v2/organizations/721cea10-b695-0134-5b94-000000000000/projects/7b3596c0-560e-0135-5b18-000000000000/builds/20b4a690-6a03-0135-d6ec-000000000000/pipelines"
    }
  }
}

And the payload that Coveralls needs looks something like this:

{
  "payload": {
    "build_num": 1234,
    "status": "done"
  }
}

First I setup environment variables for the REPO_TOKEN, and then these few lines of js are all you need to send data from the webhook.

const fetch = require('node-fetch');

exports.coveralls = async (req, res) => {
  let data;
  data = JSON.parse(req.rawBody);
  // console.log(data.build.build_id);
  // console.log(data.build.status);
  if (data.build.status == 'success') {
    coverallsResponse =
      await fetch(`https://coveralls.io/webhook.json?repo_token=${process.env.REPO_TOKEN}`,
        {
          method: 'POST',
          body: JSON.stringify({
              payload: {
                build_num: data.build.build_id,
                status: 'done'
              }
          }),
          headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json'
          }
        }
      ).then((response) => {
        if (!response.ok) {
          console.error(`Error: Response from Coveralls was ${response.statusText}`);
        }
      }).catch((error) => {
        console.error(error.message);
      })
  }
  res.status(200).send(`Done.`);
}