blob: 9c363cd06ceb00ec384a7b2c4a3bb53a5a9d016e [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
// Import the utility functionality.
import jobs.generation.Utilities
// Grab the github project name passed in
def project = GithubProject
def branch = GithubBranchName
def msbuildTypeMap = [
'debug':'chk',
'test':'test',
'release':'fre'
]
// convert `machine` parameter to OS component of PR task name
def machineTypeToOSTagMap = [
'Windows_NT': 'Windows', // Windows Server 2012 R2, equivalent to Windows 8.1 (aka Blue)
'Ubuntu16.04': 'Ubuntu',
'OSX10.12': 'OSX'
]
def dailyRegex = 'dailies'
// ---------------
// HELPER CLOSURES
// ---------------
def CreateBuildTask = { isPR, buildArch, buildType, machine, configTag, buildExtra, testExtra, runCodeAnalysis, excludeConfigIf, nonDefaultTaskSetup ->
if (excludeConfigIf && excludeConfigIf(isPR, buildArch, buildType)) {
return // early exit: we don't want to create a job for this configuration
}
def config = "${buildArch}_${buildType}"
config = (configTag == null) ? config : "${configTag}_${config}"
// params: Project, BaseTaskName, IsPullRequest (appends '_prtest')
def jobName = Utilities.getFullJobName(project, config, isPR)
def testableConfig = buildType in ['debug', 'test'] && buildArch != 'arm'
def analysisConfig = buildType in ['release'] && runCodeAnalysis
def buildScript = "call .\\jenkins\\buildone.cmd ${buildArch} ${buildType} "
buildScript += buildExtra ?: ''
buildScript += analysisConfig ? ' "/p:runcodeanalysis=true"' : ''
def testScript = "call .\\jenkins\\testone.cmd ${buildArch} ${buildType} "
testScript += testExtra ?: ''
def analysisScript = '.\\Build\\scripts\\check_prefast_error.ps1 . CodeAnalysis.err'
def newJob = job(jobName) {
// This opens the set of build steps that will be run.
// This looks strange, but it is actually a method call, with a
// closure as a param, since Groovy allows method calls without parens.
// (Compare with '.each' method used above.)
steps {
batchFile(buildScript) // run the parameter as if it were a batch file
if (testableConfig) {
batchFile(testScript)
}
if (analysisConfig) {
powerShell(analysisScript)
}
}
}
def msbuildType = msbuildTypeMap.get(buildType)
def msbuildFlavor = "build_${buildArch}${msbuildType}"
def archivalString = "test/${msbuildFlavor}.*,test/logs/**"
archivalString += analysisConfig ? ',CodeAnalysis.err' : ''
Utilities.addArchival(newJob, archivalString,
'', // no exclusions from archival
false, // doNotFailIfNothingArchived=false ~= failIfNothingArchived
false) // archiveOnlyIfSuccessful=false ~= archiveAlways
Utilities.setMachineAffinity(newJob, machine, 'latest-or-auto')
Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
if (nonDefaultTaskSetup == null) {
if (isPR) {
def osTag = machineTypeToOSTagMap.get(machine)
Utilities.addGithubPRTriggerForBranch(newJob, branch, "${osTag} ${config}")
} else {
Utilities.addGithubPushTrigger(newJob)
}
} else {
// nonDefaultTaskSetup is e.g. DailyBuildTaskSetup (which sets up daily builds)
// These jobs will only be configured for the branch specified below,
// which is the name of the branch netci.groovy was processed for.
// See list of such branches at:
// https://github.com/dotnet/dotnet-ci/blob/master/jobs/data/repolist.txt
nonDefaultTaskSetup(newJob, isPR, config)
}
}
def CreateBuildTasks = { machine, configTag, buildExtra, testExtra, runCodeAnalysis, excludeConfigIf, nonDefaultTaskSetup ->
[true, false].each { isPR ->
['x86', 'x64', 'arm'].each { buildArch ->
['debug', 'test', 'release'].each { buildType ->
CreateBuildTask(isPR, buildArch, buildType, machine, configTag, buildExtra, testExtra, runCodeAnalysis, excludeConfigIf, nonDefaultTaskSetup)
}
}
}
}
def CreateXPlatBuildTask = { isPR, buildType, staticBuild, machine, platform, configTag,
xplatBranch, nonDefaultTaskSetup, customOption, testVariant, extraBuildParams ->
def config = (platform == "osx" ? "osx_${buildType}" : "linux_${buildType}")
def numConcurrentCommand = (platform == "osx" ? "sysctl -n hw.logicalcpu" : "nproc")
config = (configTag == null) ? config : "${configTag}_${config}"
config = staticBuild ? "static_${config}" : "shared_${config}"
config = customOption ? customOption.replaceAll(/[-]+/, "_") + "_" + config : config
// params: Project, BaseTaskName, IsPullRequest (appends '_prtest')
def jobName = Utilities.getFullJobName(project, config, isPR)
def infoScript = "bash jenkins/get_system_info.sh --${platform}"
def buildFlag = buildType == "release" ? "" : (buildType == "debug" ? "--debug" : "--test-build")
def staticFlag = staticBuild ? "--static" : ""
def swbCheckFlag = (platform == "linux" && buildType == "debug" && !staticBuild) ? "--wb-check" : "";
def icuFlag = (platform == "osx" ? "--icu=/usr/local/opt/icu4c/include" : "")
def compilerPaths = (platform == "osx") ? "" : "--cxx=/usr/bin/clang++-3.9 --cc=/usr/bin/clang-3.9"
def buildScript = "bash ./build.sh ${staticFlag} -j=`${numConcurrentCommand}` ${buildFlag} " +
"${swbCheckFlag} ${compilerPaths} ${icuFlag} ${customOption} ${extraBuildParams}"
def testScript = "bash test/runtests.sh \"${testVariant}\""
def newJob = job(jobName) {
steps {
shell(infoScript)
shell(buildScript)
shell(testScript)
}
}
def archivalString = "out/build.log"
Utilities.addArchival(newJob, archivalString,
'', // no exclusions from archival
true, // doNotFailIfNothingArchived=false ~= failIfNothingArchived (true ~= doNotFail)
false) // archiveOnlyIfSuccessful=false ~= archiveAlways
Utilities.setMachineAffinity(newJob, machine, 'latest-or-auto')
Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
if (nonDefaultTaskSetup == null) {
if (isPR) {
def osTag = machineTypeToOSTagMap.get(machine)
Utilities.addGithubPRTriggerForBranch(newJob, xplatBranch, "${osTag} ${config}")
} else {
Utilities.addGithubPushTrigger(newJob)
}
} else {
// nonDefaultTaskSetup is e.g. DailyBuildTaskSetup (which sets up daily builds)
// These jobs will only be configured for the branch specified below,
// which is the name of the branch netci.groovy was processed for.
// See list of such branches at:
// https://github.com/dotnet/dotnet-ci/blob/master/jobs/data/repolist.txt
nonDefaultTaskSetup(newJob, isPR, config)
}
}
// Generic task to trigger clang-based cross-plat build tasks
def CreateXPlatBuildTasks = { machine, platform, configTag, xplatBranch, nonDefaultTaskSetup, extraBuildParams ->
[true, false].each { isPR ->
CreateXPlatBuildTask(isPR, "test", "", machine, platform,
configTag, xplatBranch, nonDefaultTaskSetup, "--no-jit", "--variants disable_jit", extraBuildParams)
['debug', 'test', 'release'].each { buildType ->
def staticBuildConfigs = [true, false]
if (platform == "osx") {
staticBuildConfigs = [true]
}
staticBuildConfigs.each { staticBuild ->
CreateXPlatBuildTask(isPR, buildType, staticBuild, machine, platform,
configTag, xplatBranch, nonDefaultTaskSetup, "", "", extraBuildParams)
}
}
}
}
def DailyBuildTaskSetup = { newJob, isPR, triggerName, groupRegex ->
// The addition of triggers makes the job non-default in GitHub.
if (isPR) {
def triggerRegex = "(${dailyRegex}|${groupRegex}|${triggerName})"
Utilities.addGithubPRTriggerForBranch(newJob, branch,
triggerName, // GitHub task name
"(?i).*test\\W+${triggerRegex}.*")
} else {
Utilities.addPeriodicTrigger(newJob, '@daily')
}
}
def CreateStyleCheckTasks = { taskString, taskName, checkName ->
[true, false].each { isPR ->
def jobName = Utilities.getFullJobName(project, taskName, isPR)
def newJob = job(jobName) {
steps {
shell(taskString)
}
}
Utilities.standardJobSetup(newJob, project, isPR, "*/${branch}")
if (isPR) {
// Set PR trigger.
Utilities.addGithubPRTriggerForBranch(newJob, branch, checkName)
} else {
// Set a push trigger
Utilities.addGithubPushTrigger(newJob)
}
Utilities.setMachineAffinity(newJob, 'Ubuntu16.04', 'latest-or-auto')
}
}
// ----------------
// INNER LOOP TASKS
// ----------------
CreateBuildTasks('Windows_NT', null, null, "-winBlue", true, null, null)
// Add some additional daily configs to trigger per-PR as a quality gate:
// x64_debug Slow Tests
CreateBuildTask(true, 'x64', 'debug',
'Windows_NT', 'ci_slow', null, '-winBlue -includeSlow', false, null, null)
// x64_debug DisableJIT
CreateBuildTask(true, 'x64', 'debug',
'Windows_NT', 'ci_disablejit', '"/p:BuildJIT=false"', '-winBlue -disablejit', false, null, null)
// x64_debug Lite
CreateBuildTask(true, 'x64', 'debug',
'Windows_NT', 'ci_lite', '"/p:BuildLite=true"', '-winBlue -lite', false, null, null)
// -----------------
// DAILY BUILD TASKS
// -----------------
if (!branch.endsWith('-ci')) {
// build and test on the usual configuration (VS 2015) with -includeSlow
CreateBuildTasks('Windows_NT', 'daily_slow', null, '-winBlue -includeSlow', false,
/* excludeConfigIf */ null,
/* nonDefaultTaskSetup */ { newJob, isPR, config ->
DailyBuildTaskSetup(newJob, isPR,
"Windows ${config}",
'slow\\s+tests')})
// build and test on the usual configuration (VS 2015) with JIT disabled
CreateBuildTasks('Windows_NT', 'daily_disablejit', '"/p:BuildJIT=false"', '-winBlue -disablejit', true,
/* excludeConfigIf */ null,
/* nonDefaultTaskSetup */ { newJob, isPR, config ->
DailyBuildTaskSetup(newJob, isPR,
"Windows ${config}",
'(disablejit|nojit)\\s+tests')})
}
// ----------------
// CODE STYLE TASKS
// ----------------
CreateStyleCheckTasks('./jenkins/check_copyright.sh', 'ubuntu_check_copyright', 'Copyright Check')
CreateStyleCheckTasks('./jenkins/check_eol.sh', 'ubuntu_check_eol', 'EOL Check')
CreateStyleCheckTasks('./jenkins/check_tabs.sh', 'ubuntu_check_tabs', 'Tab Check')
// --------------
// XPLAT BRANCHES
// --------------
// Explicitly enumerate xplat-incompatible branches, because we don't anticipate any future incompatible branches
def isXPlatCompatibleBranch = !(branch in ['release/1.1', 'release/1.1-ci', 'release/1.2', 'release/1.2-ci'])
// Include these explicitly-named branches
def isXPlatDailyBranch = branch in ['master', 'linux', 'xplat']
// Include some release/* branches (ignore branches ending in '-ci')
if (branch.startsWith('release') && !branch.endsWith('-ci')) {
// Allows all current and future release/* branches on which we should run daily builds of XPlat configs.
// RegEx matches branch names we should ignore (e.g. release/1.1, release/1.2, release/1.2-pre)
includeReleaseBranch = !(branch =~ /^release\/(1\.[12](\D.*)?)$/)
isXPlatDailyBranch |= includeReleaseBranch
}
// -----------------
// LINUX BUILD TASKS
// -----------------
if (isXPlatCompatibleBranch) {
def osString = 'Ubuntu16.04'
// PR and CI checks
CreateXPlatBuildTasks(osString, "linux", "ubuntu", branch, null, "")
// Create a PR/continuous task to check ubuntu/static/debug/no-icu
[true, false].each { isPR ->
CreateXPlatBuildTask(isPR, "debug", true, osString, "linux",
"ubuntu", branch, null, "--no-icu", "--not-tag exclude_noicu", "")
}
// daily builds
if (isXPlatDailyBranch) {
CreateXPlatBuildTasks(osString, "linux", "daily_ubuntu", branch,
/* nonDefaultTaskSetup */ { newJob, isPR, config ->
DailyBuildTaskSetup(newJob, isPR,
"Ubuntu ${config}",
'linux\\s+tests')},
/* extraBuildParams */ "--extra-defines=PERFMAP_TRACE_ENABLED=1")
}
}
// ---------------
// OSX BUILD TASKS
// ---------------
if (isXPlatCompatibleBranch) {
def osString = 'OSX10.12'
// PR and CI checks
CreateXPlatBuildTasks(osString, "osx", "osx", branch, null, "")
// daily builds
if (isXPlatDailyBranch) {
CreateXPlatBuildTasks(osString, "osx", "daily_osx", branch,
/* nonDefaultTaskSetup */ { newJob, isPR, config ->
DailyBuildTaskSetup(newJob, isPR,
"OSX ${config}",
'linux\\s+tests')},
/* extraBuildParams */ "")
}
}
// ------------
// HELP MESSAGE
// ------------
Utilities.createHelperJob(this, project, branch,
"Welcome to the ${project} Repository", // This is prepended to the help message
"For additional documentation on ChakraCore CI checks, please see:\n" +
"\n" +
"* https://github.com/Microsoft/ChakraCore/wiki/Jenkins-CI-Checks\n" +
"* https://github.com/Microsoft/ChakraCore/wiki/Jenkins-Build-Triggers\n" +
"* https://github.com/Microsoft/ChakraCore/wiki/Jenkins-Repro-Steps\n" +
"\n" +
"Have a nice day!") // This is appended to the help message. You might put known issues here.