Initial commit
Add infrastructure jobs for sandbox
Related-PROD: RE-336
Change-Id: I2140d47e3fc360ab05f92175b29b31e69b2ec10b
diff --git a/common/pipelines/codenarc.groovy b/common/pipelines/codenarc.groovy
new file mode 100644
index 0000000..c4ae040
--- /dev/null
+++ b/common/pipelines/codenarc.groovy
@@ -0,0 +1,94 @@
+#!groovy
+
+def main() {
+ String gitUrl = "${env.GERRIT_SCHEME}://${env.GERRIT_HOST}:${env.GERRIT_PORT}/${env.GERRIT_PROJECT}"
+ String gitRef = env.GERRIT_REFSPEC
+
+ stage('SCM checkout') {
+ echo "Checking out git repository from ${gitUrl} @ ${gitRef}"
+
+ checkout \
+ $class: 'GitSCM',
+ branches: [[
+ name: 'FETCH_HEAD'
+ ]],
+ userRemoteConfigs: [[
+ url: gitUrl,
+ refspec: gitRef,
+ credentialsId: env.GIT_CREDENTIALS_ID
+ ]],
+ extensions: [[
+ $class: 'WipeWorkspace'
+ ]]
+ }
+
+ stage('Codenarc') {
+ String corenarcRulesFile = 'codenarcRules.groovy'
+ if (!fileExists(corenarcRulesFile)) {
+ writeFile \
+ file: corenarcRulesFile,
+ text: env.DEFAULT_RULES
+ }
+ sh '''#!/bin/bash -ex
+ codenarc \
+ -maxPriority1Violations=0 \
+ -maxPriority2Violations=0 \
+ -maxPriority3Violations=0 \
+ -excludes='**/codenarcRules.groovy' \
+ -rulesetfiles=file:codenarcRules.groovy \
+ -report=console \
+ -report=html:report.html \
+ | tee report.log
+ if [ "${PIPESTATUS[0]}" != '0' ]; then
+ exit 1
+ fi
+ if grep -q 'Compilation failed' report.log ; then
+ exit 1
+ fi
+ if grep -q 'Error processing' report.log ; then
+ exit 1
+ fi
+ '''
+ }
+
+ stage('Report') {
+ archiveArtifacts \
+ artifacts: 'report.html',
+ allowEmptyArchive: true
+ }
+}
+
+String podTpl = """
+ apiVersion: "v1"
+ kind: "Pod"
+ spec:
+ securityContext:
+ runAsUser: 1000
+ containers:
+ - name: "codenarc"
+ image: "${env.DOCKER_IMAGE}"
+ command:
+ - "cat"
+ securityContext:
+ privileged: false
+ tty: true
+"""
+if (env.K8S_CLUSTER == 'unset') {
+ node(env.NODE_LABEL) {
+ docker.image(env.DOCKER_IMAGE).inside('--entrypoint=""') {
+ main()
+ }
+ }
+} else {
+ podTemplate(
+ cloud: env.K8S_CLUSTER,
+ yaml: podTpl,
+ showRawYaml: false
+ ) {
+ node(POD_LABEL) {
+ container('codenarc') {
+ main()
+ }
+ }
+ }
+}
diff --git a/common/pipelines/shellcheck.groovy b/common/pipelines/shellcheck.groovy
new file mode 100644
index 0000000..66a7d37
--- /dev/null
+++ b/common/pipelines/shellcheck.groovy
@@ -0,0 +1,65 @@
+#!groovy
+
+def main() {
+ String gitUrl = "${env.GERRIT_SCHEME}://${env.GERRIT_HOST}:${env.GERRIT_PORT}/${env.GERRIT_PROJECT}"
+ String gitRef = env.GERRIT_REFSPEC
+
+ stage('SCM checkout') {
+ checkout \
+ $class: 'GitSCM',
+ branches: [[
+ name: 'FETCH_HEAD'
+ ]],
+ userRemoteConfigs: [[
+ url: gitUrl,
+ refspec: gitRef,
+ credentialsId: env.GIT_CREDENTIALS_ID
+ ]],
+ extensions: [[
+ $class: 'WipeWorkspace'
+ ]]
+ }
+
+ stage('Shellcheck') {
+ sh '''#!/bin/bash -ex
+ git show --name-only --diff-filter=AM \
+ | grep -E '.sh$' \
+ | xargs --no-run-if-empty shellcheck -e SC1090,SC2013,SC2154,SC2029
+ '''
+ }
+}
+
+String podTpl = """
+ apiVersion: "v1"
+ kind: "Pod"
+ spec:
+ securityContext:
+ runAsUser: 1000
+ containers:
+ - name: "main"
+ image: "${env.DOCKER_IMAGE}"
+ command:
+ - "cat"
+ securityContext:
+ privileged: false
+ tty: true
+"""
+if (env.K8S_CLUSTER == 'unset') {
+ node(env.NODE_LABEL) {
+ docker.image(env.DOCKER_IMAGE).inside('--entrypoint=""') {
+ main()
+ }
+ }
+} else {
+ podTemplate(
+ cloud: env.K8S_CLUSTER,
+ yaml: podTpl,
+ showRawYaml: false
+ ) {
+ node(POD_LABEL) {
+ container('main') {
+ main()
+ }
+ }
+ }
+}
diff --git a/common/pipelines/test-jenkins-jobs.groovy b/common/pipelines/test-jenkins-jobs.groovy
new file mode 100644
index 0000000..e04f644
--- /dev/null
+++ b/common/pipelines/test-jenkins-jobs.groovy
@@ -0,0 +1,218 @@
+#!groovy
+//import groovy.transform.Field
+
+String getJobs(getJobsCmd) {
+ String result
+ dir("${env.WORKSPACE}/output/${env.CI_NAME}") {
+ result = sh \
+ script: """\
+ ${getJobsCmd} \
+ | grep -v '\\/\$' \
+ | grep -E '^(deleting|Files)' \
+ | sed -r 's%^(deleting|Files)\\s%%g' \
+ | sed -r 's%^old/%%' \
+ | cut -d' ' -f1
+ """,
+ returnStdout: true
+ }
+ return result
+}
+
+def main() {
+ // Use gerrit parameters if set with fallback to job param
+ String gitUrl = "${env.GERRIT_SCHEME}://${env.GERRIT_HOST}:${env.GERRIT_PORT}/${env.GERRIT_PROJECT}"
+ String gitRef = env.GERRIT_REFSPEC
+
+ String pathSep = '/'
+
+ String getAddedJobsCmd = 'rsync --dry-run -av --delete old/ new/'
+ String getRemovedJobsCmd = 'rsync --dry-run -av --delete new/ old/'
+ String getDiffJobsCmd = 'diff -rq old/ new/'
+
+ // Set current build description
+ if (env.GERRIT_CHANGE_URL) {
+ currentBuild.description = """
+ <p>
+ Triggered by change: <a href="${env.GERRIT_CHANGE_URL}">${env.GERRIT_CHANGE_NUMBER},${env.GERRIT_PATCHSET_NUMBER}</a><br/>
+ Project: <b>${env.GERRIT_PROJECT}</b><br/>
+ Branch: <b>${env.GERRIT_BRANCH}</b><br/>
+ Subject: <b>${env.GERRIT_CHANGE_SUBJECT}</b><br/>
+ </p>
+ """
+ }
+
+ // Get & prepare source code
+ stage('SCM checkout') {
+ echo "Checking out git repository from ${gitUrl} @ ${gitRef}"
+
+ checkout \
+ $class: 'GitSCM',
+ branches: [
+ [name: 'FETCH_HEAD'],
+ ],
+ userRemoteConfigs: [
+ [url: gitUrl, refspec: gitRef, credentialsId: env.GIT_CREDENTIALS_ID],
+ ],
+ extensions: [
+ [$class: 'WipeWorkspace'],
+ ]
+ }
+
+ stage('Check for non-ascii characters') {
+ def asciiStatus = sh \
+ script: 'grep -q --perl-regexp -R "[^[:ascii:]]" --include \\*.sh --include \\*.yaml --include \\*.groovy *',
+ returnStatus: true
+
+ if (asciiStatus == 0) {
+ error 'Found non-ASCII symbols!!!'
+ }
+ }
+
+ stage('JJB verify') {
+ withEnv(['HOME=/tmp/']) {
+ // Generate current jobs from parent commit (will be used for diff)
+ sh 'tox -v -e compare-xml-new'
+ }
+ }
+
+ stage('JJB compare') {
+ withEnv(['HOME=/tmp/']) {
+ // Generate jobs from parent commit (will be used for diff)
+ sh '''
+ git reset --hard HEAD^
+ git checkout FETCH_HEAD -- tox.ini
+ tox -v -e compare-xml-old
+ '''
+ }
+
+ dir("output/${env.CI_NAME}") {
+ Integer diffStatus = sh \
+ script: 'diff -rq old/ new/',
+ returnStatus: true
+
+ if (diffStatus == 0) {
+ currentBuild.result = 'SUCCESS'
+ currentBuild.description += 'No job changes'
+ currentBuild.getRawBuild().getExecutor().interrupt(Result.SUCCESS)
+ sleep(1) // Interrupt is not blocking and does not take effect immediately.
+ }
+ }
+
+ // Analyse output file and prepare array with results
+
+ String diffJobs = getJobs(getDiffJobsCmd)
+ String addedJobs = getJobs(getAddedJobsCmd)
+ String removedJobs = getJobs(getRemovedJobsCmd)
+
+ // Set job description
+
+ String description = ''
+ String _item, _itemPath
+
+ dir("output/${env.CI_NAME}") {
+ if (diffJobs.size() > 0) {
+ description += '<b>CHANGED</b><ul>'
+ diffJobs.split('\n').each { item ->
+ _item = item.replace('/config.xml', '')
+ try {
+ _itemPath = item.tokenize(pathSep)[0..-2].join(pathSep)
+ } catch (e) {
+ _itemPath = ''
+ }
+ description += "<li><a href=\"${env.BUILD_URL}artifact/output/${env.CI_NAME}/diff/${item}/*view*/\">${_item}</a></li>"
+
+ // Generate diff file
+ sh """
+ mkdir -p diff/${_itemPath}
+ diff -U 50 \
+ 'old/${item}' \
+ 'new/${item}' \
+ > 'diff/${item}' || :
+ """
+ }
+ description += '</ul>'
+ }
+
+ if (addedJobs.size() > 0) {
+ description += '<b>ADDED</b><ul>'
+ addedJobs.split('\n').each { item ->
+ _item = item.replace('/config.xml', '')
+ try {
+ _itemPath = item.tokenize(pathSep)[0..-2].join(pathSep)
+ } catch (e) {
+ _itemPath = ''
+ }
+ description += "<li><a href=\"${env.BUILD_URL}artifact/output/${env.CI_NAME}/diff/${item}/*view*/\">${_item}</a></li>"
+ sh """
+ mkdir -p diff/${_itemPath}
+ cp new/${item} diff/${_itemPath}/
+ """
+ }
+ description += '</ul>'
+ }
+
+ if (removedJobs.size() > 0) {
+ description += '<b>DELETED</b><ul>'
+ removedJobs.split('\n').each { item ->
+ _item = item.replace('/config.xml', '')
+ try {
+ _itemPath = item.tokenize(pathSep)[0..-2].join(pathSep)
+ } catch (e) {
+ _itemPath = ''
+ }
+ description += "<li><a href=\"${env.BUILD_URL}artifact/output/${env.CI_NAME}/diff/${item}/*view*/\">${_item}</a></li>"
+ sh """
+ mkdir -p diff/${_itemPath}
+ cp old/${item} diff/${_itemPath}/
+ """
+ }
+ description += '</ul>'
+ }
+ }
+
+ currentBuild.description += description
+ }
+
+ // Save results
+ stage('Record test results') {
+ archiveArtifacts([
+ artifacts: "output/${env.CI_NAME}/diff/**",
+ allowEmptyArchive: true,
+ ])
+ }
+}
+
+String podTpl = """
+ apiVersion: "v1"
+ kind: "Pod"
+ spec:
+ securityContext:
+ runAsUser: 1000
+ containers:
+ - name: "tox"
+ image: "${env.DOCKER_IMAGE}"
+ command:
+ - "cat"
+ securityContext:
+ privileged: false
+ tty: true
+"""
+if (env.K8S_CLUSTER == 'unset') {
+ node(env.SLAVE_LABEL ?: 'docker') {
+ docker.image(env.DOCKER_IMAGE).inside('--entrypoint=""') {
+ main()
+ }
+ }
+} else {
+ podTemplate(
+ cloud: env.K8S_CLUSTER,
+ yaml: podTpl,
+ showRawYaml: false
+ ) {
+ node(POD_LABEL) {
+ container('tox') {
+ main()
+ }
+ }
+ }
+}
diff --git a/common/pipelines/tox.groovy b/common/pipelines/tox.groovy
new file mode 100644
index 0000000..f0d8ccf
--- /dev/null
+++ b/common/pipelines/tox.groovy
@@ -0,0 +1,67 @@
+#!groovy
+
+def main() {
+ String gitUrl = "${env.GERRIT_SCHEME}://${env.GERRIT_HOST}:${env.GERRIT_PORT}/${env.GERRIT_PROJECT}"
+ String gitRef = env.GERRIT_REFSPEC
+
+ stage('SCM checkout') {
+ echo "Checking out git repository from ${gitUrl} @ ${gitRef}"
+
+ checkout \
+ $class: 'GitSCM',
+ branches: [[
+ name: 'FETCH_HEAD'
+ ]],
+ userRemoteConfigs: [[
+ url: gitUrl,
+ refspec: gitRef,
+ credentialsId: env.GIT_CREDENTIALS_ID
+ ]],
+ extensions: [[
+ $class: 'WipeWorkspace'
+ ]]
+ }
+
+ stage('tox') {
+ sh '''#!/bin/bash -ex
+ tox -v
+ '''
+
+ }
+}
+
+String podTpl = """
+ apiVersion: "v1"
+ kind: "Pod"
+ spec:
+ securityContext:
+ runAsUser: 1000
+ containers:
+ - name: "main"
+ image: "${env.DOCKER_IMAGE}"
+ command:
+ - "cat"
+ securityContext:
+ privileged: false
+ tty: true
+"""
+
+if (env.K8S_CLUSTER == 'unset') {
+ node(env.NODE_LABEL) {
+ docker.image(env.DOCKER_IMAGE).inside('--entrypoint=""') {
+ main()
+ }
+ }
+} else {
+ podTemplate(
+ cloud: env.K8S_CLUSTER,
+ yaml: podTpl,
+ showRawYaml: false
+ ) {
+ node(POD_LABEL) {
+ container('main') {
+ main()
+ }
+ }
+ }
+}
diff --git a/common/pipelines/update-jenkins-config.groovy b/common/pipelines/update-jenkins-config.groovy
new file mode 100644
index 0000000..0e76192
--- /dev/null
+++ b/common/pipelines/update-jenkins-config.groovy
@@ -0,0 +1,75 @@
+#!groovy
+import io.jenkins.plugins.casc.ConfigurationAsCode
+
+@NonCPS
+Boolean testConfig(String cascPath) {
+ def casc = ConfigurationAsCode.get()
+ def form
+ Boolean result = true
+ try {
+ form = casc.doCheckNewSource(cascPath)
+ } catch (Exception e) {
+ result = false
+ message = e.toString()
+ } finally {
+ if (form) {
+ println form.kind
+ println form.message.split('<')[0]
+ if (form.kind.toString() != 'OK') {
+ result = false
+ }
+ }
+ }
+ return result
+}
+
+@NonCPS
+void applyConfig(String cascPath) {
+ ConfigurationAsCode.get().configure(cascPath)
+}
+
+node('master') {
+ Boolean doApply = false
+ String cascPath = env.WORKSPACE
+
+ if (env.GERRIT_EVENT_TYPE == 'ref-updated') {
+ doApply = true
+ cascPath = ConfigurationAsCode.get().getStandardConfig()[0] ?: "${env.HOME}/casc"
+ }
+
+ stage('SCM checkout') {
+ String refSpec = env.GERRIT_REFSPEC ?: env.GERRIT_REFNAME
+ String gitUrl = "ssh://${env.GERRIT_HOST}:${env.GERRIT_PORT}/${env.GERRIT_PROJECT}"
+ echo "Checking out git repository from ${env.GERRIT_PROJECT} @ ${refSpec}"
+
+ dir(cascPath) {
+ checkout([
+ $class: 'GitSCM',
+ branches: [[
+ name: 'FETCH_HEAD',
+ ]],
+ userRemoteConfigs: [[
+ url: gitUrl,
+ refspec: refSpec,
+ credentialsId: env.GIT_CREDENTIALS_ID,
+ ]],
+ extensions: [[
+ $class: 'WipeWorkspace',
+ ]],
+ ])
+ }
+ }
+
+ stage('Test configuration') {
+ if (! testConfig(cascPath) ) {
+ currentBuild.result = 'FAILURE'
+ throw new RuntimeException ('Fail')
+ }
+ }
+
+ if (doApply) {
+ stage('Apply configuration') {
+ applyConfig(cascPath)
+ }
+ }
+}
diff --git a/common/pipelines/update-jenkins-jobs.groovy b/common/pipelines/update-jenkins-jobs.groovy
new file mode 100644
index 0000000..4bb3702
--- /dev/null
+++ b/common/pipelines/update-jenkins-jobs.groovy
@@ -0,0 +1,202 @@
+#!groovy
+
+def main(String cacheHome = 'output/cache') {
+ String gitUrl = "${env.GERRIT_SCHEME}://${env.GERRIT_HOST}:${env.GERRIT_PORT}/${env.GERRIT_PROJECT}"
+ String gitRef = env.GERRIT_BRANCH ?: env.GERRIT_REFNAME
+ String artInfraNamespace = 'binary-dev-local/infra'
+ String artCacheFile = "${env.CI_NAME}.jjb.zip"
+ String artCacheUrl = "${env.ARTIFACTORY_URL}/artifactory/${artInfraNamespace}/${artCacheFile}"
+ String artCredential = env.ART_CREDENTIALS_ID
+ String jenkinsCredential = env.JENKINS_CREDENTIALS_ID
+ def response
+
+ def jenkinsJobs
+ def jjbJobs
+ def jobsToRemove
+
+ currentBuild.description = ''
+
+ // Set current build description
+ if (env.GERRIT_CHANGE_URL) {
+ currentBuild.description = """
+ <p>
+ Triggered by change: <a href="${env.GERRIT_CHANGE_URL}">${env.GERRIT_CHANGE_NUMBER},${env.GERRIT_PATCHSET_NUMBER}</a><br/>
+ Project: <b>${env.GERRIT_PROJECT}</b><br/>
+ Branch: <b>${env.GERRIT_BRANCH}</b><br/>
+ Subject: <b>${env.GERRIT_CHANGE_SUBJECT}</b><br/>
+ </p>
+ """
+ }
+
+ stage('SCM checkout') {
+ if (env.MAINTAIN_MODE.toLowerCase() == 'false') {
+ checkout([
+ $class: 'GitSCM',
+ branches: [[
+ name: 'FETCH_HEAD'
+ ]],
+ userRemoteConfigs: [[
+ url: gitUrl,
+ refspec: gitRef,
+ credentialsId: env.GIT_CREDENTIALS_ID
+ ]],
+ extensions: [[
+ $class: 'WipeWorkspace'
+ ]],
+ ])
+ }
+ }
+
+ stage('Get JJB cache') {
+ dir(cacheHome) {
+ response = httpRequest \
+ url: artCacheUrl,
+ authentication: artCredential,
+ httpMode: 'GET',
+ outputFile: artCacheFile,
+ validResponseCodes: '100:399,404'
+ if (response.status != 404) {
+ unzip \
+ zipFile: artCacheFile,
+ dir: '.cache'
+ }
+ }
+ }
+
+ stage('Update JJB jobs') {
+ if (env.MAINTAIN_MODE.toLowerCase() == 'false') {
+ withCredentials([
+ usernamePassword(
+ credentialsId: env.JENKINS_CREDENTIALS_ID,
+ usernameVariable: 'JJB_USER',
+ passwordVariable: 'JJB_PASSWORD')
+ ]) {
+ withEnv([
+ "HOME=${cacheHome}"
+ ]) {
+ sh 'tox -v -e update $JOBS_LIST'
+ }
+ }
+ } else {
+ input \
+ message: 'Sleeping for maintainance'
+ }
+ }
+
+ stage('Get deployed jobs list') {
+ response = httpRequest \
+ url: "${JENKINS_URL}/crumbIssuer/api/json",
+ authentication: jenkinsCredential
+ def crumb = readJSON text: response.getContent()
+
+ response = httpRequest \
+ url: "${JENKINS_URL}/api/json?tree=jobs[name,description]",
+ authentication: jenkinsCredential,
+ customHeaders: [[
+ name: crumb.crumbRequestField,
+ value: crumb.crumb,
+ maskValue: true
+ ]]
+ def jobs = readJSON text: response.getContent()
+
+ jenkinsJobs = jobs.jobs.findAll {
+ // Filter jenkins jobs deployed by JJB
+ it.description.toString().contains('Managed by Jenkins Job Builder')
+ }.collect{ it.name }
+ }
+
+ stage('Get JJB jobs list') {
+ withEnv([
+ "HOME=${cacheHome}"
+ ]) {
+ sh 'tox -v -e jobs'
+ }
+ dir("output/${env.CI_NAME}") {
+ jjbJobs = sh(
+ script: "grep -rl actions | sed 's|/config.xml\$||g'",
+ returnStdout: true
+ ).trim().readLines()
+ }
+
+ if (jjbJobs.size() == 0) {
+ error 'ERROR: Unexpected JJB output. No generated jobs found'
+ }
+ }
+
+ stage('Remove undefined jobs') {
+ jobsToRemove = jenkinsJobs.findAll { ! jjbJobs.contains(it) }
+
+ if (jobsToRemove.size() > 0) {
+ withCredentials([
+ usernamePassword(
+ credentialsId: jenkinsCredential,
+ usernameVariable: 'JJB_USER',
+ passwordVariable: 'JJB_PASSWORD')
+ ]) {
+ withEnv([
+ "HOME=${cacheHome}"
+ ]) {
+ sh "tox -v -e delete ${jobsToRemove.join(' ')}"
+ }
+ }
+
+ String description = '<b>DELETED</b><ul>'
+ jobsToRemove.each { description += "<li>${it}</li>" }
+ description += '</ul>'
+ currentBuild.description += description
+ } else {
+ currentBuild.description += 'No jobs to remove'
+ }
+ }
+
+ stage('Save JJB cache') {
+ dir(cacheHome) {
+ sh "rm -f ${artCacheFile}"
+ zip \
+ zipFile: artCacheFile,
+ dir: '.cache',
+ glob: 'jenkins_jobs/**'
+ response = httpRequest \
+ url: artCacheUrl,
+ authentication: artCredential,
+ httpMode: 'PUT',
+ multipartName: 'file',
+ uploadFile: artCacheFile
+ }
+ }
+}
+
+String podTpl = """
+ apiVersion: "v1"
+ kind: "Pod"
+ spec:
+ securityContext:
+ runAsUser: 1000
+ containers:
+ - name: "tox"
+ image: "${env.DOCKER_IMAGE}"
+ command:
+ - "cat"
+ securityContext:
+ privileged: false
+ tty: true
+"""
+
+if (env.K8S_CLUSTER == 'unset') {
+ node(env.SLAVE_LABEL ?: 'docker') {
+ main(env.WORKSPACE)
+ }
+} else {
+ podTemplate(
+ cloud: env.K8S_CLUSTER,
+ yaml: podTpl,
+ showRawYaml: false
+ ) {
+ node(POD_LABEL) {
+ container('tox') {
+ main()
+ }
+ }
+ }
+}
+
diff --git a/common/pipelines/yamllint.groovy b/common/pipelines/yamllint.groovy
new file mode 100644
index 0000000..94b618a
--- /dev/null
+++ b/common/pipelines/yamllint.groovy
@@ -0,0 +1,70 @@
+#!groovy
+
+def main() {
+ String gitUrl = "${env.GERRIT_SCHEME}://${env.GERRIT_HOST}:${env.GERRIT_PORT}/${env.GERRIT_PROJECT}"
+ String gitRef = env.GERRIT_REFSPEC
+
+ stage('SCM checkout') {
+ echo "Checking out git repository from ${gitUrl} @ ${gitRef}"
+
+ checkout \
+ $class: 'GitSCM',
+ branches: [[
+ name: 'FETCH_HEAD'
+ ]],
+ userRemoteConfigs: [[
+ url: gitUrl,
+ refspec: gitRef,
+ credentialsId: env.GIT_CREDENTIALS_ID
+ ]],
+ extensions: [[
+ $class: 'WipeWorkspace'
+ ]]
+ }
+
+ stage('Yamllint') {
+ sh '''#!/bin/bash -ex
+ YAMLLINT=$(which yamllint)
+ [ -f '.yamllint' ] && YAMLLINT="${YAMLLINT} -c .yamllint"
+ git diff HEAD^ --name-only --diff-filter=AM \
+ | grep -E '\\.ya?ml$' \
+ | xargs --no-run-if-empty ${YAMLLINT}
+ '''
+
+ }
+}
+
+String podTpl = """
+ apiVersion: "v1"
+ kind: "Pod"
+ spec:
+ securityContext:
+ runAsUser: 1000
+ containers:
+ - name: "yamllint"
+ image: "${env.DOCKER_IMAGE}"
+ command:
+ - "cat"
+ securityContext:
+ privileged: false
+ tty: true
+"""
+if (env.K8S_CLUSTER == 'unset') {
+ node(env.NODE_LABEL) {
+ docker.image(env.DOCKER_IMAGE).inside('--entrypoint=""') {
+ main()
+ }
+ }
+} else {
+ podTemplate(
+ cloud: env.K8S_CLUSTER,
+ yaml: podTpl,
+ showRawYaml: false
+ ) {
+ node(POD_LABEL) {
+ container('yamllint') {
+ main()
+ }
+ }
+ }
+}