Это старая версия документа!
if (params.getOrDefault('BOOLEAN_PARAM_NAME', true)) if (params.CREDENTIAL_ID.toString().isEmpty()) { currentBuild.result = 'ABORTED' error("CREDENTIAL_ID is empty") }
pipeline { agent any stages { stage("Variables") { steps { my_var = sh label: 'my echo', returnStdout: true, script: 'echo edede' } } stage("Variables") { steps { script{ // хотя хз, чет не сработало script: ''' echo "$my_var" ''' } } } } }
Дока
Глобальная переменная, доступная через env. Объявляется в любом месте, либо в блоке environment либо в script
Хранится только в формате строки, в т.ч. и булевы значения
Обратится можно и без «env» но если нет обычной переменной с таким же именем иначе будет путаница
pipeline { agent any stages { stage("Env Variables") { steps { sh "printenv" // можно sh "printenv | sort" } } } }
Переменные среды могут быть установлены декларативно с помощью environment { }блока, императивно с помощью env.VARIABLE_NAMEили с помощью withEnv([«VARIABLE_NAME=value»]) {}блока.
pipeline { agent any environment { FOO = "bar" } stages { stage("Env Variables") { environment { NAME = "Alan" } steps { echo "FOO = ${env.FOO}" echo "NAME = ${env.NAME}" script { env.TEST_VARIABLE = "some test value" } echo "TEST_VARIABLE = ${env.TEST_VARIABLE}" withEnv(["ANOTHER_ENV_VAR=here is some value"]) { echo "ANOTHER_ENV_VAR = ${env.ANOTHER_ENV_VAR}" } } } } }
pipeline { agent any environment { FOO = "bar" NAME = "Joe" } stages { stage("Env Variables") { environment { NAME = "Alan" // overrides pipeline level NAME env variable BUILD_NUMBER = "2" // overrides the default BUILD_NUMBER } steps { echo "FOO = ${env.FOO}" // prints "FOO = bar" echo "NAME = ${env.NAME}" // prints "NAME = Alan" echo "BUILD_NUMBER = ${env.BUILD_NUMBER}" // prints "BUILD_NUMBER = 2" script { env.SOMETHING = "1" // creates env.SOMETHING variable } } } stage("Override Variables") { steps { script { env.FOO = "IT DOES NOT WORK!" // it can't override env.FOO declared at the pipeline (or stage) level env.SOMETHING = "2" // it can override env variable created imperatively } echo "FOO = ${env.FOO}" // prints "FOO = bar" echo "SOMETHING = ${env.SOMETHING}" // prints "SOMETHING = 2" withEnv(["FOO=foobar"]) { // it can override any env variable echo "FOO = ${env.FOO}" // prints "FOO = foobar" } withEnv(["BUILD_NUMBER=1"]) { echo "BUILD_NUMBER = ${env.BUILD_NUMBER}" // prints "BUILD_NUMBER = 1" } } } } }
Обращаться к переменным следует всегда с префиксами если они есть, например для переменных окружения это «env», для входных параметров это «params». т.к. переменная легко может подменится локальной с таким же именем, не имеющей отношения к переменной окружения или параметру
Модуль sh по всей видимости выполняется напрямую в оболочке, поэтому ему доступны только переменные окружения среды
Задать переменные окружения из скрипта можно в блоке Environment
// Входящий параметр (видимо по умолчанию доступны в переменных окружения) stage('Clone source') { steps { echo params.MY_BRANCH sh label: 'repo sync', script: ''' repo init -u ssh://myrepository.ru repo sync if [ $MY_BRANCH != "master" ] ; then repo forall -c git checkout $MY_BRANCH fi ''' } } // Объявление в скрипте stage('Increment & push MGA_TAG') { environment{ myLocalVar = getValueFromFunction() } steps { script{ if (env.myLocalVar == null || env.myLocalVar.equals("")) { currentBuild.result = 'ABORTED' } } sh label: 'Push tag if it is set', script: ''' cd $WORKSPACE/igas repo forall -c git tag -a $myLocalVar -m $myLocalVar repo forall -c git push origin "$myLocalVar" ''' } } // // Или вот пример stage('Build') { environment { VERSION_STRING = new SimpleDateFormat("yyyy_MM_dd_HH_mm").format(new Date()) } steps { sh label: 'my scritp', script: ''' echo variable in other block1 - $VERSION_STRING echo variable in other block2 - "$VERSION_STRING" echo variable in other block3 - '$VERSION_STRING' <-- эта не раскрывается ''' } } // Объявление входных параметров def setParameters() { properties([ parameters([ gitParameter( name: 'MY_BRANCH', description: 'Тег или ветка, откуда делать сборку', branch: '', branchFilter: '.*', defaultValue: 'origin/master', listSize: '10', quickFilterEnabled: false, requiredParameter: true, selectedValue: 'DEFAULT', sortMode: 'ASCENDING_SMART', tagFilter: '[0-9]*', type: 'PT_BRANCH_TAG' ), string( name: 'APP_VERSION', description: '', defaultValue: '', trim: true ), booleanParam( name: 'RUNACTION', description: '', defaultValue: false ) ]) ]) }
// Так не работает, переменные не раскрываются script{ echo ''' second $MY_PARAM ''' echo ''' three ${MY_PARAM} ''' echo ''' four ${params.MY_PARAM} ''' } // Работает в тройных двойных кавычках, раскрылись все переменные script{ echo """ second $MY_PARAM """ echo """ three ${MY_PARAM} """ echo """ four ${params.MY_PARAM} """ }
import java.time.LocalDateTime // Локальная ДТ, в формате "2024-02-01T19:34:11.905900287" def start = LocalDateTime.now() // Прибавить минуты def start = LocalDateTime.now().plusMinutes(360) // Тоже текущая дата, формат такой же, но дженкинс попросил аппрув (хотя не помню с первым возможно тоже был) import java.time.Instant def current_instant = Instant.now()
import java.time.LocalDateTime import java.time.ZoneId // ZoneId, тут есть явное определение временных зон, пример из джавы ZoneId zone = ZoneId.of("Asia/Almaty") ZonedDateTime time = ZonedDateTime.now(zone) // В груви так работает (тут есть перечень зон https://csharpcoderr.com/5267/ ) def zoned_dt = LocalDateTime.now(ZoneId.of("Asia/Almaty")) // Offset, собсна "смещение", тут в основном фиксированный какой то сдвиг времени от полученного из системы // Так работает def current_dt = LocalDateTime.now() def offset_dt = LocalDateTime.now(ZoneOffset.ofHours(+6)) // Вот тоже пример, по сути тоже самое ZoneOffset zoneOffSet = ZoneOffset.of("+02:00"); OffsetTime time = OffsetTime.now(zoneOffSet);
import java.time.LocalDateTime import java.time.ZoneId pipeline { agent { label 'master' } environment { GRAFANA_API_TOKEN = credentials('sdcsdcdscdsc') } stages { stage('make silence') { steps { SetParameters() script{ //def start_time_silence = LocalDateTime.now(ZoneId.of("Asia/Almaty")) //def end_time_silence = start_time_silence.plusMinutes(params.DURATION_MIN.toInteger()) def start_time_silence = LocalDateTime.now() def end_time_silence = start_time_silence.plusMinutes(params.DURATION_MIN.toInteger()) def response = httpRequest acceptType: 'APPLICATION_JSON', contentType: 'APPLICATION_JSON', responseHandle: 'NONE', httpMode: 'POST', ignoreSslErrors: true, url: 'https://url-grafana/api/alertmanager/grafana/api/v2/silences', wrapAsMultipart: false, authentication: 'dcdcdcdcdc', requestBody: """{ "comment": "comment_string", "createdBy": "user_my", "startsAt": "${start_time_silence}", "endsAt": "${end_time_silence}", "matchers": [ { "isEqual": true, "isRegex": false, "name": "alertname", "value": "${ALERT_NAME}" } ] }""" } } } } } def SetParameters() { properties([ parameters([ string( name: 'ALERT_NAME', description: 'Название alert-правила в grafana', trim: true ), string( name: 'DURATION_MIN', defaultValue: '60', description: 'Продолжительность режима тишины в минутах', trim: true ) ]) ]) }
pipeline { agent { label 'main-node' } options { quietPeriod 5 ansiColor('xterm') timestamps() buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', numToKeepStr: '10') } stages { stage('Prepare') { steps { script { cleanWs() sh( label: 'repo sync', script: ''' PATH="${HOME}/.bin:${PATH}" repo init -u ssh://username:port/myproject --depth=1 repo sync repo forall -c git checkout "master" ''' ) } } } } } # # Выбор ветки # stage('Prepare') { steps { script { SetParameters() cleanWs() sh( label: 'repo sync', script: ''' PATH="${HOME}/.bin:${PATH}" repo init -u ssh://username:port/project --depth=1 repo sync if [ ${BRANCH} != "master" ] ; then repo forall -c git checkout ${BRANCH} fi if [ ${GERRIT_REFSPEC} != "master" ] ; then cd igs/smodls/i_adm && git fetch ssh://url-repo:port/myproject ${GERRIT_REFSPEC} && git checkout FETCH_HEAD fi ''' ) } } }
- name: "Проверка и откат" block: - name: "Перезапускаем сервис" import_tasks: 60-restart_service.yml - name: "Делаем паузу и проверяем состояние сервиса" ansible.builtin.shell: cmd: "sleep 25 && systemctl is-active myservice@{{ instance_name }}.service" rescue: - name: "Откатываемся на бекап" ansible.builtin.shell: cmd: 'tar -xzvf ./backups/previous_version.tar.gz -C .' chdir: '{{ instance.root_path }}/{{ instance_name }}' - name: "Перезапускаем сервис, уже после отката" import_tasks: 60-restart_service.yml - name: "Прерываем выполнение в случае отката" ansible.builtin.fail: msg: "!!! Откат изменений после сбоя. Прерываем дальнейшее выполнение !!!"
pipeline { agent { label 'ConfigServerExt' } options { quietPeriod 5 ansiColor('xterm') timestamps() buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', numToKeepStr: '10') } environment { EXTRAS = getExtras() } stages { stage('Prepare') { steps { script { SetParameters() cleanWs() script { currentBuild.displayName = "${params.VERSION}" buildDescription "${params.APP_INSTANCE}" } sh( label: 'repo sync', script: ''' PATH="${HOME}/.bin:${PATH}" repo init -u ssh://jenkins@gerrit.ru/igs-meta --depth=1 repo sync if [ ${BRANCH} != "master" ] ; then repo forall -c git checkout ${BRANCH} fi if [ ${GERRIT_REFSPEC} != "master" ] ; then cd igs/modules/repo && git fetch ssh://gerrit.ru/proj ${GERRIT_REFSPEC} && git checkout FETCH_HEAD fi ''' ) } } } stage('Build') { when { expression { !params.SKIP_BUILD } } environment { NEXUS_CREDS = credentials('11111-1111-1111') } steps { sh label: 'gradle publish', script: ''' cd $WORKSPACE/igas ./gradlew \ "-PnexusUrl=https://nexus.ru/repository" \ "-PnexusUser=${NEXUS_CREDS_USR}" \ "-PnexusPassword=${NEXUS_CREDS_PSW}" \ :my_app:publish ''' } } stage('Deploy') { steps { dir("${WORKSPACE}/proj/pathToPlaybook") { ansiblePlaybook( playbook: "playbooks-deploy/my_role.yml", extras: "${env.EXTRAS}", colorized: true, ) } } } } } def getExtras() { if ("all".equals(params.APP_INSTANCE)) { return "-e version=${params.VERSION}" } else { return "-e version=${params.VERSION} -e instances=${params.APP_INSTANCE}" } } def SetParameters() { properties([ parameters([ booleanParam( name: 'SKIP_BUILD', description: 'Поставьте галочку и выберите версию если нужен только деплой существующей версии', defaultValue: false ), [ $class: 'ChoiceParameter', choiceType: 'PT_SINGLE_SELECT', description: 'Ветка для сборки приложения', name: 'BRANCH', randomName: 'choice-parameter-73664823423423', filterable: false, script: [ $class: 'GroovyScript', fallbackScript: [ classpath: [], sandbox: false, script: ''' return['Could not get branches list from gerrit'] '''.trim() ], script: [ classpath: [], sandbox: false, script: ''' def cmd = ['/bin/bash', '-c', 'git ls-remote --quiet --heads ssh://login@gerrit.ru/proj | grep -oP refs.* | sed "s|refs/heads|origin|g; s|master|master:selected|"'] def result = cmd.execute().text.tokenize() return result '''.trim() ] ] ], [ $class: 'ChoiceParameter', choiceType: 'PT_SINGLE_SELECT', name: 'VERSION', description: 'Укажите, если нужен деплой уже существующей версии', randomName: 'choice-parameter-5631314456178618', script: [ $class: 'GroovyScript', script: [ classpath: [], sandbox: false, script: '''\ import com.cloudbees.plugins.credentials.CredentialsMatchers import com.cloudbees.plugins.credentials.CredentialsProvider import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials import com.cloudbees.plugins.credentials.domains.DomainRequirement import jenkins.model.Jenkins import hudson.security.ACL jenkins = Jenkins.get() def lookupSystemCredentials = { credentialsId -> return CredentialsMatchers.firstOrNull( CredentialsProvider.lookupCredentials( StandardUsernameCredentials.class, jenkins, ACL.SYSTEM, Collections.<DomainRequirement>emptyList() ), CredentialsMatchers.withId(credentialsId) ) } credential = lookupSystemCredentials("111111-1111-111") nexusLogin = credential.getUsername() nexusPasswd = credential.getPassword().getPlainText() def targetUrl="https://$nexusLogin:$nexusPasswd@nexus.url.ru/repository/myapp-snapshots/com/gmware/applications/myapp/maven-metadata.xml" def sout = new StringBuilder(), serr = new StringBuilder() def proc = "curl -X GET $targetUrl".execute() proc.consumeProcessOutput(sout, serr) proc.waitForOrKill(1000) def response=sout.toString() def metadata = new XmlParser().parseText(response) def versions = ['latest:selected'] versions.addAll(metadata.versioning.versions.version.collect({it.text()}).reverse()) return versions '''.stripIndent() ] ] ], [ $class : 'ChoiceParameter', choiceType : 'PT_MULTI_SELECT', filterLength: 1, filterable : false, name : 'FM_INSTANCE', randomName : 'choice-parameter-5631314339613980', script : [ $class: 'GroovyScript', script: [ classpath: [], sandbox : false, script : '''\ def fm_instances = [] def file1 = new File("/pathToFile/file.txt") file1.eachLine { fm_instances.add(it) } def result = ["all:selected"] result.addAll(fm_instances) return result'''.stripIndent() ] ] ], string( defaultValue: 'master', description: 'Укажите патчсет, например, refs/changes/12/34567/1, откуда забирать плейбуки ansible', name: 'GERRIT_REFSPEC', trim: true ) ]) ]) }
pipeline { environment { MY_VAR = "123" } agent { node { label 'my-super-agent' } } parameters { string description: 'my param', name: 'MY_PARAM', defaultValue: '' } stages { stage("First") { when { expression { MY_VAR == "123" } } steps { cleanWs() script { sh "echo 'this is first stage'" } } } stage("Second") { when { expression { MY_VAR == "123" } } steps { script { sh "echo 'this is second stage'" } } } } }
stage('first-stage') { when { branch 'master' branch 'feature/*' } ----- when { expression { return env.BRANCH_NAME != 'master'; inputOptimizer == "OpenCV DNN" } } ----- when { environment name: 'NAME', value: 'this' } ----- steps { echo 'run this stage - ony if the branch = master branch' // Так же внутри степа script { if (env.BRANCH_NAME == "myBranch") { echo 'triggered by myBranch' } else { echo 'triggered by something else' } } } }
Вариативность: «not», «allOf» и «anyOf»
when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } } --- when { anyOf { branch 'master'; branch 'staging' } } --- when { not { branch 'master' } } ---- // Комбинировать тоже можно when { branch 'production' anyOf { environment name: 'DEPLOY_TO', value: 'production' environment name: 'DEPLOY_TO', value: 'staging' } } --- when { expression { BRANCH_NAME ==~ /(production|staging)/ } anyOf { environment name: 'DEPLOY_TO', value: 'production' environment name: 'DEPLOY_TO', value: 'staging' } } ---
Еще можно задать параметры сравнения (comparator): «EQUALS», «REGEXP»
// Сравнивать по регулярке when { branch pattern: "release-\\d+", comparator: "REGEXP"} // Простое сравнение when { branch: "release", comparator: "EQUALS"}
Строки могут плохо преобразовываться в логические значения, например «0» или «False» все равно оценится как True тк не пустая строка
Вариативность выполнения в зависимости от переменных и параметров
В т.ч подходит для инициализации джобы запуском без параметров
pipeline { environment { MY_VAR = "123" } agent any parameters { string description: 'my param', name: 'MY_PARAM', defaultValue: '' string description: 'my param', name: 'MY_PARAM2', defaultValue: '' string description: 'my param', name: 'MY_PARAM3', defaultValue: '' } stages { stage("First") { when { expression { params.MY_VAR } expression { params.MY_VAR2 != "" } expression { !params.MY_VAR2 } expression { params.MY_PARAM == "1" } } steps { cleanWs() script { sh "echo 'this is first stage'" } } } } }
Скрипты справа все таки совпадают с тасками что есть в файле «build.gradle.kts» внутри проекта
вот только как он обновляется ? таску вроде прописал, а справа не появляется этого
// Проверка переданной переменной, через аргументы вызова, "-Pversion" if(!project.hasProperty("version")) throw Exception("no value stop it") // Обращаться к свойству project.properties["buildVersion"] // Вообще таска для ShadowJar tasks { "shadowJar"(com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar::class) { mergeServiceFiles() isZip64 = true val serverAppName = "server_app-$serverAppVersion.jar" archiveFileName.set(serverAppName) doFirst { //assert(buildVersion != "non-value") { "Can not get version by git." } if(!project.hasProperty("version")) throw Exception("no value stop it") } } }
# Если скритп "gradlew" в папке с проектом stage('Build jar') { steps { sh "bash ./gradlew shadowJar" } } # Если нет, тогда stage('Build jar') { steps { sh "bash ./gradlew myProject:modules:shadowJar" (хотя не точно уже) } }