@amasad/

heroku-bot

Nodejs

A bot that responds to a slack slash command with a diff of commits going out to heroku

fork
loading
Files
  • index.js
  • package-lock.json
  • package.json

This Plugin Crashed!

Error: Error: must not create an existing file {"type":"CREATE_FILE","wid":"0.6344845789894791","path":"index.js","file":{"path":"index.js","content":{"asEncoding":{"base64":"Ly8gQ3JlYXRlIGEgLmVudiBhbmQgYWRkIHlvdXIgaGVyb2t1IHRva2VuLCBhcHAsIGFuZCB5b3VyIGdpdGh1YiByZXBvCmNvbnN0IEhlcm9rdSA9IHJlcXVpcmUoJ2hlcm9rdS1jbGllbnQnKTsKY29uc3QgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKTsKY29uc3QgdG9rZW4gPSBwcm9jZXNzLmVudi5IRVJPS1VfVE9LRU47CmNvbnN0IHJlcG8gPSBwcm9jZXNzLmVudi5SRVBPX1VSTDsKY29uc3QgaGVyb2t1ID0gbmV3IEhlcm9rdSh7IHRva2VuIH0pOwpjb25zdCBhcHAgPSBwcm9jZXNzLmVudi5BUFA7CgovLyBHZXQgYSBkaWZmIHVybCB3aXRoIGNvbW1taXRzIGJldHdlZW4gdGhlIGxhdGVzdCBkZXBsb3kgYW5kIGdpdGh1YiBtYXN0ZXIKYXN5bmMgZnVuY3Rpb24gY29tbWl0cygpIHsKICBsZXQgcmVsZWFzZXMgPSBhd2FpdCBoZXJva3UuZ2V0KGAvYXBwcy8ke2FwcH0vcmVsZWFzZXNgKTsKICBjb25zdCBsYXRlc3QgPSBmaW5kTGF0ZXN0KHJlbGVhc2VzKTsKICBjb25zdCBmcm0gPSBsYXRlc3QuZGVzY3JpcHRpb24uc3BsaXQoL1xzLylbMV07CiAgY29uc3QgdG9jID0gJ21hc3Rlcic7CgogIHJldHVybiAoCiAgICBgJHtyZXBvfS9jb21wYXJlLyR7ZnJtfS4uLiR7dG9jfWAKICApOwp9CgovLyBUcmFjZWJhY2sgYWxsIHJvbGxiYWNrcyB0byBnZXQgdG8gdGhlIGFjdHVhbCBjb21taXQKZnVuY3Rpb24gZmluZExhdGVzdChyZWxlYXNlcykgewogIGxldCBsYXRlc3QgPSByZWxlYXNlc1tyZWxlYXNlcy5sZW5ndGggLSAxXTsKCiAgdG9wOiB3aGlsZSAodHJ1ZSkgewogICAgaWYgKGxhdGVzdC5kZXNjcmlwdGlvbi5tYXRjaCgvcm9sbGJhY2svaSkpIHsgCiAgICAgIGNvbnN0IHZlcnNpb24gPSBsYXRlc3QuZGVzY3JpcHRpb24uc3BsaXQoL1xzLylbMl07CiAgICAgIGNvbnN0IG51bSA9IHBhcnNlSW50KHZlcnNpb24uc2xpY2UoMSkpOwogICAgICBmb3IgKGNvbnN0IHJlbCBvZiByZWxlYXNlcykgeyAgICAgICAgCiAgICAgICAgaWYgKHJlbC52ZXJzaW9uID09PSBudW0pIHsKICAgICAgICAgIGxhdGVzdCA9IHJlbDsKICAgICAgICAgIGNvbnRpbnVlIHRvcDsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICAvLyBBY3Rpb25zIHRvIGJlIGlnbm9yZWQKICAgIGlmIChsYXRlc3QuZGVzY3JpcHRpb24ubWF0Y2goL15VcGRhdGUvaSkgfHwKICAgICAgbGF0ZXN0LmRlc2NyaXB0aW9uLm1hdGNoKC9jb25maWcgdmFycy8pIHx8CiAgICAgIGxhdGVzdC5kZXNjcmlwdGlvbi5tYXRjaCgvXkRldGFjaC8pIHx8CiAgICAgIGxhdGVzdC5kZXNjcmlwdGlvbi5tYXRjaCgvXkF0dGFjaC8pIHx8CiAgICAgIGxhdGVzdC5kZXNjcmlwdGlvbi5tYXRjaCgvY29tcGxldGVkIHByb3Zpc2lvbmluZy8pKSB7CiAgICAgIGxhdGVzdCA9IHJlbGVhc2VzW3JlbGVhc2VzLmluZGV4T2YobGF0ZXN0KSAtIDFdOwogICAgICBjb250aW51ZTsKICAgIH0KICAgIGJyZWFrOwogIH0KCiAgcmV0dXJuIGxhdGVzdDsKfQoKaHR0cC5jcmVhdGVTZXJ2ZXIoKHJlcSwgcmVzKSA9PiB7CiAgY29tbWl0cygpLnRoZW4oKHVybCkgPT4gewogICAgcmVzLnNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKQogICAgcmVzLmVuZChKU09OLnN0cmluZ2lmeSh7CiAgICAgICJyZXNwb25zZV90eXBlIjogImluX2NoYW5uZWwiLAogICAgICAidGV4dCI6IHVybCwKICAgIH0pKQogIH0pOwp9KS5saXN0ZW4oMzAwMCk="},"asBuffer":null},"loaded":true}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Create a .env and add your heroku token, app, and your github repo
const Heroku = require('heroku-client');
const http = require('http');
const token = process.env.HEROKU_TOKEN;
const repo = process.env.REPO_URL;
const heroku = new Heroku({ token });
const app = process.env.APP;

// Get a diff url with commmits between the latest deploy and github master
async function commits() {
  let releases = await heroku.get(`/apps/${app}/releases`);
  const latest = findLatest(releases);
  const frm = latest.description.split(/\s/)[1];
  const toc = 'master';

  return (
    `${repo}/compare/${frm}...${toc}`
  );
}

// Traceback all rollbacks to get to the actual commit
function findLatest(releases) {
  let latest = releases[releases.length - 1];

  top: while (true) {
    if (latest.description.match(/rollback/i)) { 
      const version = latest.description.split(/\s/)[2];
      const num = parseInt(version.slice(1));
      for (const rel of releases) {        
        if (rel.version === num) {
          latest = rel;
          continue top;
        }
      }
    }

    // Actions to be ignored
    if (latest.description.match(/^Update/i) ||
      latest.description.match(/config vars/) ||
      latest.description.match(/^Detach/) ||
      latest.description.match(/^Attach/) ||
      latest.description.match(/completed provisioning/)) {
      latest = releases[releases.indexOf(latest) - 1];
      continue;
    }
    break;
  }

  return latest;
}

http.createServer((req, res) => {
  commits().then((url) => {
    res.setHeader('Content-Type', 'application/json')
    res.end(JSON.stringify({
      "response_type": "in_channel",
      "text": url,
    }))
  });
}).listen(3000)
node v10.16.0