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

210

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

Есть ли способ выполнить их локально без фиксации кода?

Сорин
источник

Ответы:

139

Вы не можете выполнить сценарий конвейера локально, так как его цель - сценарий Jenkins. (Это одна из причин, по которой лучше придерживаться Jenkinsfileкраткого и ограниченного кода, который фактически имеет дело с функциями Jenkins; ваша фактическая логика сборки должна обрабатываться внешними процессами или инструментами сборки, которые вы вызываете через одну строку shили batшаг.)

Если вы хотите , чтобы проверить изменения , чтобы Jenkinsfileжить , но не совершая его, использовать в Replay функцию добавляемые в 1.14

JENKINS-33925 отслеживает желаемое для автоматизированного тестового фреймворка.

Джесси Глик
источник
В сообщении блога говорится, что есть кнопка «Повторить». Есть идеи где? Я не могу найти это.
BoltzmannBrain
8
@BoltzmannBrain, перейдите на страницу Jenkins вашей работы по сборке. С левой стороны вы должны увидеть список предыдущих запусков сборки. При наведении курсора на идентификатор прогона сборки (например, «# 123») или на дату прогона сборки появляется небольшая стрелка вниз. При нажатии на него открывается контекстное меню, в котором есть опция «Воспроизвести». Опция также доступна на странице запуска сборки.
Спокойной ночи Nerd Pride
2
Concourse позволяет вам выполнять локальные сценарии на целевом сервере сборки, поэтому вы можете проверить, действительно ли он будет работать и на удаленном сервере, прежде чем вносить изменения. concourse.ci/fly-cli.html . Функция воспроизведения Jenkins в некоторой степени аналогична этому, за исключением того, что она имеет ограничения, и для ее воспроизведения необходимо сначала создать сборку.
mdo123
2
Вы можете взглянуть на этот проект , целью которого является предоставление того, что вы ищете.
Ромен
1
Взгляните на JenkinsPipelineUnit ( github.com/jenkinsci/JenkinsPipelineUnit )
user864279
79

У меня есть решение, которое хорошо работает для меня. Он состоит из локального jenkins, работающего в докере, и веб-хука git для запуска конвейера в локальном jenkins при каждом коммите. Вам больше не нужно нажимать на свой github или репозиторий bitbucket, чтобы протестировать конвейер.

Это было проверено только в среде Linux.

Сделать это довольно просто, хотя эта инструкция немного длинна. Большинство шагов там.

Это то, что вам нужно

  • Докер установлен и работает. Это не является частью этой инструкции.
  • Дженкинс работает в докере локально. Объяснил как ниже.
    • Правильные права доступа (ssh-ключ) для вашего локального пользователя докера Jenkins для извлечения из вашего локального репозитория git. Объяснил как ниже.
    • Проект конвейера Jenkins, который извлекается из вашего локального репозитория git. Объясняется ниже.
    • Пользователь git в вашем местном Jenkins с минимальными правами. Объясняется ниже.
  • Git-проект с веб-хуком пост-фиксации, который запускает конвейерный проект. Объясняется ниже.

Вот как ты это делаешь

Дженкинс Докер

Создайте файл с именем Dockerfile на месте вашего выбора. Я помещаю это в /opt/docker/jenkins/Dockerfileзаполнить это этим:

FROM jenkins/jenkins:lts
USER root
RUN apt-get -y update && apt-get -y upgrade
# Your needed installations goes here
USER jenkins

Создайте образ local_jenkins

Это вам нужно будет сделать только один раз или после добавления чего-либо в Dockerfile.

$ docker build -t local_jenkins /opt/docker/jenkins/

Запустите и перезапустите local_jenkins

Время от времени вы хотите легко запустить и перезапустить jenkins. Например, после перезагрузки вашей машины. Для этого я сделал псевдоним, который я положил .bash_aliasesв мою домашнюю папку.

$ echo "alias localjenkinsrestart='docker stop jenkins;docker rm jenkins;docker run --name jenkins -i -d -p 8787:8080 -p 50000:50000 -v /opt/docker/jenkins/jenkins_home:/var/jenkins_home:rw local_jenkins'" >> ~/.bash_aliases
$ source .bash_aliases  # To make it work

Убедитесь, что /opt/docker/jenkins/jenkins_homeпапка существует и у вас есть права на чтение и запись для нее.

Чтобы запустить или перезапустить свой Jenkins, просто наберите:

$ localjenkinsrestart

Все, что вы делаете в своем локальном jenkins, будет храниться в папке / opt / docker / jenkins / jenkins_home и сохраняться между перезапусками.

Создайте ssh ключ доступа в вашем докере

Это очень важная часть, чтобы это работало. Сначала мы запускаем docker-контейнер и создаем для него оболочку bash:

$ localjenkinsrestart
$ docker exec -it jenkins /bin/bash

Теперь вы вошли в Docker-контейнер, это вы можете увидеть чем-то вроде jenkins@e7b23bad10aa:/$вашего терминала. Хеш после @ наверняка будет отличаться.

Создать ключ

jenkins@e7b23bad10aa:/$ ssh-keygen

Нажмите ввод по всем вопросам, пока не получите ответ

Скопируйте ключ на свой компьютер. Если вы хотите знать, что внутри контейнера Docker ваш компьютер 172.17.0.1.

jenkins@e7b23bad10aa:/$ ssh-copy-id user@172.17.0.1

user = ваше имя пользователя, а 172.17.0.1 - это IP-адрес вашего компьютера из контейнера Docker.

Вы должны будете ввести свой пароль на этом этапе.

Теперь давайте попробуем завершить цикл, выполнив команду ssh на вашем компьютере из контейнера Docker.

jenkins@e7b23bad10aa:/$ ssh user@172.17.0.1

На этот раз вам не нужно вводить пароль. Если вы это сделаете, что-то пошло не так, и вы должны попробовать еще раз.

Теперь вы будете в домашней папке вашего компьютера. Попробуйте lsи посмотрите.

Не останавливайтесь на достигнутом, так как у нас есть цепочка ssh-оболочек, из которых мы должны выйти.

$ exit
jenkins@e7b23bad10aa:/$ exit

Правильно! Теперь мы вернулись и готовы продолжить.

Установите свой Дженкинс

Вы найдете свой местный Jenkins в вашем браузере по адресу http: // localhost: 8787 .

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

Настройте свои Дженкинс

Это очень важно , что вы активируете безопасность на основе матрицы на HTTP: // локальный: 8787 / configureSecurity и дать себе все права , добавив себя в матрицу и отметьте все ящики. (В крайнем правом углу есть значок галочки)

  • Выберите в Jenkins’ own user databaseкачестве области безопасности
  • Выберите Matrix-based securityв разделе Авторизация
  • Введите свое имя пользователя в поле User/group to add:и нажмите на [ Add ]кнопку
  • В таблице выше ваше имя пользователя должно появиться рядом со значком людей. Если он пересекается, вы ввели неверное имя пользователя.
  • Перейдите в крайний правый угол таблицы и нажмите кнопку с галочкой или вручную отметьте все поля в своем ряду.
  • Пожалуйста, убедитесь, что флажок Prevent Cross Site Request Forgery exploitsснят. (Так как этот Дженкинс доступен только с вашего компьютера, это не такая уж большая проблема)
  • Нажмите [ Save ]и выйдите из Jenkins и войдите снова, чтобы убедиться, что это работает. Если это не так, вы должны начать сначала и очистить /opt/docker/jenkins/jenkins_homeпапку перед перезапуском

Добавьте пользователя git

Нам нужно разрешить нашему git hook подключиться к нашему локальному Jenkins с минимальными правами. Достаточно просто посмотреть и построить рабочие места. Поэтому мы создаем пользователя gitс паролем login.

Перейдите в браузере по адресу http: // localhost: 8787 / securityRealm / addUser и добавьте его gitкак имя пользователя и loginпароль. Нажмите на [ Create User ].

Добавьте права пользователю git

Перейдите на страницу http: // localhost: 8787 / configureSecurity в вашем браузере. Добавьте пользователя git в матрицу:

  • Напишите gitв поле User/group to add:и нажмите на[ Add ]

Теперь пришло время установить флажки для минимальных прав пользователя git. Только это необходимо:

  • в целом: читать
  • работа: сборка
  • Работа: открыть
  • работа: чтение

Убедитесь, что Prevent Cross Site Request Forgery exploitsфлажок снят, и нажмите[ Save ]

Создать проект конвейера

Мы предполагаем, что у нас есть имя пользователя, userи наш проект с поддержкой git, Jenkinsfileв котором он называется, projectнаходится по адресу/home/user/projects/project

В ваш http: // localhost: 8787 Jenkins добавьте новый конвейерный проект. Я назвал это крючком для справки.

  • Нажмите New Itemв меню Дженкинс
  • Назовите проект hookpipeline
  • Нажмите на трубопровод
  • щелчок [ OK ]
  • Установите флажок Poll SCMв разделе «Построение триггеров». Оставьте расписание пустым.
  • В разделе Трубопровод:
    • Выбрать Pipeline script from SCM
    • в Repository URLполе введитеuser@172.17.0.1:projects/project/.git
    • в Script Pathполе введитеJenkinsfile
  • Сохранить проект Hookpipeline
  • Создайте соединительную линию вручную один раз, это необходимо для работы SCM опроса.

Создайте git hook

Перейдите в /home/user/projects/project/.git/hooksпапку и создайте файл с именем, post-commitкоторый содержит это:

#!/bin/sh
BRANCHNAME=$(git rev-parse --abbrev-ref HEAD)
MASTERBRANCH='master'

curl -XPOST -u git:login http://localhost:8787/job/hookpipeline/build
echo "Build triggered successfully on branch: $BRANCHNAME"

Сделайте этот файл исполняемым:

$ chmod +x /home/user/projects/project/.git/hooks/post-commit

Протестируйте хук после фиксации:

$ /home/user/projects/project/.git/hooks/post-commit

Проверьте в Дженкинсе, был ли запущен ваш проект ловушки.

Наконец, внесите некоторые произвольные изменения в ваш проект, добавьте изменения и сделайте коммит. Теперь это вызовет конвейер в вашем местном Jenkins.

Счастливые дни!

javabeangrinder
источник
Я должен был заменить docker build -t local_jenkins /opt/docker/jenkins/Dockerfileс , docker build -t local_jenkins /opt/docker/jenkinsпотому что Docker жаловался «не в состоянии подготовить контекст: контекст должен быть каталог».
Этьен Неве
1
Я получаю эту ошибку в Mac. Может кто-нибудь, пожалуйста, помогите мне в этом? >> ОШИБКА: ssh: подключиться к хосту 172.17.0.1 порт 22: соединение отказано -
Манодж Шреста
@ManojShrestha: ip 172.17.0.1 - это ip по умолчанию для компьютера, на котором запущены контейнеры Docker. Вместо этого вы можете использовать ip своих машин (MAC: s).
javabeangrinder
@ManojShrestha: Вы также можете попытаться выяснить IP-адрес шлюза вашей установки следующим образом: $ docker inspect jenkins | grep Gateway
javabeangrinder
2
Если ваш хост докера установлен на macOS и вы хотите ssh войти в него из контейнера докера, вам следует ssh user@docker.for.mac.localhost вместо использования IP-адреса. Также убедитесь, что вы включили функцию удаленного входа в Системные настройки macOs -> Меню общих папок
Paolo Angioletti
61

TL; DR

Длинное
тестирование Jenkins Pipeline становится все более и более болезненным. В отличие от классического подхода к декларативному конфигурированию заданий, в котором пользователь был ограничен тем, что пользовательский интерфейс предоставил, новый Jenkins Pipeline является полноценным языком программирования для процесса сборки, в котором вы смешиваете декларативную часть со своим собственным кодом. Как хорошие разработчики, мы хотим провести некоторые модульные тесты и для этого вида кода.

Есть три шага, которые вы должны выполнить при разработке Jenkins Pipelines. Шаг 1. должен охватывать 80% случаев использования.

  1. Делайте как можно больше в скриптах сборки (например, Maven, Gradle, Gulp и т. Д.). Тогда в ваших конвейерных скриптах просто вызывайте задачи сборки в правильном порядке. Конвейер сборки просто организует и выполняет задачи сборки, но не имеет какой-либо серьезной логики, требующей специального тестирования.
  2. Если предыдущее правило не может быть применено полностью, перейдите к библиотекам Pipeline Shared, где вы можете самостоятельно разрабатывать и тестировать собственную логику и интегрировать ее в конвейер.
  3. Если все вышеперечисленное не сработает, вы можете попробовать одну из тех библиотек, которые появились недавно (март-2017). Среда тестирования Jenkins Pipeline Unit или pipeUnit (примеры). С 2018 года существует также Jenkinsfile Runner , пакет для выполнения конвейеров Jenkins из инструмента командной строки.

Примеры

PipelineUnit репо GitHub содержит некоторые примеры Спок о том , как использовать тестирование базы Дженкинс трубопровода Unit

Vadimo
источник
1
Можете ли вы также включить краткое сравнение этих двух библиотек?
сорин
24

В Jenkins есть функция «Воспроизведение», которая позволяет быстро воспроизвести задание без обновления источников:

Функция воспроизведения

AhmedDrira
источник
1
Обратите внимание, что он отображается на странице сборки, а не на странице проекта или ветви.
ArtOfWarfare,
17

На момент написания (конец июля 2017 г.) с помощью плагина Blue Ocean вы можете проверить синтаксис декларативного конвейера непосредственно в визуальном редакторе конвейера . Редактор работает из пользовательского интерфейса Blue Ocean, когда вы нажимаете «настроить» только для проектов github (это известная проблема, и они работают, чтобы она работала также на git и т. Д.).

Но, как объясняется в этом вопросе, вы можете открыть редактор, перейдя по ссылке:

[Jenkins URL]/blue/organizations/jenkins/pipeline-editor/

Затем нажмите в середине страницы и нажмите Ctrl+S, это откроет текстовую область, где вы можете вставить конвейерный декларативный скрипт. Если вы нажмете « Обновить» , если возникнет синтаксическая ошибка, редактор сообщит вам, где находится синтаксическая ошибка. Как на этом скриншоте:

В качестве быстрого теста я ошибочно набрал «stepps» вместо «steps»

Если нет синтаксической ошибки, текстовое поле закроется, и страница отобразит ваш конвейер. Не волнуйтесь, это ничего не спасет (если это github-проект, он внесет изменение Jenkinsfile).

Я новичок в Дженкинс, и это очень полезно, без этого мне приходилось фиксировать Jenkinsfile много раз, пока он не работал (очень раздражает!). Надеюсь это поможет. Приветствия.

firepol
источник
2
Это потому, что с 2017 года Дженкинс по-прежнему нацелен на решение проблем программных инженеров "укажи и щелкни";) .... По крайней мере, у Atom есть достойный Groovy linter. Это только Groovy, но это помогает.
сорин
Редактор с подсветкой синтаксиса также является частью классического пользовательского интерфейса jenkins.
Вадимо
6

Немного опоздал на вечеринку, но именно поэтому я написал jennyнебольшую повторную реализацию некоторых основных шагов Jenkinsfile. ( https://github.com/bmustiata/jenny )

bogdan.mustiata
источник
Без обид, но если вы не будете постоянно обновлять свои материалы, это будет довольно бесполезно, так как синтаксис конвейера находится в состоянии постоянного изменения, как кажется на данный момент.
Крад
Не принято Из того, что я видел до сих пор, синтаксис конвейера, он в значительной степени стандартизирован для основных шагов конвейера ( jenkins.io/doc/pipeline/steps/workflow-basic-steps ). Я использую его в течение ~ 2 лет, не сталкиваясь с какими-либо несовместимыми изменениями. Плагины Jenkins не должны использоваться imho, а изменяющийся API можно абстрагировать с помощью пользовательских команд в общих библиотеках, где у вас будут гарантии API. Если вы говорите о декларативном синтаксисе, это может быть правдой. Я использую только программный API в своих конвейерах, и это то, что поддерживает Дженни. Твердый рок :)
bogdan.mustiata
5

Насколько я знаю, этот Pipeline Plugin является «движком» новой механики Jenkinsfile, поэтому я вполне уверен, что вы можете использовать его для локального тестирования ваших сценариев.

Я не уверен, есть ли какие-либо дополнительные шаги, необходимые при копировании его в файл Jenkinsfile, однако синтаксис и т. Д. Должны быть точно такими же.

Редактировать: Нашли ссылку на «движок», проверьте описание этой функции, последний абзац, первую запись.

Доминик Гебхарт
источник
5

В моей настройке разработки - без правильного редактора Groovy - большая часть проблем Jenkinsfile возникает из-за простых синтаксических ошибок . Чтобы решить эту проблему, вы можете проверить Jenkinsfile по вашему экземпляру Jenkins (работает на $JENKINS_HTTP_URL):

curl -X POST -H $(curl '$JENKINS_HTTP_URL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)') -F "jenkinsfile=<Jenkinsfile" $JENKINS_HTTP_URL/pipeline-model-converter/validate

Приведенная выше команда является слегка измененной версией из https://github.com/jenkinsci/pipeline-model-definition-plugin/wiki/Validating-(or-linting)-a-Declarative-Jenkinsfile-from-the-command-line

Юусо Охтонен
источник
4
Это именно то, что я искал - к сожалению, это работает только для декларативных конвейеров, а не для скриптовых конвейеров :(
thom_nic
2

Помимо функции воспроизведения, о которой уже упоминали другие (то же самое относится и к ее полезности!), Я также обнаружил, что полезно следующее:

  1. Создайте тестовое задание конвейера, в котором вы можете ввести код конвейера или указать свой репозиторий / филиал Jenkinsfile, чтобы быстро что-то проверить. Для более точного тестирования используйте многоотраслевой конвейер, который указывает на ваш собственный форк, где вы можете быстро вносить изменения и фиксировать, не влияя на продукт. Такие вещи, как BRANCH_NAME env доступны только в Multibranch.
  2. Поскольку Jenkinsfile - это код Groovy, просто вызовите его с помощью «groovy Jenkinsfile» для проверки основного синтаксиса.
Макс Чжэн
источник
Использование отдельных заданий, которые вы можете скрыть и не запутать своих пользователей, является одной из самых важных вещей. Я редактирую файлы Jenkins с IntelliJ. Это неплохо показывает ошибки синтаксиса. Тем не менее, кнопка ответа является ключевым моментом. Я создаю ветку с основным прогоном изменений, который - обычно идет немного не так. Затем я редактирую Jenkinsfile, копирую и вставляю его в окно воспроизведения и запускаю снова - повторяю это до тех пор, пока он не заработает, а затем фиксирую рабочую версию.
Джонфо
2

Поместите свой SSH-ключ в свой профиль Jenkins, затем используйте декларативный линтер следующим образом:

ssh jenkins.hostname.here declarative-linter < Jenkinsfile

Это сделает статический анализ вашего Jenkinsfile. В редакторе по вашему выбору определите сочетание клавиш, которое автоматически запускает эту команду. В Visual Studio Code, который я использую, перейдите в Задачи> Настроить задачи, затем используйте следующий JSON для создания команды Validate Jenkinsfile :

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Validate Jenkinsfile",
      "type": "shell",
      "command": "ssh jenkins.hostname declarative-linter < ${file}"
    }
  ]
}
Хендрик М Халков
источник
0

Я использую будущее воспроизведения, чтобы сделать некоторые обновления и запустить быстро.

AhmedDrira
источник
1
Можете ли вы предоставить больше информации о том, как вы делаете эту работу?
Косник
1
Я использую Bit-bucket в качестве менеджера исходного кода, затем я создал проект на Jenkins, хочу автоматически обнаруживать мой репозиторий, рекомендую этот пост. После каждого нажатия на мой репозиторий Jenkins будет автоматически воспроизводить мой файл Jenkins, и в случае его сбоя в левом меню есть кнопка Replay, ==> эта кнопка открывает редактор, содержащий ваш файл Jenkins, вы можете редактировать его и воспроизводить задание. ,
АхмедДрира
0

С некоторыми ограничениями и для скриптовых конвейеров я использую это решение:

  1. Конвейерная работа со встроенным шпунтовым скриптом:

node('master') {
    stage('Run!') {
                def script = load('...you job file...')
    }
}

  1. Jenkinsfile для тестирования имеет ту же структуру, что и для lesfurets:

def execute() {
 ... main job code here ...
}
execute()
user3148458
источник