Показаны различия между двумя версиями страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
jenkins:pipelines [2024/05/15 09:58] admin |
jenkins:pipelines [2025/01/19 15:53] (текущий) admin |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
====== Pipelines ====== | ====== Pipelines ====== | ||
- | |||
- | |||
===== Общее ===== | ===== Общее ===== | ||
- | |||
<code groovy> | <code groovy> | ||
if (params.getOrDefault(' | if (params.getOrDefault(' | ||
Строка 268: | Строка 265: | ||
< | < | ||
< | < | ||
- | |||
<code groovy> | <code groovy> | ||
// Так не работает, | // Так не работает, | ||
Строка 289: | Строка 285: | ||
===== Дата/ | ===== Дата/ | ||
- | |||
* **java.time.LocalDateTime** - Дата и время без часового пояса в календарной системе ISO-8601, например 2007-12-03T10: | * **java.time.LocalDateTime** - Дата и время без часового пояса в календарной системе ISO-8601, например 2007-12-03T10: | ||
* **java.time.Instant** - тут что то более жесткое | * **java.time.Instant** - тут что то более жесткое | ||
Строка 343: | Строка 338: | ||
- | ===== Примеры ===== | + | ===== Сохранение артефактов |
+ | < | ||
+ | < | ||
+ | Сохраняет указанные файлы для дальнейшего использования в пайплайне, | ||
+ | Сохраняет в виде TAR архива, | ||
+ | По умолчанию чистится после каждой сборки, | ||
+ | Можно добавить исключения на добавляемые файлы. Сохраняет указанные файлы в текущем рабочем каталоге, | ||
+ | <code groovy> | ||
+ | stage(" | ||
+ | agent { slave1 } | ||
+ | steps { | ||
+ | (...) | ||
+ | stash includes: ' | ||
+ | } | ||
+ | } | ||
+ | |||
+ | stage(" | ||
+ | agent { master } | ||
+ | steps { | ||
+ | cleanWs() | ||
+ | unstash name: DYNAMIC_SLAVE | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Указывать нужно с маской, | ||
+ | <code groovy> | ||
+ | stage(" | ||
+ | steps { | ||
+ | script { | ||
+ | sh """ | ||
+ | mkdir my_dir | ||
+ | touch my_dir/ | ||
+ | touch my_dir/ | ||
+ | touch my_dir/ | ||
+ | ls -l | ||
+ | """ | ||
+ | stash includes: " | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | stage(" | ||
+ | steps { | ||
+ | script { | ||
+ | cleanWs() | ||
+ | sh "ls -l" | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | stage(" | ||
+ | steps { | ||
+ | script { | ||
+ | unstash name: " | ||
+ | sh "ls -l my_dir" | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | < | ||
+ | < | ||
+ | Архивирует артефакты сборки, | ||
+ | По умолчанию Maven автоматически архивирует произведенные артефакты. Указанные здесь артефакты будут архивированы поверх\\ | ||
+ | Файлы указываются так же маской\\ | ||
+ | |||
+ | <code groovy> | ||
+ | archiveArtifacts artifacts: ' | ||
+ | archiveArtifacts artifacts: ' | ||
+ | archiveArtifacts artifacts: ' | ||
+ | |||
+ | # Из примера выше | ||
+ | archiveArtifacts artifacts: ' | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===== Примеры ===== | ||
< | < | ||
< | < | ||
Строка 426: | Строка 503: | ||
< | < | ||
- | < | + | < |
<code groovy> | <code groovy> | ||
+ | pipeline { | ||
+ | agent { | ||
+ | label ' | ||
+ | } | ||
+ | |||
+ | options { | ||
+ | quietPeriod 5 | ||
+ | ansiColor(' | ||
+ | timestamps() | ||
+ | buildDiscarder logRotator(artifactDaysToKeepStr: | ||
+ | } | ||
+ | |||
+ | stages { | ||
+ | stage(' | ||
+ | steps { | ||
+ | script { | ||
+ | cleanWs() | ||
+ | sh( | ||
+ | label: 'repo sync', | ||
+ | script: ''' | ||
+ | PATH=" | ||
+ | repo init -u ssh:// | ||
+ | repo sync | ||
+ | repo forall -c git checkout " | ||
+ | ''' | ||
+ | ) | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | # | ||
+ | # Выбор ветки | ||
+ | # | ||
+ | stage(' | ||
+ | steps { | ||
+ | script { | ||
+ | SetParameters() | ||
+ | cleanWs() | ||
+ | sh( | ||
+ | label: 'repo sync', | ||
+ | script: ''' | ||
+ | PATH=" | ||
+ | repo init -u ssh:// | ||
+ | repo sync | ||
+ | if [ ${BRANCH} != " | ||
+ | repo forall -c git checkout ${BRANCH} | ||
+ | fi | ||
+ | if [ ${GERRIT_REFSPEC} != " | ||
+ | cd igs/ | ||
+ | fi | ||
+ | ''' | ||
+ | ) | ||
+ | } | ||
+ | } | ||
+ | } | ||
</ | </ | ||
</ | </ | ||
Строка 434: | Строка 569: | ||
- | ====== Use Gradle ====== | + | < |
+ | < | ||
+ | <code bash> | ||
+ | - name: " | ||
+ | block: | ||
+ | - name: " | ||
+ | import_tasks: | ||
+ | - name: " | ||
+ | ansible.builtin.shell: | ||
+ | cmd: "sleep 25 && systemctl is-active myservice@{{ instance_name }}.service" | ||
+ | rescue: | ||
+ | - name: " | ||
+ | ansible.builtin.shell: | ||
+ | cmd: 'tar -xzvf ./ | ||
+ | chdir: '{{ instance.root_path }}/{{ instance_name }}' | ||
+ | |||
+ | - name: " | ||
+ | import_tasks: | ||
+ | |||
+ | - name: " | ||
+ | ansible.builtin.fail: | ||
+ | msg: "!!! Откат изменений после сбоя. Прерываем дальнейшее выполнение !!!" | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | < | ||
+ | < | ||
+ | <code java> | ||
+ | pipeline { | ||
+ | |||
+ | agent { | ||
+ | label ' | ||
+ | } | ||
+ | |||
+ | options { | ||
+ | quietPeriod 5 | ||
+ | ansiColor(' | ||
+ | timestamps() | ||
+ | buildDiscarder logRotator(artifactDaysToKeepStr: | ||
+ | } | ||
+ | |||
+ | environment { | ||
+ | EXTRAS = getExtras() | ||
+ | } | ||
+ | |||
+ | stages { | ||
+ | stage(' | ||
+ | steps { | ||
+ | script { | ||
+ | SetParameters() | ||
+ | cleanWs() | ||
+ | script { | ||
+ | currentBuild.displayName = " | ||
+ | buildDescription " | ||
+ | } | ||
+ | sh( | ||
+ | label: 'repo sync', | ||
+ | script: ''' | ||
+ | PATH=" | ||
+ | repo init -u ssh:// | ||
+ | repo sync | ||
+ | if [ ${BRANCH} != " | ||
+ | repo forall -c git checkout ${BRANCH} | ||
+ | fi | ||
+ | if [ ${GERRIT_REFSPEC} != " | ||
+ | cd igs/ | ||
+ | fi | ||
+ | ''' | ||
+ | ) | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | stage(' | ||
+ | when { | ||
+ | expression { | ||
+ | !params.SKIP_BUILD | ||
+ | } | ||
+ | } | ||
+ | environment { | ||
+ | NEXUS_CREDS = credentials(' | ||
+ | } | ||
+ | steps { | ||
+ | sh label: ' | ||
+ | cd $WORKSPACE/ | ||
+ | ./gradlew \ | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | : | ||
+ | ''' | ||
+ | } | ||
+ | } | ||
+ | stage(' | ||
+ | steps { | ||
+ | dir(" | ||
+ | ansiblePlaybook( | ||
+ | playbook: " | ||
+ | extras: " | ||
+ | colorized: true, | ||
+ | ) | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | def getExtras() { | ||
+ | if (" | ||
+ | return "-e version=${params.VERSION}" | ||
+ | } else { | ||
+ | return "-e version=${params.VERSION} -e instances=${params.APP_INSTANCE}" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | def SetParameters() { | ||
+ | properties([ | ||
+ | parameters([ | ||
+ | booleanParam( | ||
+ | name: ' | ||
+ | description: | ||
+ | defaultValue: | ||
+ | ), | ||
+ | [ | ||
+ | $class: ' | ||
+ | choiceType: ' | ||
+ | description: | ||
+ | name: ' | ||
+ | randomName: ' | ||
+ | filterable: false, | ||
+ | script: [ | ||
+ | $class: ' | ||
+ | fallbackScript: | ||
+ | classpath: [], | ||
+ | sandbox: false, | ||
+ | script: | ||
+ | ''' | ||
+ | return[' | ||
+ | ''' | ||
+ | ], | ||
+ | script: [ | ||
+ | classpath: [], | ||
+ | sandbox: false, | ||
+ | script: | ||
+ | ''' | ||
+ | def cmd = ['/ | ||
+ | def result = cmd.execute().text.tokenize() | ||
+ | return result | ||
+ | ''' | ||
+ | ] | ||
+ | ] | ||
+ | ], | ||
+ | [ | ||
+ | $class: ' | ||
+ | choiceType: ' | ||
+ | name: ' | ||
+ | description: | ||
+ | randomName: ' | ||
+ | script: [ | ||
+ | $class: ' | ||
+ | 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.< | ||
+ | ), | ||
+ | CredentialsMatchers.withId(credentialsId) | ||
+ | ) | ||
+ | } | ||
+ | credential = lookupSystemCredentials(" | ||
+ | nexusLogin = credential.getUsername() | ||
+ | nexusPasswd = credential.getPassword().getPlainText() | ||
+ | def targetUrl=" | ||
+ | def sout = new StringBuilder(), | ||
+ | def proc = "curl -X GET $targetUrl" | ||
+ | proc.consumeProcessOutput(sout, | ||
+ | proc.waitForOrKill(1000) | ||
+ | def response=sout.toString() | ||
+ | def metadata = new XmlParser().parseText(response) | ||
+ | def versions = [' | ||
+ | versions.addAll(metadata.versioning.versions.version.collect({it.text()}).reverse()) | ||
+ | return versions | ||
+ | ''' | ||
+ | ] | ||
+ | ] | ||
+ | ], | ||
+ | [ | ||
+ | $class | ||
+ | choiceType | ||
+ | filterLength: | ||
+ | filterable | ||
+ | name : ' | ||
+ | randomName | ||
+ | script | ||
+ | $class: ' | ||
+ | script: [ | ||
+ | classpath: [], | ||
+ | sandbox | ||
+ | script | ||
+ | def fm_instances = [] | ||
+ | def file1 = new File("/ | ||
+ | file1.eachLine { | ||
+ | fm_instances.add(it) | ||
+ | } | ||
+ | def result = [" | ||
+ | result.addAll(fm_instances) | ||
+ | return result''' | ||
+ | ] | ||
+ | ] | ||
+ | ], | ||
+ | string( | ||
+ | defaultValue: | ||
+ | description: | ||
+ | name: ' | ||
+ | trim: true | ||
+ | ) | ||
+ | ]) | ||
+ | ]) | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | < | ||
+ | < | ||
+ | <code groovy> | ||
+ | pipeline { | ||
+ | environment { | ||
+ | MY_VAR = " | ||
+ | } | ||
+ | |||
+ | agent { | ||
+ | node { | ||
+ | label ' | ||
+ | } | ||
+ | } | ||
+ | |||
+ | parameters { | ||
+ | string description: | ||
+ | } | ||
+ | |||
+ | stages { | ||
+ | stage(" | ||
+ | when { | ||
+ | expression { | ||
+ | MY_VAR == " | ||
+ | } | ||
+ | } | ||
+ | steps { | ||
+ | cleanWs() | ||
+ | script { | ||
+ | sh "echo 'this is first stage'" | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | stage(" | ||
+ | when { | ||
+ | expression { | ||
+ | MY_VAR == " | ||
+ | } | ||
+ | } | ||
+ | steps { | ||
+ | script { | ||
+ | sh "echo 'this is second stage'" | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | < | ||
+ | < | ||
+ | <code groovy> | ||
+ | stage(' | ||
+ | when { | ||
+ | branch ' | ||
+ | branch ' | ||
+ | |||
+ | } | ||
+ | ----- | ||
+ | when { | ||
+ | expression { | ||
+ | return env.BRANCH_NAME != ' | ||
+ | inputOptimizer == " | ||
+ | } | ||
+ | } | ||
+ | ----- | ||
+ | when { | ||
+ | environment name: ' | ||
+ | } | ||
+ | ----- | ||
+ | |||
+ | steps { | ||
+ | echo 'run this stage - ony if the branch = master branch' | ||
+ | // Так же внутри степа | ||
+ | script { | ||
+ | if (env.BRANCH_NAME == " | ||
+ | echo ' | ||
+ | } else { | ||
+ | echo ' | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Вариативность: | ||
+ | <code groovy> | ||
+ | when { allOf { branch ' | ||
+ | --- | ||
+ | when { anyOf { branch ' | ||
+ | --- | ||
+ | when { not { branch ' | ||
+ | ---- | ||
+ | |||
+ | // Комбинировать тоже можно | ||
+ | when { | ||
+ | branch ' | ||
+ | anyOf { | ||
+ | environment name: ' | ||
+ | environment name: ' | ||
+ | } | ||
+ | } | ||
+ | --- | ||
+ | |||
+ | when { | ||
+ | expression { BRANCH_NAME ==~ / | ||
+ | anyOf { | ||
+ | environment name: ' | ||
+ | environment name: ' | ||
+ | } | ||
+ | } | ||
+ | --- | ||
+ | |||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | Еще можно задать параметры сравнения (comparator): | ||
+ | <code groovy> | ||
+ | // Сравнивать по регулярке | ||
+ | when { branch pattern: " | ||
+ | |||
+ | // Простое сравнение | ||
+ | when { branch: " | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | :!: Строки могут плохо преобразовываться в логические значения, | ||
+ | |||
+ | |||
+ | Вариативность выполнения в зависимости от переменных и параметров\\ | ||
+ | В т.ч подходит для инициализации джобы запуском без параметров\\ | ||
+ | <code groovy> | ||
+ | pipeline { | ||
+ | environment { | ||
+ | MY_VAR = " | ||
+ | } | ||
+ | |||
+ | agent any | ||
+ | |||
+ | parameters { | ||
+ | string description: | ||
+ | string description: | ||
+ | string description: | ||
+ | } | ||
+ | |||
+ | stages { | ||
+ | stage(" | ||
+ | when { | ||
+ | expression { params.MY_VAR } | ||
+ | expression { params.MY_VAR2 != "" | ||
+ | expression { !params.MY_VAR2 } | ||
+ | expression { params.MY_PARAM == " | ||
+ | } | ||
+ | steps { | ||
+ | cleanWs() | ||
+ | script { | ||
+ | sh "echo 'this is first stage'" | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | < | ||
+ | < | ||
+ | <code groovy> | ||
+ | // Создание файла | ||
+ | configFileProvider([configFile(fileId: | ||
+ | script { | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Данные в переменной | ||
+ | configFileProvider([configFile(fileId: | ||
+ | script { | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | < | ||
+ | < | ||
+ | <code groovy> | ||
+ | writeFile file: " | ||
+ | text: ${var1} | ||
+ | test: ${var2} | ||
+ | """ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ==== Запись результатов/ | ||
+ | |||
+ | < | ||
+ | < | ||
+ | |||
+ | Запись резов текстом, | ||
+ | Можно применять html\\ | ||
+ | <code bash> | ||
+ | currentBuild.description = " | ||
+ | </ | ||
+ | |||
+ | Артефакты файлами\\ | ||
+ | <code bash> | ||
+ | archiveArtifacts artifacts: ' | ||
+ | </ | ||
+ | |||
+ | |||
+ | Публикация полноценного отчета, | ||
+ | <code bash> | ||
+ | publishHTML (target : [allowMissing: | ||
+ | keepAll: true, reportDir: '', | ||
+ | reportName: 'My Reports', | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ====== Use Gradle ====== | ||
< | < | ||
< | < | ||
Строка 464: | Строка 1076: | ||
</ | </ | ||
</ | </ | ||
+ | |||
Строка 484: | Строка 1097: | ||
</ | </ | ||
</ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Прерывание | ||
+ | |||
+ | |||
+ | |||
+ | if (!params.MY_VAR.contains(" | ||
+ | currentBuild.result = ' | ||
+ | error(" | ||
+ | } | ||
+ | |||
+ | |||