Инструменты пользователя

Инструменты сайта


jenkins:pipelines

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
jenkins:pipelines [2024/02/01 13:42]
admin
jenkins:pipelines [2025/01/19 15:53] (текущий)
admin
Строка 1: Строка 1:
 ====== Pipelines ====== ====== Pipelines ======
- 
- 
 ===== Общее ===== ===== Общее =====
- 
 <code groovy> <code groovy>
 if (params.getOrDefault('BOOLEAN_PARAM_NAME', true)) if (params.getOrDefault('BOOLEAN_PARAM_NAME', true))
Строка 16: Строка 13:
  
 ===== Переменные ===== ===== Переменные =====
 +<details>
 +<summary>:!: Примеры</summary>
 +<code groovy>
 +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"
 +                  '''
 +                }
 +            }
 +        }
 +    }
 +}
 +</code>
 +</details>
 +
 +
 ==== Переменные среды ==== ==== Переменные среды ====
 [[https://e.printstacktrace.blog/jenkins-pipeline-environment-variables-the-definitive-guide/|Дока]] [[https://e.printstacktrace.blog/jenkins-pipeline-environment-variables-the-definitive-guide/|Дока]]
Строка 139: Строка 164:
 ==== Переменные ==== ==== Переменные ====
 Обращаться к переменным следует всегда с префиксами если они есть, например для переменных окружения это "env", для входных параметров это "params". т.к. переменная легко может подменится локальной с таким же именем, не имеющей отношения к переменной окружения или параметру\\ Обращаться к переменным следует всегда с префиксами если они есть, например для переменных окружения это "env", для входных параметров это "params". т.к. переменная легко может подменится локальной с таким же именем, не имеющей отношения к переменной окружения или параметру\\
 +
  
 <details> <details>
-<summary>:!: Работа с переменными в pipeline</summary>+<summary>:!: Работа с переменными, модуль sh</summary> 
 +Модуль **sh** по всей видимости выполняется напрямую в оболочке, поэтому ему доступны только переменные окружения среды\\ 
 +Задать переменные окружения из скрипта можно в блоке **Environment**\\ 
  
 <code groovy> <code groovy>
-  // Входящий параметр+  // Входящий параметр (видимо по умолчанию доступны в переменных окружения)
 stage('Clone source') { stage('Clone source') {
  steps {  steps {
Строка 158: Строка 187:
 } }
  
-// Объявление переменной+// Объявление в скрипте
 stage('Increment & push MGA_TAG') { stage('Increment & push MGA_TAG') {
     environment{     environment{
Строка 177: Строка 206:
     }     }
 } }
 +
 +//
 +// Или вот пример 
 +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' <-- эта не раскрывается
 +        '''
 +    }
 +}
 +
 +
 +
  
 // Объявление входных параметров // Объявление входных параметров
Строка 215: Строка 262:
  
  
-<details> 
-<summary>:!: Еще переменные, multiline</summary> 
  
 +<details>
 +<summary>:!: multiline</summary>
 <code groovy> <code groovy>
 // Так не работает, переменные не раскрываются // Так не работает, переменные не раскрываются
Строка 238: Строка 285:
  
 ===== Дата/Время ===== ===== Дата/Время =====
 +  * **java.time.LocalDateTime** - Дата и время без часового пояса в календарной системе ISO-8601, например 2007-12-03T10:15:30\\ неизменяемый объект даты и времени, с точностью до наносекунды, не хранит и не представляет часовой пояс\\
 +  * **java.time.Instant** - тут что то более жесткое
 +
 +
 +  * **ZoneId** - (java.time.ZoneId) больше связано с правилами преобразования между часовыми поясами\\
 +  * **ZoneOffset** - (java.time.ZoneOffset) тут уже больше про смещение относительно UTC\\
  
 <details> <details>
Строка 250: Строка 303:
 def start = LocalDateTime.now().plusMinutes(360) def start = LocalDateTime.now().plusMinutes(360)
  
 +// Тоже текущая дата, формат такой же, но дженкинс попросил аппрув (хотя не помню с первым возможно тоже был) 
 +import java.time.Instant 
 +def current_instant = Instant.now()
 </code> </code>
 </details> </details>
  
 +
 +<details>
 +<summary>:!: Часовые пояса</summary>
 +[[https://javarush.com/quests/lectures/questsyntaxpro.level16.lecture06|Неплохая статья]]\\
 +<code groovy>
 +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);
 +</code>
 +</details>
  
  
  
 +===== Сохранение артефактов =====
 <details> <details>
-<summary>:!: </summary>+<summary>:!: Stash</summary> 
 +Сохраняет указанные файлы для дальнейшего использования в пайплайне, вне зависимости от агентов\\ 
 +Сохраняет в виде TAR архива, поэтому большие файлы не рекомендуется передавать т.к будет проседать ЦП\\ 
 +По умолчанию чистится после каждой сборки, но есть плагины позволяющие сохранить между запусками, "preserveStashes()"\\ 
 +Можно добавить исключения на добавляемые файлы. Сохраняет указанные файлы в текущем рабочем каталоге, распаковывает сохраняя относительные пути\\ 
 <code groovy> <code groovy>
 +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
 +  }
 +}
 +</code>
 +
 +Указывать нужно с маской, например **includes: "my_dir/*"**, при этом сохраняет всю папку
 +<code groovy>
 +        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"
 +                }
 +            }
 +        }
 </code> </code>
 </details> </details>
  
  
 +<details>
 +<summary>:!: archiveArtifacts</summary>
 +Архивирует артефакты сборки, затем они доступны на веб-странице джобы\\
 +По умолчанию Maven автоматически архивирует произведенные артефакты. Указанные здесь артефакты будут архивированы поверх\\
 +Файлы указываются так же маской\\
  
 +<code groovy>
 +archiveArtifacts artifacts: 'target/*.jar'
 +archiveArtifacts artifacts: 'target/*.jar, target/*.war'
 +archiveArtifacts artifacts: '**/*.jar'
  
 +# Из примера выше
 +archiveArtifacts artifacts: 'my_dir/*'
 +</code>
 +</details>
  
  
  
  
 +===== Примеры =====
 +<details>
 +<summary>:!: Работа с grafana API</summary>
 +<code groovy>
 +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}"
 +                                }
 +                              ]
 +                            }"""
 +                }
 +            }
 +        }
 +        
 +    }
 +}
  
-====== Gradle ======+def SetParameters() { 
 +    properties([ 
 +        parameters([ 
 +            string( 
 +                name: 'ALERT_NAME', 
 +                description: 'Название alert-правила в grafana', 
 +                trim: true 
 +            ), 
 +            string( 
 +                name: 'DURATION_MIN', 
 +                defaultValue: '60', 
 +                description: 'Продолжительность режима тишины в минутах', 
 +                trim: true 
 +            ) 
 +        ]) 
 +    ]) 
 +
 +</code> 
 +</details>
  
-<details> 
-<summary>:!: Общее </summary> 
-:!: Скрипты справа все таки совпадают с тасками что есть в файле "build.gradle.kts" внутри проекта\\ 
-вот только как он обновляется ? таску вроде прописал, а справа не появляется этого 
  
  
 +
 +
 +<details>
 +<summary>:!: Минимальный пример, скачивание репозитория </summary>
 <code groovy> <code groovy>
-  // Проверка переданной переменной, через аргументы вызова, "-Pversion" +pipeline {
-if(!project.hasProperty("version")) throw Exception("no value stop it")+
  
-  // Обращаться к свойству +    agent { 
-project.properties["buildVersion"]+        label 'main-node' 
 +    }
  
-  // Вообще таска для ShadowJar +    options 
-tasks              +        quietPeriod 5 
-    "shadowJar"(com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar::class{ +        ansiColor('xterm'
-        mergeServiceFiles() +        timestamps() 
-        isZip64 = true +        buildDiscarder logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', numToKeepStr: '10') 
-        val serverAppName = "server_app-$serverAppVersion.jar" +    } 
-        archiveFileName.set(serverAppName) + 
-        doFirst +    stages { 
-            //assert(buildVersion != "non-value""Can not get version by git.+        stage('Prepare') { 
-            if(!project.hasProperty("version")) throw Exception("no value stop it")+            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
 +                    '''
 +                    )
 +                }
 +            }
 +        }
 </code> </code>
 </details> </details>
 +
  
  
 <details> <details>
-<summary>:!: Работа из пайплайна</summary>+<summary>:!: Проверка и откат</summary>
 <code bash> <code bash>
-  # Если скритп "gradlew" в папке с проектом +    - name: "Проверка и откат" 
-stage('Build jar') { +      block: 
- steps { +        - name: "Перезапускаем сервис" 
- sh "bash ./gradlew shadowJar"+          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: "!!! Откат изменений после сбоя. Прерываем дальнейшее выполнение !!!" 
 +</code> 
 +</details> 
 + 
 + 
 + 
 +<details> 
 +<summary>:!: Выбор инстансов</summary> 
 +<code java> 
 +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() { 
-stage('Build jar') { +    if ("all".equals(params.APP_INSTANCE)) { 
- steps +        return "-e version=${params.VERSION}" 
- sh "bash ./gradlew myProject:modules:shadowJar(хотя не точно уже)+    } 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
 +            )
 +        ])
 +    ])
 } }
 </code> </code>
 </details> </details>
 +
  
  
 <details> <details>
-<summary>:!: Типичный скрипт для сборки</summary> +<summary>:!: Минимальный образец пайплайна</summary> 
-Тут модификация shadowJar для того чтобы в имя файла не добавлялся постфикс "-all"\\ +<code groovy> 
-Так же можно явно задавать имя артефакту\\ +pipeline { 
-Так же таска для публикации в nexus\\+    environment { 
 +        MY_VAR = "123
 +    }
  
-<code bash> +    agent { 
-plugins +        node 
-    application +            label 'my-super-agent' 
-    java +        } 
-    id("com.github.johnrengelman.shadow"+    }
-    id("com.coditory.manifest"+
-    id("maven-publish"+
-}+
  
-dependencies +    parameters 
- (зависимости могут варьироваться) +        string description: 'my param', name: 'MY_PARAM', defaultValue: '' 
-    implementation(Deps.toml) +    }
-    implementation(Deps.opencsv) +
-}+
  
-application +    stages 
-    mainClass.set("com.gmware.applications.(тут какой то класс)")+        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'" 
 +                } 
 +            } 
 +        } 
 + 
 +    }
 } }
  
-group = "com.gmware.applications" +</code> 
-version = "0.0.0.1-SNAPSHOT" +</details>
  
-// При желании, так можно получить хэш последнего коммита, для записи в манифест + 
-fun getGitCommit()String { + 
-    val result = StringBuilder() +<details> 
-    val process = ProcessBuilder("git", "rev-parse", "HEAD").start(+<summary>:!When</summary> 
-    process.inputStream.reader(Charsets.UTF_8).use +<code groovy> 
-        result.append(it.readText())+stage('first-stage'{ 
 +    when 
 +        branch 'master' 
 + branch 'feature/*' 
 +
     }     }
-    process.waitFor() +----- 
-    return result.toString().trim() +    when { 
-}+        expression { 
 +            return env.BRANCH_NAME != 'master'; 
 +     inputOptimizer == "OpenCV DNN"  
 +        } 
 +    } 
 +----- 
 +    when {  
 +        environment name: 'NAME', value: 'this'  
 +    } 
 +-----
  
-tasks +    steps { 
-    "shadowJar"(com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar::class) +        echo 'run this stage - ony if the branch = master branch' 
-        archiveClassifier.set("") +    // Так же внутри степа 
-        manifest +        script 
-            attributes(mapOf( +            if (env.BRANCH_NAME == "myBranch") { 
-                "Main-Class" to application.mainClass, +                echo 'triggered by myBranch' 
-                "Version" to version, +            } else { 
-         "Module-version" to getGitCommit() +                echo 'triggered by something else' 
-            ))+            }
         }         }
 +
     }     }
 } }
 +</code>
  
-publishing { +Вариативность: "not", "allOf" и "anyOf"\\ 
-    repositories +<code groovy> 
-        maven +when allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } } 
-            url = uri("${properties["nexusUrl"]}/myApp-snapshot") +--- 
-            credentials +when anyOf { branch 'master'; branch 'staging' } } 
-                username = "${properties["nexusUser"]}" +--- 
-                password = "${properties["nexusPassword"]}"+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' 
 +                } 
 +            } 
 +--- 
 + 
 + 
 +</code> 
 + 
 + 
 +Еще можно задать параметры сравнения (comparator): "EQUALS", "REGEXP"\\ 
 +<code groovy> 
 +// Сравнивать по регулярке 
 +when { branch pattern: "release-\\d+", comparator: "REGEXP"
 + 
 +// Простое сравнение 
 +when { branch: "release", comparator: "EQUALS"
 +</code> 
 + 
 + 
 + 
 +:!: Строки могут плохо преобразовываться в логические значения, например "0" или "False" все равно оценится как True тк не пустая строка\\ 
 + 
 + 
 +Вариативность выполнения в зависимости от переменных и параметров\\ 
 +В т.ч подходит для инициализации джобы запуском без параметров\\ 
 +<code groovy> 
 +pipeline { 
 +    environment { 
 +        MY_VAR = "123"
     }     }
-    publications + 
-        register("mavenJava"MavenPublication::class) { +    agent any 
-            artifact(tasks["shadowJar"])+ 
 +    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'" 
 +                } 
 +            }
         }         }
     }     }
 } }
 </code> </code>
 +</details>
  
  
-Избавится от постфикса "-all" в имени джарки\\ + 
-параметр "jar.archiveClassifier.set("")"\\+<details> 
 +<summary>:!: Использование config файла</summary> 
 +<code groovy> 
 +// Создание файла 
 +configFileProvider([configFile(fileId: 'kubeconf', targetLocation: 'kubeconf.сщта')]) { 
 +  script { 
 +  } 
 +
 + 
 +// Данные в переменной 
 +configFileProvider([configFile(fileId: 'kubeconf', variable: 'kubeconf')]) { 
 +  script { 
 +  } 
 +
 + 
 +</code> 
 +</details> 
 + 
 + 
 + 
 +<details> 
 +<summary>:!: Запись в файл. Декларативный метод</summary> 
 +<code groovy> 
 +writeFile file: "${MY_FILENAME}.txt", text: """ 
 +  text: ${var1} 
 +  test: ${var2} 
 +""".stripIndent() 
 +</code> 
 +</details> 
 + 
 + 
 + 
 +==== Запись результатов/Артефакты джобы ==== 
 + 
 +<details> 
 +<summary>:!: Примеры</summary> 
 + 
 +Запись резов текстом, сразу на странице джобы\\ 
 +Можно применять html\\
 <code bash> <code bash>
-# Вариант с таской shadowJar +currentBuild.description = "Сборка BIN-артефакта - ${my-variable.getAbsoluteUrl()}" 
-tasks {+</code> 
 + 
 +Артефакты файлами\\ 
 +<code bash> 
 +archiveArtifacts artifacts: 'result.html' 
 +</code> 
 + 
 + 
 +Публикация полноценного отчета, доступен слева в меню\\ 
 +<code bash> 
 +publishHTML (target : [allowMissing: false, alwaysLinkToLastBuild: true, 
 +keepAll: true, reportDir: '', reportFiles: 'result.html', 
 +reportName: 'My Reports', reportTitles: 'The Report']) 
 +</code> 
 +</details> 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 +====== Use Gradle ====== 
 +<details> 
 +<summary>:!: Общее </summary> 
 +:!: Скрипты справа все таки совпадают с тасками что есть в файле "build.gradle.kts" внутри проекта\\ 
 +вот только как он обновляется ? таску вроде прописал, а справа не появляется этого 
 + 
 + 
 +<code groovy> 
 +  // Проверка переданной переменной, через аргументы вызова, "-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) {     "shadowJar"(com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar::class) {
-        archiveClassifier.set(""+        mergeServiceFiles(
-        manifest +        isZip64 = true 
-            attributes(mapOf( +        val serverAppName = "server_app-$serverAppVersion.jar" 
-                "Main-Classto application.mainClass, +        archiveFileName.set(serverAppName
-                "Version" to version, +        doFirst 
-                "Module-version" to getGitCommit() +            //assert(buildVersion != "non-value") { "Can not get version by git." } 
-            ))+            if(!project.hasProperty("version")) throw Exception("no value stop it")
         }         }
     }     }
 } }
 +</code>
 +</details>
  
  
-# Таска с Jar + 
-fun configureJar(jar: Jar) { +<details> 
-    jar.setManifestClassPathToRuntimeDependencies() +<summary>:!: Работа из пайплайна</summary> 
-    jar.doFirst { +<code bash> 
-        jar.manifest { +  # Если скритп "gradlew" в папке с проектом 
-            attributes["Main-Class"] = application.mainClass +stage('Build jar') { 
-            attributes["Module-Name"] = jar.archiveBaseName.get() + steps { 
-            attributes["Module-Commit-Date"] = getCommitDate() + sh "bash ./gradlew shadowJar" 
-            attributes["Created-By"] = System.getProperty("java.version") +    } 
-        }+} 
 + 
 +  # Если нет, тогда  
 +stage('Build jar'{ 
 + steps { 
 + sh "bash ./gradlew myProject:modules:shadowJar(хотя не точно уже)
     }     }
-    jar.archiveFileName.set("my-name.jar") 
-    jar.archiveClassifier.set("") 
 } }
 </code> </code>
Строка 433: Строка 1100:
  
  
-==== Запуск из консоли ==== 
-Сборка и загрузка в репозиторий\\ 
-<code bash> 
-./gradlew -PnexusUrl=https://url/repository -PnexusUser=<user> -PnexusPassword=<passwd> :module-name:publish 
-</code> 
  
  
 +Прерывание
  
  
-==== ShadowJar ==== 
-Есть несколько вариантов, один из это подключить плагин, в файле "build.gradle.kts" добавляем\\ 
-**plugins {    id("com.github.johnrengelman.shadow") }**\\ 
  
-[[https://romanmarkunas.com/build/2018/11/13/0007-build-gradle-fat-jars/|Тут есть описание]]\\+if (!params.MY_VAR.contains("@")) { 
 +    currentBuild.result = 'ABORTED' 
 +    error("Параметр 'MY_VAR' указан неверно"
 +
 + 
  
  
  
jenkins/pipelines.1706794974.txt.gz · Последнее изменение: 2024/02/01 13:42 — admin