Skip to content

Instantly share code, notes, and snippets.

@markmandel
Last active February 16, 2018 17:24
Show Gist options
  • Save markmandel/2d20f543f60eb09f361126555a56fa5e to your computer and use it in GitHub Desktop.
Save markmandel/2d20f543f60eb09f361126555a56fa5e to your computer and use it in GitHub Desktop.
Connect Google Container Builder to Github with Google Cloud Functions
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// npm install github
var GitHubApiModule = require('github');
var githubapi = new GitHubApiModule();
// user token
githubapi.authenticate({
type: 'token',
// use a user token, or auth of your choice
token: '<your user token>'
});
/**
* Responds to Github Webhook
* Connect this function to the Github Webhook
* gcloud beta functions deploy github --trigger-http
*
* @param {Object} req Cloud Function request context.
* @param {Object} res Cloud Function response context.
*/
exports.github = function github(req, res) {
if (req.get('X-GitHub-Event') == "push") {
console.log("Github push request recieved");
var msg = req.body.head_commit.message;
if (msg.includes("[skip ci]") || msg.includes("[ci skip]")) {
console.log("Skipping CI");
res.status(200).end();
return;
}
var args = {
owner: req.body.repository.owner.login,
repo: req.body.repository.name,
sha: req.body.head_commit.id,
state: "pending",
context: "build-bot",
description: "Starting build process...",
};
console.log("Setting commit status:", args);
githubapi.repos.createStatus(args)
.then(() => res.status(200).end())
.catch(err => {
console.log("error setting status:", err);
res.status(504).end();
});
} else {
res.status(400).end();
}
};
/**
* Called on Google Cloud Container Builder builds
* Connect this to the Google Container Builder pubsub topic
* gcloud beta functions deploy builder --trigger-topic cloud-builds
*
* @param {object} event The Cloud Functions event.
*/
exports.builder = function builder(event) {
// since we don't know the originating repo (as we sync to cloud source repo)
// specify it here
var owner = "<your repo>";
var status = event.data.attributes.status;
var buildId = event.data.attributes.buildId;
var dataJSON = Buffer.from(event.data.data, 'base64').toString();
var data = JSON.parse(dataJSON);
console.log("received event: status:", status);
console.log("received event: data:", data);
var args = {
owner: owner,
repo: data.sourceProvenance.resolvedRepoSource.repoName, // we assume the repo names match
sha: data.sourceProvenance.resolvedRepoSource.commitSha,
context: "build-bot",
target_url: data.logUrl,
};
switch (status) {
case "QUEUED":
args.state = "pending";
args.description = "Build " + buildId + " is queued";
break;
case "WORKING":
args.state = "pending";
args.description = "Build " + buildId + " is working";
break;
case "SUCCESS":
args.state = "success";
args.description = "Build " + buildId + " succeeded";
break;
case "FAILURE":
args.state = "failure";
args.description = "Build " + buildId + " failed";
break;
// anything else means it failed somehow
default:
args.state = "error";
args.description = "Build " + buildId + " errored with a status of: " + status;
break;
}
console.log("Sending github status: ", args);
return githubapi.repos.createStatus(args);
};
@Philmod
Copy link

Philmod commented Dec 29, 2017

Hey Mark,

Why is the first function even necessary (the github one)?
When the build is started ("QUEUED"), it will send a status anyway.

Cheers,
Mod

@markmandel
Copy link
Author

@Philmod - basically I was concerned that if the container builder step didn't even start, then a PR could still be pushed through.

It's more of a "just in case".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment