t.me/atinfo_chat Telegram группа по автоматизации тестирования

Как из одного Jenkinsfile в репозитории управлять другими ветками?

groovy
gitlab
jenkins
pipeline
Теги: #<Tag:0x00007f9e3cf9a830> #<Tag:0x00007f9e3cf9a628> #<Tag:0x00007f9e3cf9a420> #<Tag:0x00007f9e3cf9a128>

(bor_bor) #1

Добрый день. Я начинающий Jenkins user и только в начале пути изучения этого сервиса.
Столкнулся с проблемой следующего характера.
Мне нужно сделать так, чтобы при сборке проекта определенные действия применялись только к одной ветке.
Использую Git Lab.
К примеру, при сборке веток Jenkins_Test и Jenkins_Test2, отчет/артефакты должны выгружаться в Nexus только с ветки Jenkins_Test. И, соответственно, если запускается только по ветке Jenkins_Test2, то ничего никуда не выгружается. С выгрузкой как таковой проблем нет никаких. А вот в определением или исключением веток появились проблемы.
Много гуглил уже, решения кейса не нашел. Вот пример, кода (который не работает).

        stage('Nexus') {
   when {
       not {
           branch 'Jenkins_Test2 '
       }
   }  
            steps {
                nexusPublisher nexusInstanceId: 'Nexus', nexusRepositoryId: 'maven', packages: [[$class: 'Maven', mavenAssetList: [[classifier: '', extension: '', filePath: 'target/***.jar']], mavenCoordinate: [artifactId: 'integration', groupId: '***', packaging: 'jar', version: '${BUILD_NUMBER}']]]
            }
        }

Помогите , пожалуйста! Очень жду предложений.
Вполне допускаю применение плагинов.


(Alexandr D.) #2

Stages в помощь.


(bor_bor) #3

Можете конкретнее, пожалуйста. Stages у меня и так используется.


(Alexandr D.) #4

Внутри stages разделить на вложенные stages (при необходимости) или просто на несколько stage со своими условиями веток

stage('deploy staging') {
                    when {
                        anyOf {
                            branch 'master';
                            branch 'hotfix-*';
                            branch 'release-*';
                        }
                    }

Но я не очень понял, почему ваш кейс не работает? Какая ошибка? Not тоже должен работать.


(bor_bor) #5

Cейчас заработало, но все равно не правильно. Как-будто синтаксис был нарушен (проблем и точка с запятой)

При такой конфигурации кода:

    stage('Nexus') {
        when {
            branch 'Test_Jenkins'
        }
        steps {
            nexusPublisher nexusInstanceId: ...
        }
    }

Появляется следующий лог: (хотя комит был в ветке Test_Jenkins, веток в проекте много)

Stage “Nexus” skipped due to when conditional
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS


(bor_bor) #6

Плюс проблема следующего рода возникает.
Jenkinsfile находится в ветке Test_Jenkins. Если сделать комит в ветке Test_Jenkins2, то выходит следующая ошибка:

ERROR: /var/lib/jenkins/workspace/***/Jenkinsfile not found
Finished: FAILURE

Хотя pipeline настроен на все ветки и он не должен выполнить только шаг “Nexus”.
Сейчас пришла идея, что Jenkinsfile должен быть в ветке master? С чем это связано.


(Alexandr D.) #7

Jenkinsfile должен быть в каждой ветке, которая должна билдиться


(Vladislav Abramov) #8

файл сборки должен быть одинаковым на все ветки, чтобы проблемы как у вас сейчас не было, и чтобы вы сами не путались, почему в мастере написано одно делать, а делается совсем другое

погуглите gitflow, gitlab flow и так далее


(Alexandr D.) #9

Исходя из всего этого, думаю проблема в том, что у вас разные версии Jenkinsfile в ветках, отсюда все проблемы.


(bor_bor) #10

Все правы! Одно из другого выходит, хорошо.
В целом еще общий вопрос есть.
Можно ли тоже самое ( чтобы независимо от того, где произошел комит, выгрузка осуществлялась только при комите мастера) сделать не через pipeline, а через обычную задачу (где настройки, плагины)?


(Vladislav Abramov) #11

ну в смысле не через пайплайн?
вы поймите правильно, в хороших ci на каждый чих сборка происходит, и это нормально


(bor_bor) #12

Через это. Мы просто подключаем задачу к репозиторию в гите. И в настройках задачи указываем все конфигурации сборки (триггеры, выгрузки, послесборочные операции итд.) Там же и куча плагинов и т.п.


(Vladislav Abramov) #13

ну то есть вы просто напишите все свои пайплайны ручками :smiley:

а зачем вам дженкинс? у гитлаба вполне себе хороший ci встроенный


(bor_bor) #14

В продолжении темы, Вы сказали, что везде должен быть одинаковый Jenkinsfile.
Я правильно понимаю, что если будует использоваться Multibranch, то уже идентичность файлов не принципиальна?


(bor_bor) #15

Я его использовал и у меня с ним тоже много проблем. Был вопрос открыт, но так и не решили его.


(Vladislav Abramov) #16

я в дженкинсе не силен. знаю только, что у него куча плагинов, что является плюсом и минусом одновременно (мол захочешь плагин обновить, а соседний плагин этого сделать не даст)
насчет мультибранча тем более не подскажу.

если вы погуглите gitflow, то увидите, что у вас должна быть хотя бы одна ветка (master), в которую собираются все изменения и из которой потом идут ветки стендов разработки, тестирования, продакшена и препродакшена. В общем случае, у вас в мастере актуальный файл сборочной линии, в котором вы описываете все процессы сборки и поставки, который потом расходится по целевым веткам через мержи или черри-пики


(Alexandr D.) #17

Нет, вы неправильно понимаете.
Jenkinsfile обязан находиться в ветке, которая будет собираться через pipeline. Если у вас собирается при пуше в репу две ветки, значит в этих двух ветках должен быть этот файл. И он должен быть одинаковым, для избежания коллизий.

Multibranch отличная фича в Jenkins, которую лично я использую в данный момент и в хвост и в гриву.

  1. Настраивается хук в гите (ББ/гитхаб, что угодно), который будет улетать на Jenkins при пушах в репу.
  2. В Jenkins можно настроить кучу разных фильтров, при которых будет срабатывать триггер на билд.
    У меня, например, это выглядит так:

Т.е. автоматически стартуют билды только веток, которые подпадают под фильтры.
При этом не только при их изменении, но и при их создании (что немаловажно для веток типа хотфикс-релиз, которые форкаются от дева и просто вливаются без изменений)

Ещё раз - идентичность Jenkinsfile во всех ветках необходима!
Иначе у вас будет выполняться разный скрипт сборки/деплоя в зависимости от ветки, что приведет к запутыванию и форс-мажорам в конечном итоге.
Если вам надо сделать разные условия - делайте это в одном Jenkinsfile и потом раскидывайте его в нужные ветки.