-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathplugin.js
87 lines (71 loc) · 2.84 KB
/
plugin.js
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
const express = require('express')
const bodyParser = require('body-parser')
const { Octokit } = require('@octokit/rest')
const yaml = require('yaml')
const glob = require('globule')
const createFilesChangedDeterminer = require('./lib/files-changed-determiner')
const createParsedYamlRetriever = require('./lib/parsed-yaml-retriever')
const isValidSig = require('./lib/signature-validator')
const githubToken = process.env.GITHUB_TOKEN
const sharedKey = process.env.PLUGIN_SECRET
const gh = new Octokit({
auth: githubToken
})
const determineFilesChanged = createFilesChangedDeterminer(gh)
const getParsedYaml = createParsedYamlRetriever(gh)
const nullYaml = index => `kind: pipeline\nname: default_${index}\ntrigger:\n event:\n exclude: [ "*" ]`
const app = express()
app.post('/', bodyParser.json({limit: '50mb'}), async (req, res) => {
console.log('Processing...')
if (!req.headers.signature) return res.status(400).send('Missing signature')
if (!isValidSig(req, sharedKey)) return res.status(400).send('Invalid signature')
if (!req.body) return res.sendStatus(400)
const data = req.body
let filesChanged = []
try {
filesChanged = await determineFilesChanged(data)
} catch (e) {
console.log('ERROR:', e)
return res.sendStatus(500)
}
console.log('Files changed:', filesChanged)
let parsedYaml = null
try {
parsedYaml = await getParsedYaml(data)
} catch (e) {
if (e.code === 404) return res.sendStatus(204)
console.log('ERROR:', e)
return res.sendStatus(500)
}
const finalYamlDocs = parsedYaml.map((py, index) => {
if (py.kind !== 'pipeline') return yaml.stringify(py)
if (py.trigger && py.trigger.changeset && py.trigger.changeset.includes) {
const requiredFiles = py.trigger.changeset.includes
const matchedFiles = glob.match(requiredFiles, filesChanged, { dot: true })
console.log('Matched files for pipeline:', matchedFiles.length, 'Allowed matches:', requiredFiles)
if (!matchedFiles.length) {
py.trigger = { event: { exclude: ['*'] } }
return yaml.stringify(py)
}
}
const transformedSteps = py.steps.map(s => {
if (!s.when || !s.when.changeset || !s.when.changeset.includes) {
return s;
}
const requiredFiles = s.when.changeset.includes
const matchedFiles = glob.match(requiredFiles, filesChanged, { dot: true })
console.log('Matched files for step:', matchedFiles.length, 'Allowed matches:', requiredFiles)
if (!matchedFiles.length) {
// Add an impossible conditional which guarantees the step gets skipped
s.when = {
...s.when,
event: { exclude: ['*'] },
}
}
return s;
})
return transformedSteps.length ? yaml.stringify({ ...py, steps: transformedSteps }) : nullYaml(index)
})
res.json({ Data: finalYamlDocs.join('\n---\n') })
})
app.listen(3000)