Skip to content

Instantly share code, notes, and snippets.

@ealebed
Last active December 20, 2023 03:45
Show Gist options
  • Save ealebed/90ef01a93a0b9d7cb55399bfffd48415 to your computer and use it in GitHub Desktop.
Save ealebed/90ef01a93a0b9d7cb55399bfffd48415 to your computer and use it in GitHub Desktop.
Groovy script for creating Jenkins job from .yaml file
@Grab(group='org.yaml', module='snakeyaml', version='1.18')
import jenkins.model.*
import hudson.model.*
import hudson.triggers.*
import hudson.tasks.LogRotator
import hudson.plugins.git.*
import hudson.plugins.git.extensions.*
import hudson.plugins.git.extensions.impl.*
import org.jenkinsci.plugins.workflow.job.WorkflowJob
import org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition
import org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty
import com.coravy.hudson.plugins.github.*
import com.cloudbees.jenkins.GitHubPushTrigger
import net.uaznia.lukanus.hudson.plugins.gitparameter.*
import net.uaznia.lukanus.hudson.plugins.gitparameter.GitParameterDefinition.*
import org.yaml.snakeyaml.Yaml
import org.jenkinsci.plugins.github.pullrequest.events.impl.*
import org.jenkinsci.plugins.github.pullrequest.*
Jenkins jenkins = Jenkins.get()
def pluginParameter = "workflow-aggregator github-pullrequest"
def plugins = pluginParameter.split()
def pm = jenkins.getPluginManager()
def installed = false
plugins.each {
if (!pm.getPlugin(it)) {
println("Plugin ${it} not installed, skip creating jobs!")
} else {
installed = true
}
}
if(installed) {
def listExistingJob = jenkins.items.collect { it.name }
def listExistingViews = jenkins.views.collect { it.name }
def listNewJobs = []
def jobParameters = new Yaml().load(new FileReader('/root/job_list.yaml'))
for (view in jobParameters) {
for (job in view.value) {
listNewJobs += "${job.key}"
}
}
def diff = listExistingJob.sort().minus(listNewJobs.sort())
println("+++ I'll delete jobs: ${diff} ")
diff.each { jobNameToDelete ->
def jd = jenkins.getItem(jobNameToDelete)
jd.delete()
}
for (view in jobParameters) {
if (jobParameters.any { listExistingViews.contains(view.key) }) {
println("--- View ${view.key} already exist, skip")
} else {
println("--- Create new view ${view.key}")
jenkins.addView(new ListView(view.key))
}
for (item in view.value) {
def jobName = item.key
def config = view.value.get(item.key)
def jobDisabled = config['jobDisabled'] ?: false
def enableGithubPolling = config['enableGithubPolling'] ?: false
def enableGPRTrigVerify = config['enableGPRTrigVerify'] ?: false
def timeTriggerSchedule = config['timeTriggerSchedule'] ?: ""
def daysBuildsKeep = config['daysBuildsKeep'] ?: '7'
def numberBuildsKeep = config['numberBuildsKeep'] ?: '15'
def githubRepoName = config['githubRepoName']
def githubRepoUrl = 'https://github.com/loopme/' + githubRepoName + '/'
def githubRepo = 'git@github.com:loopme/' + githubRepoName + '.git'
def githubBranch = config['githubBranch']
def advancedBehaviors = config['advancedBehaviors'] ?: 'CleanBeforeCheckout'
def description = config['description'] ?: ""
def gitParameter = config['gitParameter'] ?: false
def jenkinsfilePath = config['jenkinsfilePath'] ?: "Jenkinsfile"
def branchConfig = []
if (githubBranch) {
branchConfig = githubBranch.split('[,;]').collect { it.trim() }.findAll { it != "" }.collect { new BranchSpec(it) }
}
if (branchConfig.isEmpty()) {
branchConfig = [new BranchSpec("*/master")]
}
List<ParameterDefinition> listOfParameters = new ArrayList<ParameterDefinition>()
if (gitParameter) {
GitParameterDefinition gitReleaseTagParam = new GitParameterDefinition(
'RELEASE_TAG',
'PT_BRANCH_TAG',
'origin/master',
'Tag (version) to build',
'',
'.*',
'*',
SortMode.DESCENDING_SMART,
SelectedValue.DEFAULT,
'',
false)
gitReleaseTagParam.setListSize('0')
listOfParameters.add(gitReleaseTagParam)
}
def m = [
"CleanCheckout": { new CleanCheckout() },
"CleanBeforeCheckout": { new CleanBeforeCheckout() },
"PruneStaleBranch": { new PruneStaleBranch() },
"WipeWorkspace": { new WipeWorkspace() }
]
def extensions = []
if (advancedBehaviors) {
extensions = advancedBehaviors.split("[;,]").collect { it.trim() }.toSet().collect { m["${it}"]?.call() }.findAll { it }
}
def nameRepo = ""
def refspec = ""
if (enableGPRTrigVerify) {
nameRepo = 'origin'
refspec = '+refs/pull/${GITHUB_PR_NUMBER}/head:refs/remotes/origin/pull/${GITHUB_PR_NUMBER}/head'
}
def userConfig = [new UserRemoteConfig(githubRepo, nameRepo, refspec, null)]
def scm = new GitSCM(userConfig, branchConfig, false, [], null, null, extensions)
def flowDefinition = new CpsScmFlowDefinition(scm, jenkinsfilePath)
if (view.value.any { listExistingJob.contains(item.key) }) {
println("--- Job ${item.key} already exist, check params")
Jenkins.instance.views.each { v ->
if ( view.key == v.name ) {
v.items.each { j ->
if ( item.key == j.name ) {
GithubProjectProperty ghpp = j.getProperty(GithubProjectProperty.class)
if (ghpp == null || ghpp.getProjectUrl() == null) {
baseUrl = ""
} else {
baseUrl = ghpp.getProjectUrl().baseUrl()
}
if (githubRepoUrl != baseUrl && !githubRepoUrl.isEmpty()) {
j.addProperty(new GithubProjectProperty(githubRepoUrl))
}
if (description != j.description) {
j.setDescription(description)
}
if (jobDisabled != j.disabled) {
j.setDisabled(jobDisabled)
}
if (numberBuildsKeep != j.buildDiscarder.numToKeep.toString() || daysBuildsKeep != j.buildDiscarder.daysToKeep.toString()) {
j.addProperty(new BuildDiscarderProperty(new LogRotator(daysBuildsKeep, numberBuildsKeep, null, null)))
}
if (gitParameter) {
ParametersDefinitionProperty jobExistedParameters = j.getProperty(ParametersDefinitionProperty.class)
if (null != jobExistedParameters) {
j.removeProperty(ParametersDefinitionProperty.class)
}
j.addProperty(new ParametersDefinitionProperty(listOfParameters))
}
PipelineTriggersJobProperty triggersJobProperty = j.getProperty(PipelineTriggersJobProperty.class)
if (triggersJobProperty) {
j.removeProperty(triggersJobProperty)
}
if (true == enableGithubPolling) {
j.addTrigger(new GitHubPushTrigger())
}
if (true == enableGPRTrigVerify) {
GitHubPRTrigger trigger = new GitHubPRTrigger("", GitHubPRTriggerMode.HEAVY_HOOKS, [new GitHubPROpenEvent(), new GitHubPRCommitEvent()])
j.addTrigger(trigger)
}
if (!timeTriggerSchedule.isEmpty()) {
TimerTrigger trigger = new TimerTrigger(timeTriggerSchedule)
j.addTrigger(trigger)
}
if (jenkinsfilePath != j.definition.scriptPath ||
advancedBehaviors != j.definition.getScm().getExtensions().toString().replace("[", "").replace("]", "").replace("{}", "") ||
githubBranch != j.definition.getScm().getBranches().name.toString().replace("[", "").replace("]", "") ||
githubRepo != j.definition.getScm().getUserRemoteConfigs().url.toString().replace("[", "").replace("]", "") ||
nameRepo != j.definition.getScm().getUserRemoteConfigs().name.toString().replace("[", "").replace("]", "") ||
refspec != j.definition.getScm().getUserRemoteConfigs().refspec.toString().replace("[", "").replace("]", "") ) {
j.definition = flowDefinition
}
}
}
}
}
} else {
println("--- Create new job ${item.key}")
def job = new WorkflowJob(jenkins, jobName)
if (!githubRepoUrl.isEmpty()) {
job.addProperty(new GithubProjectProperty(githubRepoUrl))
}
if (true == enableGithubPolling) {
job.addTrigger(new GitHubPushTrigger())
}
if (true == enableGPRTrigVerify) {
GitHubPRTrigger trigger = new GitHubPRTrigger("", GitHubPRTriggerMode.HEAVY_HOOKS, [new GitHubPROpenEvent(), new GitHubPRCommitEvent()])
job.addTrigger(trigger)
}
if (!timeTriggerSchedule.isEmpty()) {
TimerTrigger trigger = new TimerTrigger(timeTriggerSchedule)
job.addTrigger(trigger)
}
job.setDescription(description)
job.setConcurrentBuild(false)
job.setDisabled(jobDisabled)
job.addProperty(new BuildDiscarderProperty(new LogRotator(daysBuildsKeep, numberBuildsKeep, null, null)))
if (gitParameter) {
job.addProperty(new ParametersDefinitionProperty(listOfParameters))
}
job.definition = flowDefinition
flowDefinition.setLightweight(true)
jenkins.save()
jenkins.reload()
hudson.model.Hudson.instance.getView(view.key).doAddJobToView(jobName)
}
}
}
}
####################################################################################################################
# Example configuration:
####################################################################################################################
# ads-app: <- View name
# ads-app-3rd-party-stats-prod: <- Job name
# jobDisabled: false <- Disabled or enabled job, can be skipped (default: false)
# enableGithubPolling: false <- Enable GitHub push trigger, can be skipped (default: false)
# enableGPRTrigVerify: false <- Enable GitHub Pull Request trigger, can be skipped (default: false)
# gitParameter: true <- Add Git Parameter 'RELEASE_TAG' for ability to build from tags, can be skipped (default: false)
# timeTriggerSchedule: "H 4 * * *" <- Cron Build Trigger schedule
# daysBuildsKeep: "14" <- Days to keep build, can be skipped (default: 7)
# numberBuildsKeep: "50" <- Number builds to keep, can be skipped (default: 15)
# githubRepoName: "ads-api" <- GitHub repository Name (for creating githubRepoUrl/githubRepo under the hood)
# githubBranch: "*/master" <- Branch(es) to build, can be skipped (default: "*/master")
# advancedBehaviors: "CleanBeforeCheckout" <- Advanced behaviors (CleanCheckout, CleanBeforeCheckout, PruneStaleBranch or WipeWorkspace. Default: CleanBeforeCheckout)
# description: "" <- Job description, can be skipped (default: "")
# jenkinsfilePath: "schemas/postgres/Jenkinsfile" <- Jenkinsfile path, can be skipped (default: Jenkinsfile)
####################################################################################################################
---
ads-app:
ads-api-share:
githubRepoName: 'share-service'
enableGithubPolling: true
gitParameter: true
advancedBehaviors: 'CleanBeforeCheckout, WipeWorkspace'
ads-api-adtag:
githubRepoName: 'ads-api-adtag'
enableGithubPolling: true
gitParameter: true
advancedBehaviors: 'CleanBeforeCheckout, WipeWorkspace'
checkstyle:
ads-lib-logging-core-checkstyle:
enableGPRTrigVerify: true
githubRepoName: 'ads-lib-logging-core'
githubBranch: 'origin/pull/${GITHUB_PR_NUMBER}/head'
jenkinsfilePath: 'Jenkinsfile_checkstyle'
validations:
ads-dependency-check:
enableGPRTrigVerify: true
githubRepoName: 'ads'
githubBranch: 'origin/pull/${GITHUB_PR_NUMBER}/head'
jenkinsfilePath: 'Jenkinsfile_dependency_check'
ads-verifier:
enableGPRTrigVerify: true
githubRepoName: 'ads'
githubBranch: 'origin/pull/${GITHUB_PR_NUMBER}/head'
jenkinsfilePath: 'Jenkinsfile_verifier'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment