Указанная в заголовке связка незначительно облегчает процесс deploy проекта, т.к. предназначена не совсем для этого. Эта связка скорее для мониторинга и трекинга работы над проектом, а так же минимальный контроль ошибок и качества. Так же в команде, которая использует Slack, удобно видеть когда были изменения от других участников.
Идея конфигурации
В качестве системы контроля версий будет использоваться Mercirial (hg). В проекте обязательно присутствуют 3 ветки – dev, staging, stable. На каждую ветку настроен свой хост на сервере. Это рекомендуемая и проверенная практика деплоя приложения. Наилучшим образом об этом написано тут – http://guides.beanstalkapp.com/deployments/best-practices.html
Основной смысл в том, что в dev деплоятся критические изменения, в staging те, что не меняют значительно проект, относильно stable. Ну а stable это то, чем пользуются пользователи, продакшн. Учитывая эту рекомендацию автодеплой с jenkins стоит настраивать только на staging. Для dev это сделать эффективно не получится, т.к. при критических изменениях по большей части приходится делать все руками. Более того на dev допустимы ошибки, а на staging, в предрелизном состоянии, уже нет.
Настройка Jenkins и ant
Для начала необходимо установить на сервер сам jenkins и ant. Моя версия jekins 2.7. Именно через конфиг ant будут описаны шаги, после выполнения которых можно будет считать, что build прошел успено.
Дальше нужно установить плагины slack, ant и bitbucket. У меня установлены следующие плагины: ant 1.2, bitbucket 1.1.0, cloverphp 0.4, cvs, git 2.3.5, git-client 1.17.1, junit 1.6, maven-plugin 2.10, mercurial 1.54, php 1.0, pmd 3.41, slack 1.8, xunit 1.96
На самом деле список гораздо больше, тут я оставил только актуальные для меня.
Далее для php проекта будет актуальна следующая ссылка с шаблоном – http://jenkins-php.org/.
Конкретно на шаге установки необходимых php инструментов и плагинов для jenkins приводится достаточно большой список. У себя в конфиге ant с названием build.xml я оставил только lint проверку на синтаксические ошибки и чуть позже мне понадобится phpunit, остальное убрано. На самом деле удобнее начинать с минимального конфига и добавлять все потом.
Так же я добавил в конфиг ant две команды на скачивание последнего composer.phar и вызов его Install и dumpautoload команд. Пример минимального конфига build.xml (без phpunit), который надо добавить в корень php проекта:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
<?xml version="1.0" encoding="UTF-8"?> <project name="project name" default="build"> <!-- By default, we assume all tools to be on the $PATH --> <property name="toolsdir" value=""/> <!-- Uncomment the following when the tools are in ${basedir}/vendor/bin --> <!-- <property name="toolsdir" value="${basedir}/vendor/bin/"/> --> <target name="build" depends="composerInstall,composerDump,lint" description="Main build"/> <target name="build-parallel" depends="lint" description="Parallel build"/> <target name="lint" unless="lint.done" description="Perform syntax check of sourcecode files"> <apply executable="php" failonerror="true" taskname="lint"> <arg value="-l"/> <fileset dir="${basedir}/module"> <include name="**/*.php"/> <modified/> </fileset> <!--<fileset dir="${basedir}/tests">--> <!--<include name="**/*.php"/>--> <!--<modified/>--> <!--</fileset>--> </apply> <property name="lint.done" value="true"/> </target> <property name="composer" value="${basedir}/composer.phar"/> <target name="php-check"> <condition property="php" value="php"> <not> <isset property="{php}"/> </not> </condition> </target> <property name="builddir" value="${basedir}/build"/> <property name="data_logs" value="${basedir}/data/logs"/> <property name="doctrine_dir" value="${basedir}/data/DoctrineORMModule"/> <property name="doctrine_dir_migrations" value="${basedir}/data/DoctrineORMModule/Migrations"/> <property name="doctrine_dir_proxy" value="${basedir}/data/DoctrineORMModule/Proxy"/> <target name="prepare"> <mkdir dir="${builddir}"/> <mkdir dir="${data_logs}"/> <mkdir dir="${doctrine_dir}"/> <mkdir dir="${doctrine_dir_migrations}"/> <mkdir dir="${doctrine_dir_proxy}"/> <chmod dir="${builddir}" perm="777" failonerror="true"/> <chmod dir="${data_logs}" perm="777" failonerror="true"/> <chmod dir="${doctrine_dir}" perm="777" failonerror="true"/> <chmod dir="${doctrine_dir_migrations}" perm="777" failonerror="true"/> <chmod dir="${doctrine_dir_proxy}" perm="777" failonerror="true"/> </target> <target name="composer-check" depends="prepare"> <available file="${composer}" property="composer.present"/> </target> <target name="composer-download" depends="composer-check" unless="composer.present"> <property name="composer.noselfupdate" value="true"/> <get src="https://getcomposer.org/composer.phar" dest="${composer}"/> </target> <target name="composer-selfupdate" depends="php-check,composer-download" unless="composer.noselfupdate"> <exec executable="${php}"> <arg value="${composer}"/> <arg value="self-update"/> <arg value="--quiet"/> </exec> </target> <target name="composerInstall" depends="composer-selfupdate" unless="composer.noupdate" description="Run composer update"> <exec executable="${php}" failonerror="true"> <arg value="${composer}"/> <arg value="install"/> </exec> </target> <target name="composerDump" depends="composerInstall" description="Run composer dump-autoload"> <exec executable="${php}" failonerror="true"> <arg value="${composer}"/> <arg value="dump-autoload"/> <arg value="-o"/> </exec> </target> </project> |
Необходимо установить проект-шаблон в jenkins и как это сделать описано тут. В итоге проект php-template появится на главной странице jenkins.
Теперь на основе этого шаблона можно создать проект в jenkins под свой php проект, путем выбора “copy exiting project” при создании нового проекта и выбора там php-template. После чего зайти в конфигурацию созданного проекта и удалить там лишнее и настроить что нужно.
В глобальной конфигурации jenkins необходимо настроить конфигурации инсталяций для ant и mercurial (или git). Они уже должны быть установлены на сервере и тут необходимо только прописать пути к исполняющимся файлам и домашним директориям. В разделе конфигурации slaсk можно прописать название домена команды (только приставка, без slack.com) и адрес, по которому доступен jenkins на внешку, например ip/8080.
В конфигурации безопасности необходимо во первых включить безопаность, далее поставить галочки на Jenkins’ own user database и Allow users to sign up, и ниже один из вариантов Anyone can do anything или Logged-in users can do anything. Конечно если веб интерфейс доступен на внешку, то подойдет только второй вариант, в случае если он доступен только на разрешенный ip удобнее работать при первом варианте.
Теперь нужно создать пользователя. Его нужно создать в любом случае, т.к. именно api токен этого пользователя будет использовать bitbucket для инициализации билда проекта. Перейдя на вкладку People создать пользователя и нажать Show api token. Можно скопировать заранее куда-то. В моем случае будет такое
user – abrakadabrausertoken
Подготовка проекта в Jenkins
В проекте Jenkins, который создан как копия от шаблона php-template, в настройках нужно сделать следующее:
- Нужно ввести настройки для репозитория git или hg. Основные настройки это адрес репозитория и данные для авторизации. Проще использовать https способ, а не ssh. Тут же нужно указать staging ветку.
- В разделе Build Triggers нужно включить Triggers builds remotely и придумать или сгенерировать токен в поле ниже. Я буду использовать abrakadabraprojecttoken.
- Для slack можно сразу заполнить имя домена команды в Advanced и установить галочки на какие события должны быть уведомления. У меня стоят все кроме Build Start.
Перед тестом нужно еще убедится, что в настройках Deployment keys добавлен id_rsa.pub ключ с сервера. Его нужно взять так с директории пользователя, под которым jenkins будет деплоить проект:
1 2 3 |
cat ~/.ssh/id_rsa.pub |
Теперь можно запустить билд проекта в jenkins вручную. В процессе репозиторий должен склонироваться, а build.xml должен быть выполнен через ant. При возникновении проблем нужно смотреть Console log в информации билда и гуглить по позникшим ошибкам.
Интеграция с Bitbucket
Есть 2 способа интеграции: через service и через webhook. Второй способ реализауется с помощью bitbucket plugin, первый же делается нативно без плагина. Я настраиваю по первому способу, но, скорее всего bitbucket в будущем закроет service интеграцию, поэтому придется перейти на webhook.
Чтобы использовать данные пользователя в bitbucket интеграции нужно сформировать строку подключения вида
http://<user>:<user token>@<jenkins ip or host>/
Например http://user:abrakadabrausertoken@ip:8080/
Теперь в bitbucket нужно перейти в настройки репозитория проекта, далее в сервисы (services), нажать на добавление нового и выбрать jenkins. Будут предложены следующие поля
Endpoint (точка входа) – сюда пишется сформированная строка подключения
Project name – имя проекта, точь в точь как назван проект в jenkins, например MyProjectCI
Token – тот токен, который был прописан на этапе подготовки проекта (abrakadabraprojecttoken)
Module name – я эту фичу не использую.
Готово. Можно попробовать создать тестовый файл в корне проекта и запушить изменения в репозиторий. В jenkins должен будет запустится билд проекта. Будет выполнено все то же самое, что и при ручном запуске.
Интеграция с Slack
Теперь хочется чтобы при билде проекта в slack канале было видно это событие и его статус. На шагах выше уже был установлен плагин. Осталось только создать канал и получить token для канала.
Находясь в интерфейсе своей команды нужно перейти в настройках в раздел Apps & Integrations, тут выбрать Jenkins. Далее configure->create configuration. Далее будет предложено выбрать или создать канал. Создаем новый private канал с названием, например, myproject_builds, добавляем в него участников. Теперь канал выбран и жмем на Add Jenkins Integration. Появится окно настроек, где ничего не надо менять, а только скопировать токен, например abrakadabraslacktoken.
Этот токен и нужно прописать в настройках проекта Jenkins в разделе Advanced для slack и там же прописать имя созданного канала, которое должно начинаться с #.
Кликнув кнопку test connection должно придти сообщение в соответствующий канал о том, что настройка успешна.
А если теперь запушить изменения в bitbucket, то после удачного или неудачного завершения билда в Jenkins, в Slack придет сообщение success или failure соответственно.
В конце хочу привести ссылку на статью, которая помогла мне вначале – http://felixleong.com/blog/2012/02/hooking-bitbucket-up-with-jenkins.