Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] jenkins: add a node-ci pipeline for running tests #1156

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions jenkins/pipelines/node-ci.jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#!/usr/bin/env groovy

properties([
parameters([
booleanParam(name: 'CERTIFY_SAFE', defaultValue: false, description: 'I have reviewed *the latest version of* these changes and I am sure that they don’t contain any code that could compromise the security of the CI infrastructure.'),
string(name: 'GITHUB_REPO', defaultValue: 'nodejs/node', description: 'The user/repo targeted by the PR'),
string(name: 'GIT_REF', defaultValue: 'refs/pull/XXX/head', description: 'The ref to build (branch name or "refs/pull/<PR number>/head"'),
booleanParam(name: 'POST_STATUS_TO_PR', defaultValue: true, description: 'Posts build status updates to a nodejs/node PR.'),
choice(name: 'REBASE_ONTO', choices: '''<pr base branch>
master
next
next+1
v4.x
v3.x
v0.12
v0.10
<no rebasing>''', description: 'Branch to rebase onto before building'),
]),
])

// TODO(gib): Enable the "Trigger builds remotely (e.g., from scripts)" option.

/*
* I know this is awful, but the params dict we get (`params`) is immutable. So
* we need to copy it to a mutable dict (`pr`), modify it, and then create
* another immutable set of parameters (`p`). It also creates a Stringified
* version (`printParams`) for pretty-printing.
*/

def pr = [:] // Mutable copy of params.
params.each{ key, value -> pr.put(key, value) }

/*
* Validate sane parameters were passed.
*/

if (pr['CERTIFY_SAFE'] == "false") {
error("Please certify that you have reviewed the changes to be tested, by ticking the CERTIFY_SAFE checkbox on the job launch page.")
}
if (!pr['GITHUB_REPO']) { error("You didn't define the target GitHub repo, bailing.") }
if (!pr['GIT_REF']) { error("You didn't define a ref to clone, bailing.") }

/*
* Work out which branch to rebase onto.
*/

if (pr['REBASE_ONTO'] == "<pr base branch>") {
def jsonResponse = new URL(
"https://api.github.com/repos/${TARGET_GITHUB_ORG}/${TARGET_REPO_NAME}/pulls/${PR_ID}"
).getText()
def json = new groovy.json.JsonSlurper().parseText(jsonResponse)
pr['PR_BASE_BRANCH'] = json.base.ref
pr['GIT_SHA'] = json.head.sha

if (!pr['PR_BASE_BRANCH']) { error("Failed to detect PR base branch.") }

pr['REBASE_ONTO']="origin/${pr['PR_BASE_BRANCH']}"
} else if (pr['REBASE_ONTO'] == "<no rebasing>") {
pr['REBASE_ONTO']=""
} else {
pr['REBASE_ONTO']="origin/${pr['REBASE_ONTO']}"
}

/*
* Add other needed parameters.
*/

pr['NODES_SUBSET'] = "auto"
pr['IGNORE_FLAKY_TESTS'] = "true"
pr['REPO_NAME'] = pr['TARGET_REPO_NAME']
pr['GIT_REMOTE_REF'] = pr['GIT_REF']


def p = [] // Parameter class to pass to jobs.
String printParams = '' // String of params to print

for (param in pr) {
printParams += param.toString() + '\n'
p.push(string(name: param.key, value: "${param.value}"))
}

// println "Running ci on this Pull Request:\n${printParams}\n"

// Set the description that shows up next to the build number.
currentBuild.description = "${pr['TARGET_GITHUB_ORG']}/${pr['TARGET_REPO_NAME']}#${pr['PR_ID']}"


// TODO(gib): Is this needed in this job?

// stage('Abort existing rebase') { timeout(60) {
// node('jenkins-workspace') {
// withEnv(["REPO_NAME=${pr['REPO_NAME']}", "GIT_REMOTE_REF=${GIT_REMOTE_REF}"]) {
// def ret = sh(
// script: '''
// git rebase --abort || true
// git checkout -f refs/remotes/origin/_jenkins_local_branch
// '''
// )
// }
// }}

def statusOptions = [
IDENTIFIER: "node-test-pull-request",
URL: env.BUILD_URL,
COMMIT: pr['GIT_SHA'],
REF: pr['GIT_REMOTE_REF'],
STATUS: "pending",
]

// println "Pre Build Status Update Params:\n${statusOptions}"

def statusParams = []
statusOptions.each{key, value -> statusParams.push(string(name: key, value: value)) }

stage('Pre Build Status Update') {
build(job: 'post-build-status-update', parameters: statusParams)
}

/*
* Run node-test-commit with the correct parameters.
*/

stage('node-test-commit') {
def buildStatus = build(job: "node-test-commit", parameters: p, propagate: false)
currentBuild.result = buildStatus.result
}

/*
* Run post-build-status-update again with STATUS set to the return code
*/

statusOptions.STATUS = currentBuild.result.toString().toLowerCase()
statusParams = []
statusOptions.each{key, value -> statusParams.push(string(name: key, value: value)) }

// println "Post Build Status Update Params:\n${statusOptions}"

stage('Post Build Status Update') {
build(job: 'post-build-status-update', parameters: statusParams)
}

// println "\n\n \\(• ◡ •)/ FLOW COMPLETE \\(• ◡ •)/\n\n"