Страницы

Поиск по вопросам

Показаны сообщения с ярлыком jenkins. Показать все сообщения
Показаны сообщения с ярлыком jenkins. Показать все сообщения

пятница, 14 февраля 2020 г.

Постоянный запуск билда на дженкинсе

#git #bitbucket #jenkins #непрерывная_интеграция


У меня есть jenkins и проект на битбакете. Я настроил запуск билда по коммиту в битбакет.
Если билд прошел успешно, я хочу запушить мои изменения, полученные при работе билда,
в ветку, при коммите которой, запускается эта джоба. Я не хочу повторно запускать билд,
как решить эту проблему?
    


Ответы

Ответ 1



Заведите метку, обозначающую, что для данной задачи не нужен запуск CI, например [skip ci]. Когда Jenkins делает коммит, пускай добавляет эту метку в текст сообщения коммита. При запуске конвейера (pipeline) в первую очередь проверяйте наличие метки в сообщении последнего коммита текущей ветки. Есть расширение Jenkins CI Skip, но оно давно не обновлялось. Если оно не работает, можно сделать ту же проверку вручную. Сначала определите наличие метки в сообщении коммита и экспортируйте переменную в окружение. if [[ $(git show -s --format=%B) == *"skip ci"* ]]; then export SKIPCI=1 fi После добавьте условие: если метки нет, выполнять остальную часть конвейера.

Ответ 2



Проще создать юзера jenkins в bitbucket и сконфигурить git-config на jenkins'е. После чего исключить username jenkins из коммитеров которые триггерят hook.

среда, 12 февраля 2020 г.

Jenkins запуск build проекта после push

#gitlab #build #jenkins


Доброго времени суток. Первый раз столкнулся с задачами CI. Проблема - не получается
адекватно настроить Jenkins. Что требуется: после push проекта на GitLab (именно после
push, это важно), Jenkins должен попытаться собрать проект.

Шаги предпринятые для решения этой проблемы:


Jenkins сервер поднят и настроен, и работает по адресу jenkinsaddres:port
На Jenkins сервере есть GitLab connection опция которая настроена на gitlabhost,
GitLab API token задан и test connection возвращает радостное success.
Добавлен проект, Source Code Management, Repository URL, Credentials, Branch Specifier
настроены.
В проекте опции Build when a change is pushed to GitLab. GitLab CI Service URL: jenkinsaddres:port/project/test
активна, GitLab Triggers: Push events опция так же активна.
GitLabProject -> Settings -> Web hook -> jenkinsaddres:port/project/test, и опция
Push Events тоже активна.


Проект build'ится по расписанию, или вручную но никак не хочет собираться даже при
тестовой отправке hook'а с GitLab. POST сообщение доходит следующего вида source: gitlabhost;
destination: jenkinsaddres; Protocol: HTTP; info: POST /project/test HTTP/1.1 (application/json).
Ответ: адреса верные поэтому не буду их показывать, поле info: HTTP/1.1 404 Not Found
(text/html).

Если на Jenkins выключить все secure опции, и посылать hook на jenkinsaddres:port/job/test(сюда
он стягивает проекты) то тогда объект все-таки находится: Found. Но оказывается что
изменений Jenkins не видит (Not Modified), думаю поэтому проект и не ребилдится.
    


Ответы

Ответ 1



Борюсь с подобной же проблемой. Статья https://github.com/jenkinsci/gitlab-plugin/issues/298 дала следующую подсказку - тестируют с POST а не GET, что возвращает 403 так как "anonymous is missing the Job/Build permission". Два решения по починке https://github.com/jenkinsci/gitlab-plugin/issues/375 Если не заработает после правки - стоит проверить имя проекта. Если что есть URL encoded - это проблемма Так Unit Tests не работает, а UnitTests работает.

Ответ 2



Можно использовать триггер с токеном, он позволяет запускать сборку даже анонимному пользователю. Например, в моем дженкинсе аноним имеет разрешение только на просмотр (Read) задач и сборок. Но хуки работают из Гитлаба, curl'ом и просто через браузер. В конфигурации задачи example_jenkins_job: Хук в Гитлабе: http://jenkinsaddress:port/job/example_jenkins_job/build?token=secret_token Или, если задача параметризованная: http://jenkinsaddress:port/job/example_jenkins_job /buildWithParameters?token=secret_token В этом случае будет запущена сборка с дефолтными значениями параметров. Вы можете передавать собственные значения параметров следующим образом: http://jenkinsaddress:port/job/example_jenkins_job /buildWithParameters?token=secret_token¶m1=value1¶m2=value2 Можно добавить причину сборки: &cause=Cause+Text Она сохранится в информации о сборке: И в логе сборки, первой строкой: Started by remote host 127.0.0.1 with note: Cause Text

пятница, 24 января 2020 г.

Регулярный запуск параметризованой сборки с заданными параметрами

#jenkins #непрерывная_интеграция


Jenkins, параметризованная сборка (Parameterized Build), имеющая несколько строковых
параметров.

Хочу настроить регулярное выполнение сборки с заданными значениями параметров (это
будут не дефолтные значения).

Пока что лучшее, что придумал — создать новую регулярную сборку, которая при запуске
будет просто запускать эту через Parametrized Trigger. Но это выглядит как-то слишком
сложно. 

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


Ответы

Ответ 1



Походу только через это: https://wiki.jenkins.io/display/JENKINS/Parameterized+Scheduler+Plugin но судя по комментам там пока водятся баги.

Выполнение задач в Docker-контейнере в Jenkins

#docker #jenkins #непрерывная_интеграция


Может ли Jenkins работать так же, как GitLab Runner + Docker executor:


Из образа развернуть контейнер.
Внутрь контейнера клонировать репозиторий git, выполнить произвольные команды.
Выделить артефакты и сохранить их вне контейнера, свернуть контейнер (завершить его
работу).



  Вопрос: нужна пошаговая инструкция по настройке Jenkins для выполнения трех вышеуказанных
шагов.


Нашел Docker Plugin. Вроде бы он умеет разворачивать Jenkins slave в докере, подключать
его к мастеру и утилизировать после использования. Этот вариант мне точно не подходит,
потому что нужно тащить в сборочное окружение Java и прочие не нужные там вещи. Базовый
образ jenkins-slave весит в 100 раз больше alpine, это вообще за гранью разумного.

docker images                                                                   
                                          
REPOSITORY              ...     SIZE
alpine                  ...     3.97 MB
evarga/jenkins-slave    ...     368 MB


Еще нашел плагин Docker build step. Одна из фич — "create new container from image".
Возможно, мне нужно именно это, но я не понимаю, как выполнить пункты 2 и 3.
    


Ответы

Ответ 1



В Jenkins можно выполнить bash/batch команду, для bash это будет примерно так: docker run -it -d my_image # запускам image в detached моде docker exec $(docker ps -a -q --filter ancestor=my_image) bash -c "cd your_path; your_command" # запускаем Вашу команду в контейнере. list=$(docker exec $(docker ps -a -q --filter ancestor=my_image) bash -c 'ls /path/to/artifacts/inside/container') # создаем список артефактов, которые мы будем вытаскивать из контенера for i in $list; do docker cp $(docker ps -a -q --filter ancestor=my_image):$i ./path/to/outside container ; done # вытаскиваем артефакты согласно списку for i in $(docker ps -a -q --filter ancestor=my_image); do docker rm $(docker stop $i); done # удалям контейнеры, если они работают

суббота, 11 января 2020 г.

Разбиение строки на части в shell скрипте, запускаемом через jenkins pipeline

#linux #bash #shell #jenkins


Дано:

работающий shell код, разбивающий строку по точке и пишущий части полученные в переменные.

version='1.2.3.4'

IFS='.' read -r major minor micro build <<- _EOF_
$version
_EOF_

echo $major $minor


Задача:

Использовать его в рамках pipeline скрипта Jenkins

Проблема:

Т.к. мне надо использовать в shell скрипте переменные из pipeline я должен обернуть
shell код в 3 двойных кавычки. Из-за них мне надо всё подряд экранировать. И всё экранируется
кроме вот этого места:

stage('test') {
    steps {
        sh """
        version='1.2.3.4'

        IFS='.' read -r major minor micro build <<- _EOF_
        \$version
        _EOF_

        echo \$major \$minor
        """
    }
}


Если экранировать так: \$version - происходит попытка чтения pipline переменной и
падение. Если начать как-то извращаться - лезут уж совсем странные ошибки типа unexpected
end of file

Вопрос:

Как тут надо сделать? И почему проблема именно тут? У меня вообще довольно много
там кода, но экранирование не работает именно тут
    


Ответы

Ответ 1



Проблема заключается в том, что перед последовательностью символов, завершающих heredoc, должны быть только табуляторы (0х09), и наких пробелов, ни перед, ни после. Подробнее в этом ответе. О том, что редакторы могут заменять вводимые символы табуляции пробелами, см., например, связанный с ним вопрос. Чтобы не заботится об отступпах, можно просто удалить отступы методом stripIndent(). Фрагмент кода из вопроса будет выглядеть так: stage('test') { steps { sh """ version='1.2.3.4' IFS='.' read -r major minor micro build <<- _EOF_ \$version _EOF_ echo \$major \$minor """.stripIndent() } } PS этот ответ касается только "красоты" кода, о целесообразности здесь heredoc уже подробно отвечено в комментарии @alexanderbarakin.

Ответ 2



В итоге проблема оказалась в пробелах и табах, с помощью которых код станавится читаемым и красивым. Если код изуродовать так(убрав отступы): stage('test') { steps { sh """ version='1.2.3.4' IFS=. read a b c d <

Ответ 3



У меня получилось так: node { sh """echo -e "sqlplus ${dbuser}/${dbpass}@test << EOF select * from dual; EOF " > test.sh """ sh "bash -vx test.sh" }

суббота, 4 января 2020 г.

Настройка и интеграция Jenkins и Gradle с нуля

#java #git #юнит_тесты #gradle #jenkins


Туториалов много, но каждый охватывает только часть процесса, не могу найти простой
и понятный для новичка, охватывающий весь процесс.

Что я хочу: 


Есть Java приложение (причем, это может быть как web приложение, запускаемое в том
же Tomcat, либо обычное консольное приложение или библиотека, собираемая в jar  )
Написаны Unit и интеграционные тесты
Приложение собирается gradle-ом.
Развернут Artifactory с репозиторием, куда я хочу деплоить сборки. 


Собственно процесс, который я хочу настроить:


При каждом пуше на сервере прогоняются unit-тесты, интеграционные тесты, анализируется
покрытие кода тестами, codestyle и т.д. 
Если все хорошо, сборка деплоится в Artifactory, а также (если приложение - веб),
обновляется и перезапускается на dev сервере.
Либо иметь некоторую страничку, представляющее собой таблицу: ссылка на скачивание
- commit message (для примера: http://abrok.eu/stockfish/)
Если что-то пошло не так, ответ с описанием приходит на почту (например)


Было бы здорово посмотреть туториал с самого нуля, когда создается helloWorld Java
проект, как настраивается Jenkins, что происходит, когда делается commit и т.д. Т.е.
туториал, где одновременно с настройкой Jenkins пишется и изменяется java код. 

Может быть не обязательно полностью описанный мной процесс, но какой-нибудь туториал,
который показывает упрощенно процесс разработки (изменение, написание тестов, коммиты)
java приложение при работающем jenkins. 
    


Ответы

Ответ 1



Если сфокусироваться на организации процесса сборки средствами Jenkins, получится примерно следующее: При каждом пуше на сервере прогоняются unit-тесты, интеграционные тесты, анализируется покрытие кода тестами, codestyle и т.д. Для проекта (job) задается триггер сборки "Опрашивать SCM об изменениях" и расписание проверки Git-а на наличие свежих коммитов, например раз в 10 минут. Расписание задается в формате crontab: H/10 * * * *. Другой вариант - выбрать триггер "Trigger builds remotely (e.g., from scripts)" и настроить post-commit hook в репозитории, который будет уведомлять Jenkins о наличии новых коммитов. Для этого достаточно дернуть curl-ом адрес http:///job//build. Прогон тестов реализуется вызовом gradle. Установите на билдсервер Gradle Plugin и в качестве основного шага сборки вызывайте gradle, как если бы вы запускали его на локальной машине. Если сборка будет включать в себя прогон тестов, jenkins сохранит информацию о результатах. Если все хорошо, сборка деплоится в Artifactory, а также (если приложение - веб), обновляется и перезапускается на dev сервере. Ставите Artifactory Plugin и добавляете послесборочный шаг "Deploy artifacts to Artifactory". Редеплой приложение лучше вынести в отдельный проект, который будет вызываться после основной сборки через Послесборочную операцию "Build other project". Чтобы "дотянуться" из проекта деплоя до артефактов основной сборки, установите Copy Artifacts Plugin. Вам будет доступен шаг сборки "Copy artifacts from another project", который скопирует нужные файлы из исходной (upstream) сборки. Саму процедуру деплоя можно реализовать средствами Jenkins (например, Deploy Plugin), средствами gradle (например, gradle-cargo-plugin) или просто shell-скриптом. Если что-то пошло не так, ответ с описанием приходит на почту (например) Это Jenkins умеет "из коробки", достаточно включить в настройках проекта флажок "E-mail Notification". Но я рекомендую поставить Email-ext plugin - он позволяет гибче настраивать события для письма и содержимое.

пятница, 27 декабря 2019 г.

Как использовать возможность автоматического merge изменений сервером непрерывной интеграции?

#jenkins #непрерывная_интеграция #teamcity


У TeamCity есть билд фича Automatic merge. Она позволяет сделать merge изменений
коммита в определенную ветку (интеграции). Каждый раз когда кто-нибудь делает коммит
который проходит все тесты можно этот коммит автоматически влить в ветку интерграции
и, если не получилось, выдать ошибку что при мерже возникли конфликты что позволит
команде оперативно среагировать.

Вопрос: Что делать после того как оказалось что при слиянии возникли конфликты?

По идее, если программист работает в feature ветке, он должен намержить ветку на
себя и разрулить конфликты. Только это не девелоп. В девелоп нельзя автоматом мержить.
Не могу разобраться как эту фичу грамотно заюзать. Какие есть use-cases?
    


Ответы

Ответ 1



Мне видится два варианта использования автоматического мержа: Если вы используете фича/багфикс бранчи, но при этом в вашем процессе нет пулл-реквестов/интеграционной ветки, т.е. вы готовы сразу мержить в мастер. Это позволяет достичь изолированности изменений и их автоматической интеграции. (Хотя лично мне такая модель представляется сомнительной, особенно для достаточно больших изменений, поскольку заставляет делать локальные коммиты без пуша, а это может быть чревато.) Если вы используете интеграционный бранч, куда вливаются фича/багфикс бранчи. Изменения тестируются, а после этого вливаются в мастер. Во втором случае интеграционный бранч по сути является копией мастера с добавленными изменениями. Поэтому при вливании в интеграционный бранч конфликты могут возникнуть по двум причинам: изменения конфликтуют с мастером изменения конфликтуют с изменениями из другого фича/багфикс бранча, которые были влиты в интеграционную ветку, но еще не попали в мастер В обоих случаях разруливать конфликт достаточно мержем из интеграционной ветки. Первый случай очевиден -- конфликтующие изменения из мастера есть и в интеграционной ветке. Второй случай тоже очевиден -- без "зеленой" интеграционной ветки работа дальше не пойдет. И тут действует стандартное правило -- кто последний коммитит, тот и мержит :). идея в том чтобы обнаруживать конфликты как можно раньше. Тогда может стоит просто добавить мерж из мастера в фича/багфикс ветку при каждом билде? Если говорить о TeamCity, то первым шагом билда добавляете следующий код: git remote set-url origin %repo_url% if NOT %teamcity.build.branch.is_default%==true git fetch if NOT %teamcity.build.branch.is_default%==true git merge origin/master Это гарантированно будет обнаруживать конфликты сразу. Мастер будет всегда "зеленый", вы не будете получать конфликты из-за того, что кто-то залил конфликтующие изменения в интеграционную ветку.

воскресенье, 22 декабря 2019 г.

Как передавать значения переменных из Jenkins в Java проект

#java #maven #test_automation #jenkins


Привет. Подскажите, пожалуйста, 

есть проект, авто-тесты, которые, например создают некоторую сущность. Данные для
этих сущностей беруться либо из .properties по ключам, либо из .txt документов опять
же из ресурcов (директория).

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

Нашел, что в Jenkins можно настраивать параметризацию, т.е. запускать с параметром.

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


на Jenkins создаю Job Item, указываю параметр "This project is parameterized" = True


Создаю переменную:

String Parameter
Name = generalUrl
Default Value = http://ru.stackoverflow.com


далее, указываю, что этот job item должен собираться с помощью maven, путь к pom.xml
и все такое.
И в goal прописываю - clean test

Сохраняю.


Иду в проект, в файле pom.xml указываю



http://maven.apache.org/maven-v4_0_0.xsd">
    4.0.0

com
erm-nav-qa-integration-test
1.0-SNAPSHOT


    2.53.1
    6.9.10
    3.9.2
    4.12
    1.4.23
    2.19.1
    1.8.5
    3.5.1
    9.3.11.v20160721
    2.5
    3.9
    smoke_ui_tests.xml
    http://ru.stackoverflow.com




    
        org.testng
        testng
        ${testng.version}
    

    
        com.codeborne
        selenide
        ${selenide.version}
    

    
        junit
        junit
        ${junit.vesrion}
    

    
        ru.yandex.qatools.allure
        allure-testng-adaptor
        ${allure.version}
        
            
                junit
                junit
            
        
    

    
        org.apache.poi
        poi
        ${apache.poi.version}
        
            
                xml-apis
                xml-apis
            
        
    
    
        org.apache.poi
        poi-ooxml
        ${apache.poi.version}
        
            
                xml-apis
                xml-apis
            
        
    





    

        

            
                org.apache.maven.plugins
                maven-resources-plugin
                3.0.1
            

            
                org.apache.maven.plugins
                maven-surefire-plugin
                ${maven.surefire.version}
                

                    
                        ${suiteName}
                    

                    true
                    
                        -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                    

                    
                        ${generalUrl}
                    

                

                
                    
                        org.aspectj
                        aspectjweaver
                        ${aspectj.version}
                    
                

            

            
                org.apache.maven.plugins
                maven-compiler-plugin
                ${maven.compiler.version}
                
                    1.8
                    1.8
                    true
                    true
                
            

            
            
                org.eclipse.jetty
                jetty-maven-plugin
                ${jetty.version}
                
                    ${project.build.directory}/site/allure-maven-plugin
                    stop
                    1234
                
            

        

    

    
        
            src/main/resources
            true
        
    





    true
    
        
            ru.yandex.qatools.allure
            allure-maven-plugin
            ${allure.maven.version}
            
                
                    ${basedir}/target/allure-reports/
                    ${basedir}/target/allure-results
                
            
        

    

    ${basedir}/site






В файле .properties есть ключ с значнием baseUrl=${generalUrl}.
Вроде бы все сделал как находил по кусочкам где-то, запускаю свои тесты, получаю ошибку:

org.openqa.selenium.WebDriverException: unknown error: unhandled inspector error:
{"code":-32603,"message":"Cannot navigate to invalid URL"}
  (Session info: chrome=53.0.2785.89)


Включаю дебаггер и вижу, что на этапе чтения файла .properties, система берет просто
${generalUrl}, т.е. просто как текст...

Подскажите, как можно из Jenkins передавать переменные, т.е. как настроить сам pom.xml,
.properties, чтобы можно было выполнять параметризированный запуск.

Спасибо.

UPD: Добавил pom.xml
    


Ответы

Ответ 1



У вас по сути есть две задачи: пробросить значения параметров сборки из Jenkins в свойство maven-проекта (property). обработать .properties-файл(ы), заменяя заглушки ${generalUrl} на значения свойств maven-а. Maven интерпретирует аргументы JVM -Dfoo=bar в качестве свойств проекта. Значения параметров сборки Jenkins доступны в виде макросов вида ${MYPARAM}. Чтобы передать параметр из Jenkins в maven, в соответствующем шаге сборки в поле Goals and options остается связать свойство maven с параметром Jenkins примерно так: clean install -DgeneralUrl=${generalUrl} (замените clean install на то, что используетя в вашем случае) Для подстановки свойств в ресурсы у maven есть готовое решение в составе Maven Resources Plugin - фильтрация ресурсов. Добавьте в pom.xml плагин актуальной версии: org.apache.maven.plugins maven-resources-plugin 3.0.1 Просто в секции вашего pom-файла включите фильтрацию для нужных ресурсов: src/test/resources true Теперь при выполненнии maven-ом фазы process-test-resources будет выполняться задача resources:testResources, которая заменит выражение ${generalUrl} в файле src/main/resources/data.properties на свойство generalUrl из pom-файла, которое в свое очередь может пробрасываться из Jenkins.

Ответ 2



Всем спасибо! Решил с помощью профилей http://software-testing.ru/library/testing/general-testing/1984 И немного переписал загрузку из проперти файлов. По ссылке выше, все детально рассказывается и есть ссылка на архетип проекта, с примером пома с профилями. Теперь тесты запускаются как локально из IDE, береться дефолтное значение из "дибаг.проперти", так и с помощью команды mvn clean -DgeneralUrl=http://google.com test, которое пробрасывает это значение переменной в проект. Дальше с настройкой в Jenkins, дело житейское :).

вторник, 17 декабря 2019 г.

Скрипт для получения информации для Jenkins

#git #jenkins


Есть проект, управление версиями идет через Git. Используем метки tag, чтобы выставлять
версионность проекта. Сейчас переходим на автоматическую сборку проекта через Jenkins.
Хотим автоматически получать информацию от git (в частности использовать команду git
describe) и парсить ее.
Сам с git-ом работаю недавно и не знаю как написать bat-файл, чтобы получить нужную
информацию из git-a и передать её в Jenkins.

Кто сталкивался с подобной задачей, и как ее решили?
    


Ответы

Ответ 1



Ставите Groovy plugin и EnvInject Plugin на Jenkins. А в job-е в Pre Steps делаете следующее: Добавляете шаг "Выполнить команду Windows"/"Выполнить команду shell", которая вычитает нужные данные из вывода git describe и создаст текстовый файл, например, env.txt в формате KEY=value. Пример готового файла: MY_TAG=sometag Добавляете шаг "Inject environment variables" и указываете упомянутый выше файл в качестве "Properties File Path". Теперь все ключи из файла станут доступными на любом этапе сборки переменными окружения. Например, $MY_TAG. Обработайте данные, как вам нужно, в groovy скрипте: def myTag = build.properties.get("envVars")['MY_TAG'] // делаем магию с myTag Если нужно из groovy-скрипта породить новые переменные окружения: def paramsAction = new ParametersAction([ new StringParameterValue("SOME_VAR", result), new StringParameterValue("SOME_OTHER_VAR", someValue1) ]) build.addAction(pa)

Ответ 2



У jenkins есть плагин git. Скорее всего он позволит решить ваши проблемы

Как в Jenkins запустить последний успешный build проекта?

#git #github #jenkins #непрерывная_интеграция


Есть 2 jobs, в них один и тот же проект;
один job запускается только тогда, когда обнаруживается новая версия git;
второй job должен запускать последнюю версию git, build которой был успешным в 1-ом job.

Как сделать, чтобы 2-ой job запускал последний успешный build 1-го job?
    


Ответы

Ответ 1



Я не очень большой специалист в jenkins, но я бы делал так. Первая задача по выполнению компиляции проекта, копирует скомпилированные файлы, нужные для работы программы, в отдельную папку. Грубо говоря, она делает инсталляцию. Вторая задача при запуске проверяет наличие файлов в папке и запускает, если они есть. Так как неудачная компиляция проекта в первом случае не будет удалять скомпилированные файлы с специальной папки, то вторая задача всегда будет иметь возможность запускать "последний успешный билд".

Ответ 2



Способов много. Я бы в первом проекте сохранял GIT_COMMIT в файл (echo GIT_COMMIT=$GIT_COMMIT > env.properties, а во втором проекте копировал бы этот файл из последней успешной сборки первого проекта (плагин Copy artifact) и использовал бы в shell-скрипте или импортировал информацию плагином EnvInject, что безопаснее. А большие мальчики делают HTTP-запрос к API (URL вида http://твой_сервер/job/твой_проект/lastStableBuild/api/json?tree=actions[lastBuiltRevision[branch[*]]]) и анализируют полученный JSON

Ответ 3



В идеальной CI системе эта схема должна работать так: первый билд делает сборку и публикует результат (например, бинарники) в качестве артефакта второй билд должен зависеть от первого: брать из последнего успешного первого билда его артефакты и запускаться либо вручную, либо автоматически В ТимСити, например, это все есть из коробки. Что касается Дженкинса: артефакты для первого билда он сгенерит плагин Copy Artifacts поможет второму билду скопировать артефакты из первого билда (причем нужно указать, что брать нужно из Last successful build), а автоматического запуска второго билда есть разные способы, в т.ч. и встроенные

воскресенье, 15 декабря 2019 г.

Jenkins. Как сделать чтобы каждый второй билд не запускал тесты?

#java #maven #jenkins


Что нужно поменять/установить в настройках джоба(item) Jenkins, чтобы каждый второй
билд не запускал тесты?
    


Ответы

Ответ 1



Вариант 1 Можно поставить Conditional BuildStep Plugin - он позволяет задавать условие для выполнения отдельного шага сборки. В вашем случае таким условием является четность номера сборки. По порядку: Добавляете шаг Conditional step (single) в билд В качестве условия Run? выбираете Boolean condition. В качестве Token задаете выражение: ${GROOVY,script = "(Thread.currentThread().executable.number) %2 == 0"} В качестве Builder указываете Invoke Maven 3 и настраиваете ваш обычный maven-билд. Повторяете шаги 1-4, но задаете условие для нечетности: ${GROOVY,script = "(Thread.currentThread().executable.number) %2 != 0"} и запускаете maven-билд с флагом -DskipTests=true PS. У вас так же должны быть установлены Groovy Plugin и Token Macro Plugin, в настройках Jenkins должен быть включен флаг Groovy -> Allow token macro processing Слышал есть более простой способ, а именно, использовать переменную среды Jenkins - BUILD_NUMBER. По сути мы и так использовали BUILD_NUMBER, только не через переменные среды, а через API. Если хотите без обойтись без groovy в голову приходят два варианта: Вариант 2. Можно взять EnvInject Plugin и перед сборкой инжектить в переменную, скажем $RUN_TESTS, значение $(($BUILD_NUMBER % 2)), что будет давать нам либо 1 либо 0. А в переменную $DONT_RUN_TESTS соответственно противоположное значение: $((1 - $BUILD_NUMBER % 2)). Но это не избавит нас от Conditional BuildStep Plugin. Просто Token-ы поменяются на ${ENV,var='RUN_TESTS'} и ${ENV,var='DONT_RUN_TESTS'} Conditional BuildStep Plugin вообще всеядный и в качестве true рассматривает значения 1, y, yes, t, true, on, run. Вариант 3. Другой вариант - настроить в самом pom.xml файле проекта средствами maven-а профиль в котором будут глушиться тесты. Пусть он называется no-tests. Теперь все тем же EnvInject-ом заинжектим переменную окружения, например $MVN_PROFILE, которая для четных билдов пустая, а для нечетных - содержит значение -P no-tests, то есть $MVN_PROFILE должна содержат результат вычисления: $(if [[ $(($BUILD_NUMBER % 2)) -eq 0 ]]; then echo '-P no-tests'; fi )

понедельник, 10 июня 2019 г.

Как получить доступ к значению переменной, созданной внутри фигурных скобок в shell

Дано:
Код, разбивающий строку по точке и складывающий полученные части в переменные.
sh """ version='1.2.3.4'
echo \$version | { IFS=. read a b c d; echo \$a; }
echo \"a\" \$a """
При запуске получаем вот это:
+ version=1.2.3.4 + IFS=. read a b c d + echo 1.2.3.4 + echo 1 1 + echo a a
Проблема:
Из-за фигурных скобок переменные, в которых лежит нужные значения, недоступны.
Вопрос:
Каким образом получить значения переменных a, b, c, d за пределами фигурных скобок?


Ответ

А почему бы не прочитать сразу все значения в массив:
IFS='.' read -r -a arr <<< "${version}"
Результат:
[ ~]# echo ${arr[@]} 1 2 3 4 [ ~]# echo ${arr[0]} 1 [ ~]# echo ${arr[1]} 2 [ ~]# echo ${arr[2]} 3 [ ~]# echo ${arr[3]} 4
или так:
IFS='.' read -r -a a b c d <<< "${version}"

понедельник, 18 марта 2019 г.

Выполнение задач в Docker-контейнере в Jenkins

Может ли Jenkins работать так же, как GitLab Runner + Docker executor
Из образа развернуть контейнер. Внутрь контейнера клонировать репозиторий git, выполнить произвольные команды. Выделить артефакты и сохранить их вне контейнера, свернуть контейнер (завершить его работу).
Вопрос: нужна пошаговая инструкция по настройке Jenkins для выполнения трех вышеуказанных шагов.
Нашел Docker Plugin. Вроде бы он умеет разворачивать Jenkins slave в докере, подключать его к мастеру и утилизировать после использования. Этот вариант мне точно не подходит, потому что нужно тащить в сборочное окружение Java и прочие не нужные там вещи. Базовый образ jenkins-slave весит в 100 раз больше alpine, это вообще за гранью разумного.
docker images REPOSITORY ... SIZE alpine ... 3.97 MB evarga/jenkins-slave ... 368 MB
Еще нашел плагин Docker build step. Одна из фич — "create new container from image". Возможно, мне нужно именно это, но я не понимаю, как выполнить пункты 2 и 3.


Ответ

В Jenkins можно выполнить bash/batch команду, для bash это будет примерно так:
docker run -it -d my_image # запускам image в detached моде docker exec $(docker ps -a -q --filter ancestor=my_image) bash -c "cd your_path; your_command" # запускаем Вашу команду в контейнере.
list=$(docker exec $(docker ps -a -q --filter ancestor=my_image) bash -c 'ls /path/to/artifacts/inside/container') # создаем список артефактов, которые мы будем вытаскивать из контенера for i in $list; do docker cp $(docker ps -a -q --filter ancestor=my_image):$i ./path/to/outside container ; done # вытаскиваем артефакты согласно списку
for i in $(docker ps -a -q --filter ancestor=my_image); do docker rm $(docker stop $i); done # удалям контейнеры, если они работают

среда, 5 декабря 2018 г.

Как использовать возможность автоматического merge изменений сервером непрерывной интеграции?

У TeamCity есть билд фича Automatic merge. Она позволяет сделать merge изменений коммита в определенную ветку (интеграции). Каждый раз когда кто-нибудь делает коммит который проходит все тесты можно этот коммит автоматически влить в ветку интерграции и, если не получилось, выдать ошибку что при мерже возникли конфликты что позволит команде оперативно среагировать.
Вопрос: Что делать после того как оказалось что при слиянии возникли конфликты?
По идее, если программист работает в feature ветке, он должен намержить ветку на себя и разрулить конфликты. Только это не девелоп. В девелоп нельзя автоматом мержить. Не могу разобраться как эту фичу грамотно заюзать. Какие есть use-cases?


Ответ

Мне видится два варианта использования автоматического мержа:
Если вы используете фича/багфикс бранчи, но при этом в вашем процессе нет пулл-реквестов/интеграционной ветки, т.е. вы готовы сразу мержить в мастер. Это позволяет достичь изолированности изменений и их автоматической интеграции. (Хотя лично мне такая модель представляется сомнительной, особенно для достаточно больших изменений, поскольку заставляет делать локальные коммиты без пуша, а это может быть чревато.) Если вы используете интеграционный бранч, куда вливаются фича/багфикс бранчи. Изменения тестируются, а после этого вливаются в мастер.
Во втором случае интеграционный бранч по сути является копией мастера с добавленными изменениями. Поэтому при вливании в интеграционный бранч конфликты могут возникнуть по двум причинам:
изменения конфликтуют с мастером изменения конфликтуют с изменениями из другого фича/багфикс бранча, которые были влиты в интеграционную ветку, но еще не попали в мастер
В обоих случаях разруливать конфликт достаточно мержем из интеграционной ветки. Первый случай очевиден -- конфликтующие изменения из мастера есть и в интеграционной ветке. Второй случай тоже очевиден -- без "зеленой" интеграционной ветки работа дальше не пойдет. И тут действует стандартное правило -- кто последний коммитит, тот и мержит :).

идея в том чтобы обнаруживать конфликты как можно раньше.
Тогда может стоит просто добавить мерж из мастера в фича/багфикс ветку при каждом билде? Если говорить о TeamCity, то первым шагом билда добавляете следующий код:
git remote set-url origin %repo_url% if NOT %teamcity.build.branch.is_default%==true git fetch if NOT %teamcity.build.branch.is_default%==true git merge origin/master
Это гарантированно будет обнаруживать конфликты сразу. Мастер будет всегда "зеленый", вы не будете получать конфликты из-за того, что кто-то залил конфликтующие изменения в интеграционную ветку.

четверг, 25 октября 2018 г.

Jenkins. Как сделать чтобы каждый второй билд не запускал тесты?

Что нужно поменять/установить в настройках джоба(item) Jenkins, чтобы каждый второй билд не запускал тесты?


Ответ

Вариант 1
Можно поставить Conditional BuildStep Plugin - он позволяет задавать условие для выполнения отдельного шага сборки. В вашем случае таким условием является четность номера сборки.
По порядку:
Добавляете шаг Conditional step (single) в билд В качестве условия Run? выбираете Boolean condition В качестве Token задаете выражение:
${GROOVY,script = "(Thread.currentThread().executable.number) %2 == 0"} В качестве Builder указываете Invoke Maven 3 и настраиваете ваш обычный maven-билд. Повторяете шаги 1-4, но задаете условие для нечетности:
${GROOVY,script = "(Thread.currentThread().executable.number) %2 != 0"}
и запускаете maven-билд с флагом -DskipTests=true
PS. У вас так же должны быть установлены Groovy Plugin и Token Macro Plugin, в настройках Jenkins должен быть включен флаг Groovy -> Allow token macro processing

Слышал есть более простой способ, а именно, использовать переменную среды Jenkins - BUILD_NUMBER.
По сути мы и так использовали BUILD_NUMBER, только не через переменные среды, а через API.
Если хотите без обойтись без groovy в голову приходят два варианта:
Вариант 2. Можно взять EnvInject Plugin и перед сборкой инжектить в переменную, скажем $RUN_TESTS, значение $(($BUILD_NUMBER % 2)), что будет давать нам либо 1 либо 0. А в переменную $DONT_RUN_TESTS соответственно противоположное значение: $((1 - $BUILD_NUMBER % 2))
Но это не избавит нас от Conditional BuildStep Plugin. Просто Token-ы поменяются на ${ENV,var='RUN_TESTS'} и ${ENV,var='DONT_RUN_TESTS'}
Conditional BuildStep Plugin вообще всеядный и в качестве true рассматривает значения 1, y, yes, t, true, on, run Вариант 3. Другой вариант - настроить в самом pom.xml файле проекта средствами maven-а профиль в котором будут глушиться тесты. Пусть он называется no-tests. Теперь все тем же EnvInject-ом заинжектим переменную окружения, например $MVN_PROFILE, которая для четных билдов пустая, а для нечетных - содержит значение -P no-tests, то есть $MVN_PROFILE должна содержат результат вычисления:
$(if [[ $(($BUILD_NUMBER % 2)) -eq 0 ]]; then echo '-P no-tests'; fi )