Следующие три стадии уже непосредственно используют подключенный к проекту shell gitlab-runner, поэтому в них блок tags уже носит не декоративный характер, а действительно используется gitlab для выбора, на каком именно runner запускать текущую стадию. Прежде чем продолжать, следует привести файл build.gradle приложения. Так будет удобнее делать пояснения к отдельным стадиям. Конкретно на данной стадии нас интересуют строка id 'com.google.cloud.tools.jib' version '3.3.0' Это ничто иное, как подключение специального плагина, который позволяет создать из проекта docker-образ вашего приложения и поместить его в локальное хранилище. После установки плагина у вас появятся новые таски в gradle, одна из которых используется для этой операции: Разумеется, вы можете воспользоваться этой таской для того, чтобы локально вручную запускать сборку образа в локальное хранилище, причем при каждом запуске будет собираться новая версия образа, что можно увидеть по изменению хэша образа с одним и тем же именем, под которым вы его собираете. Но для нас это будет разрыв пайплайна для одной ручной операции, в то время как вполне можно запустить любую таску gradle прямо из пайплайна, оформив это, как отдельную стадию. Вот пример того, как это можно сделать (добавим новую стадию к предыдущей): Обратите внимание, что во второй стадии отсутствует секция image - в этом случае gitlab не будет создавать среду исполнения стадии "у себя", а обратится к зарегистрированным для этого проекта runner и выберет из них именно тот, который имеет тэг feature, и попытается запустить стадию на нем. Если это shell runner, то стадия будет выполняться в терминале сервера, на котором runner зарегистрирован, под специальной учетной записью gitlab-runner, автоматически создаваемой при регистрации. Здесь следует отметить, что нужно внимательно следить за тем, чтобы не возникало конфликтов runner, зарегистрированных для проекта - а именно, советую делать так, чтобы тэги не пересекались, то есть каждый уникальный тэг имелся только у одного runner (что не запрещает одному runner иметь несколько разных тегов, если это зачем-то нужно), если пересекающихся по тэгам раннеров больше одного, насколько мне известно, gitlab пайплайн вполне может запуститься, но выберет тэг для исполнения стадии случайным образом. Поэтому лучше не экспериментируйте, и следите за этим моментом строго. Для настройки следующей стадии нам потребуется helm chart для того, чтобы было удобно развертывать и, при необходимости, уничтожать тестовые стенды в kubernetes всякий раз, когда нам это нужно. Хотя это и уводит немного в сторону, сделаем краткое отступление о том, как я это делал. Очень часто java-разработчики (и не только) в процессе работы создают для удобства файл docker-compose.yml с набором взаимосвязанных сервисов, необходимых для отладки и тестирования приложения. Например, нужна база данных, нужно поднять миграции в приложении для нее, нужно провести после этого модульное тестирование и так далее. Затем может потребоваться перенести всю эту конструкцию в kubernetes. Кто-то имеет большой опыт и пишет деплойменты "на лету". Для меня же удобнее оказалось воспользоваться helm, а деплойменты сконвертировать из docker-compose.yml файла при помощи удобного средства kompose https://kompose.io/getting-started/. В частности, я воспользовался командой: kompose -f docker-compose.yml convert -c После создания чарта helm можно воспользоваться им для развертывания стендов - хоть тестировочных, хоть продуктовых, как вам угодно. И разумеется, поскольку это все выполняется консольными командами, почему бы не использовать их в очередной стадии, что я и сделал. Вот как это выглядит: Чтобы было понятнее содержание скрипта, приведу скриншот структуры моего helm чарта: Не углубляясь в детали, скажу, что в нем используются шаблоны с подстановками, которые позволяют создавать отдельные конфигурации в разных namespace, если задать соответствующие входные параметры для команды helm. Например, на этой стадии мы создаем отдельный набор подов для моего приложения командой: helm install docker-compose-feature docker-compose --namespace=yamangulov-feature --values=docker-compose/values-yamangulov-feature.yaml То есть в данном случае мы создаем чарт с именем docker-compose-feature из шаблона чарта docker-compose в пространстве имен yamangulov-feature, подгружая при этом дополнительный файл values-yamangulov-feature.yaml, содержащий дополнительные значения переменных для шаблона именно в этом namespace. Поскольку содержание шаблона чарта и чартов может быть интересным и полезным для многих, а также для изложения некоторых планируемых стадий пайплайна, приведу его содержание полностью. Теперь, если мы запустим пайплайн (для этого достаточно внести какое-то изменение в проект и запушить его в gitlab), мы увидим, как выполняются все стадии одна за другой. Выглядит это примерно так: зеленым цветом отмечаются успешно пройденные стадии пайплайна, красным - ошибки, после чего пайплайн останавливается, коричневый цвет с восклицательным знаком - особые стадии с некритическими ошибками, в которых пайплайн не останавливается, а переходит в выполнению следующей стадии несмотря на возникновение ошибок (это нам пригодится чуть позже) Теперь, если мы проверим kubernetes, мы увидим наш развернутый в нужном namespace чарт: Ну вот, казалось бы, все нормально, стенд для тестирования фичи развернут, и его можно предоставить тестировщикам для проверки развернутого приложения. И действительно это так, но только на первый взгляд все в порядке. А теперь давайте представим себе, что тестирование показало какие-то недостатки и проект возвращен на доработку. Разработчик исправил недостатки и снова запушил проект в gitlab. Пайплайн запустился на выполнение снова, и тут вы увидите, что он вываливается с ошибкой! В логе ошибки кубер сообщает вам что такой чарт уже существует и отказывается создавать его заново. Ага, вы меняете команду следующим образом: helm upgrade docker-compose-feature docker-compose --install --namespace=yamangulov-feature --values=docker-compose/values-yamangulov-feature.yaml то есть вы указываете helm обновить чарт, если он существует и создать заново, если он не существует. Должно работать, но в данном случае не работает. Вы снова получите ошибку, и содержание ее расскажет вам, что при выполнении команды helm upgrade не удается пересоздать уже созданные ingress хосты с определенными именами в предыдущем запуске чарта. Существует вот такая особенность helm и мы ее обнаружили. Чтобы решить эту проблему, самый простой и очевидный способ - вставить перед стадией развертывания стадию удаления нашего чарта при условии, если чарт существует и был ранее установлен - вот тогда гарантированно удаляются созданные ingress хосты вместе с остальными элементами чарта, то есть чарт удаляется абсолютно полностью начисто, что нам и нужно для чистоты свежего развертывания, чтобы не осталось никаких следов от предыдущего. Вот так теперь будет выглядеть наш исправленный пайплайн: Здесь команда helm uninstall docker-compose-feature --namespace=yamangulov-feature как раз и служит для полного предварительного удаления чарта перед его новой установкой, если он уже существовал. В стадии feature-clean-stand есть еще одна особенность - если стенд НЕ существовал на момент ее выполнения, то уже УДАЛЕНИЕ стенда вываливается с ошибкой, в результате чего обычная стадия остановит весь пайплайн, что нам совсем не нужно. Поэтому в стадию добавлена опция allow_failure: true которая как раз и заставит стадию работать так, как нам нужно. Если стенд уже был удален ранее (например, DevOps "пошалил" и удалил его вручную, либо же пайплайн запускается в самой первой итерации при разработке фичи, когда стенд вообще еще ни разу не создавался), при ошибке мы увидим в пайплайне как раз тот самый коричневый цвет с восклицательным знаком, и пайплайн спокойно перейдет к следующей стадии без остановки. В продолжении статьи будет рассказано о том, как я делал стадии для выполнения тестов в sonarqube, smoke и регрессионного тестирования Также рекомендую к посещению два бесплатных урока от OTUS, которые пройдут уже совсем скоро: 2 ноября. "Scope бинов в Spring". Расскажем, какие бывают Scope и для чего они могут понадобится. На примере проследим как работает Scope "Request", и, если успеем, разберем создание своего собственного Scope. Зарегистрироваться. 9 ноября. "Spring Actuator". В процессе занятия пройдёмся по метрикам и конечным точкам для работы с приложением. Ощутим мощь актуатора и даже напишем свой "индикатор здоровья". Зарегистрироваться.  Software development engineer / Data engineer