forked from openshift/openshift-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJenkinsfile
More file actions
147 lines (130 loc) · 6.17 KB
/
Jenkinsfile
File metadata and controls
147 lines (130 loc) · 6.17 KB
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
141
142
143
144
145
146
147
// Process the github webhook and trigger tests or builds depending on the payload data
node {
stage "Check PR Action"
// Parse json payload
def test_key = "[test]"
def slurper = new groovy.json.JsonSlurper()
def jout = new groovy.json.JsonOutput()
def webhook = slurper.parseText(payload)
def trigger
def pull_request
// The following are the actions we should test:
// "opened", "reopened", "synchronize"
// We should build if the action is "closed" and the "merged" flag is true
// The "edited" action is when a comment is edited, we don't care about that.
// Additionally, to support re-testing via a comment made on the PR, we should test
// on the following issue-only actions:
// created, edited
// These will requier some additional verification, as tests should only commence if
// the comment was made on an open pull request and includes a certain phrase.
// The following block determines the action (trigger) to take depending on the action field in the webhook
def action = webhook.action
echo "Webhook payload action: ${action}"
if (action == "opened" || action == "reopened" || action == "synchronize") {
echo "Pull request has been opened or modified, testing..."
pull_request = webhook.pull_request
trigger = "test"
} else if (action == "closed" && webhook.pull_request.merged) {
echo "Pull request has been merged, running builds..."
pull_request = webhook.pull_request
trigger = "build"
} else if (action == "created" || action == "edited") {
if (webhook.issue && webhook.issue.containsKey("pull_request")) {
body = webhook.comment.body
if (body.toLowerCase().contains(test_key)) {
echo "Pull request comment contains '${test_key}', running tests..."
// The webhook only contains the comment and issue details. We need to get the pull request
pr_json = get_pr(webhook.issue.pull_request.url)
pull_request = slurper.parseText(pr_json)
trigger = "test"
} else {
echo "Pull request comment does not contain '${test_key}'. Ignoring..."
}
} else {
echo "Comment made on issue, not pull request. Ignoring..."
}
}
echo "Trigger: ${trigger}"
// From the determined trigger, initiate tests or builds
if (trigger != null) {
// Unset the pull request title and body in the pull request json
// This is done to avoid possible issues in parsing the json when unexpected characters are used in the title and body
pull_request.title = ""
pull_request.body = ""
// Get sha and repo to submit pr update
sha = pull_request.head.sha
repo = pull_request.base.repo.full_name
// Get the json string representation of the updated pull request data to pass to openshift
pull_request_string = jout.toJson(pull_request)
// These variables must be nullified as they are not serializable
// See http://stackoverflow.com/questions/37864542/jenkins-pipeline-notserializableexception-groovy-json-internal-lazymap
slurper = null
jout = null
webhook = null
pull_request = null
if (trigger == "test") {
stage "Test Changes"
run_tests(pull_request_string, sha, repo)
} else if (trigger == "build") {
stage "Build RPMS"
echo "Starting Build"
// TODO this is not yet implemented
stage "Deploy Updates"
echo "Deploying updated RPMs"
// TODO this is not yet implemented
} else {
echo "Trigger ${trigger} not recognized"
currentBuild.result = 'FAILURE'
}
} else {
echo "Webhook action, ${action}, does not justify running any jobs."
currentBuild.result = 'SUCCESS'
}
}
// Run pull request testing
def run_tests(pull_request_string, sha, repo) {
echo "Starting Tests"
update_pr_status("pending", "Automated tests in progress", sha, repo)
try {
openshiftBuild buildConfig: 'openshift-tools-test', env: [[ name: 'PULL_REQUEST', value: pull_request_string ], [ name: 'BUILD_URL', value: env.BUILD_URL ]], showBuildLogs: true
// It is the build's responsibility to update the PR status when the tests pass
// This is to ensure that the PR is updated with "success" as soon as possible
currentBuild.result = 'SUCCESS'
} catch(Exception e) {
println "Build failed!"
update_pr_status("failure", "Automated tests failed", sha, repo)
currentBuild.result = 'FAILURE'
}
}
// Update the status of a pull request
def update_pr_status(state, text, sha, repo) {
String token = new File('/openshift-ops-bot/token').text
def target_url = env.BUILD_URL
def urlString = "https://api.github.com/repos/" + repo + "/statuses/" + sha
def url = new URL(urlString)
def conn = url.openConnection()
conn.setRequestMethod("POST")
conn.setRequestProperty("Content-Type", "application/json")
conn.setRequestProperty("Authorization", "token " + token)
def data = '{"state": "' + state + '", "description": "' + text + '", "target_url": "' +
target_url + '", "context": "jenkins-ci"}'
println "Updating ${sha} in github with state ${state} and description ${text}..."
conn.doOutput = true
def writer = new OutputStreamWriter(conn.outputStream)
writer.write(data)
writer.flush()
writer.close()
conn.connect()
println "Posted PR status update with response: ${conn.responseCode} ${conn.responseMessage}"
}
// Get a pull request
def get_pr(urlString) {
String token = new File('/openshift-ops-bot/token').text
def url = new URL(urlString)
def conn = url.openConnection()
conn.setRequestMethod("GET")
conn.setRequestProperty("Authorization", "token " + token)
conn.connect()
assert conn.responseCode == 200
return conn.content.text
}