Files
llvm-project/.ci/green-dragon/bisect.groovy
Justice Adams bdf4eaed89 [green-dragon] fix test param in triggered bisection jobs (#181962)
Fix the usage of our skip_tests parm
2026-02-17 20:30:23 -08:00

192 lines
7.2 KiB
Groovy

branchName = 'main'
library identifier: "zorg-shared-lib@${branchName}",
retriever: modernSCM([
$class: 'GitSCMSource',
remote: "https://github.com/llvm/llvm-zorg.git"
])
pipeline {
options {
skipDefaultCheckout()
}
agent {
node {
label 'macos-trigger'
}
}
parameters {
string(name: 'GOOD_COMMIT', description: 'Known good commit SHA', defaultValue: '')
string(name: 'BAD_COMMIT', description: 'Known bad commit SHA', defaultValue: '')
choice(
name: 'TEST_JOB_NAME',
choices: [
'clang-stage1-RA',
'clang-stage1-RA-cmake-incremental',
'clang-stage1-RA-expensive',
'clang-stage1-RA-as',
'clang-san-iossim',
'clang-stage2-cmake-RgSan',
'clang-stage2-cmake-RgTSan',
'clang-stage2-Rthinlto',
],
description: 'Job to execute for testing each commit'
)
choice(
name: 'REPOSITORY',
choices: ['llvm-project'],
description: 'Repository to bisect'
)
booleanParam(name: 'RUN_TESTS', defaultValue: true, description: 'Run tests as part of bisection. Set to False if bisecting a build failure.')
string(name: 'SESSION_ID', description: 'Session ID to continue (optional)', defaultValue: '')
booleanParam(name: 'DRY_RUN', defaultValue: false, description: 'Dry run mode')
string(name: 'REQUESTOR', description: 'Email address of the requestor', defaultValue: '')
}
stages {
stage('Validate Parameters') {
steps {
script {
if (!params.GOOD_COMMIT || !params.BAD_COMMIT) {
error("Both GOOD_COMMIT and BAD_COMMIT parameters are required")
}
if (!params.TEST_JOB_NAME) {
error("TEST_JOB_NAME parameter is required")
}
}
}
}
stage('Setup Repository') {
steps {
script {
echo "📁 Setting up repository: ${params.REPOSITORY}..."
dir(params.REPOSITORY) {
// Clone or checkout the repository
checkout([$class: 'GitSCM', branches: [
[name: params.GOOD_COMMIT]
], extensions: [
[$class: 'CloneOption',
timeout: 30]
], userRemoteConfigs: [
[url: 'https://github.com/llvm/llvm-project.git']
]])
// Verify commits exist
sh "git cat-file -e ${params.GOOD_COMMIT}"
sh "git cat-file -e ${params.BAD_COMMIT}"
echo "Repository setup complete"
}
}
}
}
stage('Initialize Bisection') {
steps {
script {
bisectionManager.initializeBisection(
params.GOOD_COMMIT,
params.BAD_COMMIT,
params.TEST_JOB_NAME,
params.REPOSITORY,
params.SESSION_ID ?: null
)
}
}
}
stage('Execute Bisection') {
steps {
script {
def stepNumber = 1
def maxSteps = 50
while (stepNumber <= maxSteps) {
// Log step and get info
def stepInfo = bisectionManager.logStepStart(stepNumber, params.REPOSITORY)
if (stepInfo.type == 'complete') {
echo "Bisection complete! Failing commit: ${stepInfo.failing_commit}"
break
}
// Show restart instructions
bisectionManager.showRestartInstructions(stepNumber, params.TEST_JOB_NAME, params.REPOSITORY)
if (params.DRY_RUN) {
def simulatedResult = (stepNumber % 2 == 0) ? "SUCCESS" : "FAILURE"
echo "Simulated result: ${simulatedResult}"
bisectionManager.recordTestResult(stepInfo.commit, simulatedResult, params.REPOSITORY)
} else {
// Execute real job
def startTime = System.currentTimeMillis()
def jobResult = build(
job: "llvm.org/bisect/${params.TEST_JOB_NAME}",
parameters: [
string(name: 'GIT_SHA', value: stepInfo.commit),
string(name: 'BISECT_GOOD', value: stepInfo.bisection_range.current_good),
string(name: 'BISECT_BAD', value: stepInfo.bisection_range.current_bad),
booleanParam(name: 'IS_BISECT_JOB', value: true),
booleanParam(name: 'SKIP_TESTS', value: !params.RUN_TESTS),
booleanParam(name: 'SKIP_TRIGGER', value: true)
],
propagate: false,
wait: true
)
def duration = ((System.currentTimeMillis() - startTime) / 1000.0) as double
// Log the job execution
bisectionManager.logJobExecution(
params.TEST_JOB_NAME,
jobResult.result,
duration,
jobResult.absoluteUrl,
jobResult.number.toString(),
params.REPOSITORY
)
// Record the test result
bisectionManager.recordTestResult(stepInfo.commit, jobResult.result, params.REPOSITORY)
}
stepNumber++
sleep(2)
}
if (stepNumber > maxSteps) {
error("Bisection exceeded maximum steps")
}
}
}
}
stage('Final Report') {
steps {
script {
bisectionManager.generateFinalReport(params.REPOSITORY)
}
}
}
}
post {
always {
script {
bisectionManager.displaySummary(params.REPOSITORY)
archiveArtifacts artifacts: "bisection_state.json,bisection.log,restart_instructions.log,bisection_final_report.txt",
allowEmptyArchive: true
}
}
cleanup {
// Clean up but preserve artifacts
sh 'rm -f bisection_manager.py'
}
}
}