Содержание

Pipelines

Общее

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}"
                }
            }
        }
    }
}
:!: Переопределение переменных
  • Блок withEnv([«env=value]) { }может переопределить любую переменную среды.
  • Переменные, заданные с помощью environment {}блока, не могут быть переопределены с помощью императивного env.VAR = «value»присваивания.
  • Императивное env.VAR = «value»присваивание может переопределить только переменные среды, созданные с помощью императивного присваивания.
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

Модуль 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
            )
        ])
    ])
}
:!: multiline
// Так не работает, переменные не раскрываются
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} """
}

Дата/Время

:!: more
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);

Сохранение артефактов

:!: Stash

Сохраняет указанные файлы для дальнейшего использования в пайплайне, вне зависимости от агентов
Сохраняет в виде TAR архива, поэтому большие файлы не рекомендуется передавать т.к будет проседать ЦП
По умолчанию чистится после каждой сборки, но есть плагины позволяющие сохранить между запусками, «preserveStashes()«
Можно добавить исключения на добавляемые файлы. Сохраняет указанные файлы в текущем рабочем каталоге, распаковывает сохраняя относительные пути

stage("first") {
  agent { slave1 }
  steps {
    (...)
    stash includes: 'terraform.tfstate, terraform.backup, .terraform/**', name: DYNAMIC_SLAVE
  }
}
 
stage("second") {
  agent { master }
  steps {
    cleanWs()
    unstash name: DYNAMIC_SLAVE
  }
}

Указывать нужно с маской, например includes: «my_dir/*», при этом сохраняет всю папку

        stage("first stage") {
            steps {
                script {
                    sh """
                        mkdir my_dir
                        touch my_dir/first_file_${BUILD_NUMBER}
                        touch my_dir/second_file_${BUILD_NUMBER}
                        touch my_dir/three_file_${BUILD_NUMBER}
                        ls -l 
                    """
                    stash includes: "my_dir/*", name: "dirr"
                }
            }
        }
 
        stage("second stage") {
            steps {
                script {
                    cleanWs()
                    sh "ls -l"
                }
            }
        }
 
        stage("three stage") {
            steps {
                script {
                    unstash name: "dirr"
                    sh "ls -l my_dir"
                }
            }
        }
:!: archiveArtifacts

Архивирует артефакты сборки, затем они доступны на веб-странице джобы
По умолчанию Maven автоматически архивирует произведенные артефакты. Указанные здесь артефакты будут архивированы поверх
Файлы указываются так же маской

archiveArtifacts artifacts: 'target/*.jar'
archiveArtifacts artifacts: 'target/*.jar, target/*.war'
archiveArtifacts artifacts: '**/*.jar'
 
# Из примера выше
archiveArtifacts artifacts: 'my_dir/*'

Примеры

:!: Работа с grafana API
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'"
                }
            }
        }
 
    }
}
:!: When
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'"
                }
            }
        }
    }
}
:!: Использование config файла
// Создание файла
configFileProvider([configFile(fileId: 'kubeconf', targetLocation: 'kubeconf.сщта')]) {
  script {
  }
}
 
// Данные в переменной
configFileProvider([configFile(fileId: 'kubeconf', variable: 'kubeconf')]) {
  script {
  }
}
:!: Запись в файл. Декларативный метод
writeFile file: "${MY_FILENAME}.txt", text: """
  text: ${var1}
  test: ${var2}
""".stripIndent()

Use Gradle

:!: Общее

:!: Скрипты справа все таки совпадают с тасками что есть в файле «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" (хотя не точно уже)
    }
}

Прерывание

if (!params.MY_VAR.contains(»@»)) {

  currentBuild.result = 'ABORTED'
  error("Параметр 'MY_VAR' указан неверно")

}