我希望我的管道在白天不断构建和运行单元测试,并在午夜自动部署最新版本。如果需要,还需要能够手动强制部署。我的问题是当天的第一个版本没有被取消,所以管道将部署两次。
也许如果我创建一个单独的作业,在午夜之前锁定部署资源,并在确保所有构建都在队列中进行锁定之后释放它,以便'inversePrecedence'修剪所有较旧的构建。有更简单的解决方案吗?
stage('build')
node('myNode') {
sh 'build.ksh'
sh 'runtest.ksh'
stash includes: 'Builds/', name: 'Builds'
}
// Wait for midnight to deploy
milestone 1
stage('wait for midnight')
if (!isMidnight()) {
waitForMidnightOrManualTrigger()
}
milestone 2
stage('deploy')
lock(resource: 'deploy-server', inversePrecedence: true) {
node('myNode') {
unstash 'Builds'
sh "deploy.ksh"
}
}
milestone 3
def isMidnight() {
int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
return hour < 1
}
def waitForMidnightOrManualTrigger() {
echo 'Wait until midnight. Or Force deploy. Or abort.'
try {
waitTime = getMillisToMidnight()
timeout(time: waitTime, unit: 'MILLISECONDS') {
input 'Click Proceed to force deploy now. Or wait till midnight for automatic deploy.'
}
} catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e){
if (isAborted(e)) {
echo "The job was aborted by user"
throw e
} else {
echo "Timeout reached, proceed!"
}
}
}
def getMillisToMidnight() {
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_MONTH, 1);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
return c.getTimeInMillis() - System.currentTimeMillis();
}
// There might be an easier way to differ between if the timeout throws the
// exception or if it is the user that has aborted the build...
def isAborted(e) {
def stackTrace = e.getStackTrace()
for (int i=0; i<stackTrace.size(); ++i) {
if (stackTrace[i].toString().contains("InputStepExecution.stop")) {
return false
}
}
return true
}