-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathindex.js
140 lines (120 loc) · 4.03 KB
/
index.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/bin/node
var Promise = require('bluebird')
var request = Promise.promisifyAll(require('request'))
var url = require('url')
var _ = require('underscore')
var POLL_TIMEOUT = process.env['FOSSA_POLL_TIMEOUT'] || 1000 * 60 * 30 // 30 minute polling timeout
var PING_WAIT_TIME = 1000 * 10 // 15 second ping wait time
var api_base_url
var fossa_project_id
var full_fossa_locator
var build_endpoint
var scan_endpoint
var request_headers
function getResource (url) {
return request.getAsync({
url: url,
method: 'GET',
headers: request_headers
})
.then(function (response) {
return JSON.parse(response.body)
})
}
function setup () {
if (!process.env['FOSSA_API_TOKEN']) {
console.error('Environment variable \'FOSSA_API_TOKEN\' not found')
process.exit(1)
}
api_base_url = process.env['FOSSA_ENDPOINT_URL'] || 'https://app.fossa.io/'
// Get project information from CircleCI Environment variables
fossa_project_id = 'git+' + process.env['CIRCLE_REPOSITORY_URL']
full_fossa_locator = fossa_project_id + '$' + process.env['CIRCLE_SHA1']
// Build the FOSSA endpoint URL's
queue_build_endpoint = url.resolve(api_base_url, '/api/revisions/' + encodeURIComponent(full_fossa_locator) + '/build')
build_endpoint = url.resolve(api_base_url, '/api/builds')
scan_endpoint = url.resolve(api_base_url, '/api/revisions/' + encodeURIComponent(full_fossa_locator))
// API Access token to access FOSSA API
request_headers = {
Authorization: 'token ' + process.env['FOSSA_API_TOKEN']
}
}
function run () {
return queueFOSSABuild()
.then(function (build) {
if (!build.id) {
console.error('Build queue failed')
process.exit(1)
}
if (build.status && build.status !== 'RUNNING') return build
return pollFOSSABuildResults(build.id)
})
.then(function (build) {
if (build.status === 'FAILED') throw new Error('FOSSA Build failed. Build error: ' + (build.error || '') )
// build has succeeded! Now check if FOSSA has scanned it for issues yet...
return pollFOSSAScanResults()
})
.then(function (revision) {
if (revision.unresolved_issue_count > 0) throw new Error('FOSSA Issue scan has found issues. Please resolve these to pass build.')
console.log('FOSSA scan has passed.')
process.exit(0) // Success!
})
.catch(function (err) {
console.error('Error getting FOSSA build data: ' + err.toString())
process.exit(1)
})
}
// This function will ping the FOSSA API for build data on the current SHA1 of the build. It will keep pinging this URL for 30 minutes
function pollFOSSABuildResults (build_id) {
console.log("Polling FOSSA build: " + build_id + '...')
function poll () {
return getResource(build_endpoint + '/' + build_id)
.then(function (build_data) {
var completed_build = (build_data.status && build_data.status !== 'RUNNING') //Build is not null and either FAILED or SUCCEEDED
// if no build has been found yet, or it is still queued/running wait then ping URL again
if (!completed_build) {
return Promise.delay(PING_WAIT_TIME).then(poll)
}
return build_data
})
}
return poll().timeout(POLL_TIMEOUT) // total timeout time of 30 minutes
.catch(function (err) {
console.error('Error fetching FOSSA build: ' + err.toString())
process.exit(1)
})
}
function pollFOSSAScanResults () {
console.log("Polling FOSSA for resolved revision.")
function poll () {
return getResource(scan_endpoint)
.then(function (scan_data) {
var scanned_revision = (scan_data.unresolved_issue_count !== null)
// if issue count hasn't been set, then the revision still needs to be scanned
if (!scanned_revision) {
return Promise.delay(PING_WAIT_TIME).then(poll)
}
return scan_data
})
}
return poll().timeout(POLL_TIMEOUT)
.catch(function (err) {
console.error('Error fetching FOSSA scan: ' + err.toString())
process.exit(1)
})
}
function queueFOSSABuild () {
console.log("Queuing a FOSSA build.")
return request.putAsync({
url: queue_build_endpoint,
method: 'PUT',
headers: request_headers
})
.then(function (response) {
return JSON.parse(response.body)
})
}
// setup global vars
setup()
// run!
run()