In this article we will describe what CI/CD means and overview CI/CD workflows, which can be implemented with werf.

Let’s define the main goal of using CI/CD for some project: deliver application code changes to the end user as fast as possible. CI/CD consists of 2 parts: CI means continuous integration of application code changes into main code base, and CD means continuous delivery of these changes to the end user.

Firstly some basic terms like environment and workflow are defined, then workflow building blocks are defined and then there is a description of ready-to-use workflows, which can be constructed using provided workflow building blocks.

It is recommended also to read one the following guides about CI/CD configuration for needed CI/CD system:

Basics

NOTICE: In the following text term “git” can be interpreted as a common name for any version control system, but werf supports only git version control system. It is supposed that reader is familiar with the following terms related to the git: branch, tag, master, commit, merge, rebase, fast-forward merge, git push-force procedure. It is recommended to get to know with these terms for full understanding of this article.

Environment

Production

Real users interact with application in production environment. This is also the target environment for all application code changes, which are made by application developers.

There are also so called production-like environments. Production-like environment is separate from production, but have the same configuration of hardware and software, network infrastructure, operation system, software versions, etc. In real world there may be some differences though, but each project defines own accetable risks related to the difference between production-like and production environments. Example of production-like environments: staging and testing.

Staging

Staging is a production-like environment which serves as a playground to check your application before deploying to production. Staging is also the place to test new business function by managers, testers and client customers. Real users do not interact with staging environment.

In the case when your application uses some external services, then staging typically is the only environment (besides production itself) which uses the same external services APIs and versions as production does.

Testing

Testing is a production-like environment which have the following goal: reveal problems which will occur with the new version of application in the production environment. Some long-running application tests may use this environment to implement full fledged application testing in production-like environment. The more difference between testing and production environments the more risks to deploy application with bugs to the production environment. That’s why it is recomended to have production-like environment as similar to production as possible (same software versions, libraries, operating system, IP-addresses and ports, hardware etc.).

Review

Dynamical (temporary) environment which used by an application developers to check newly written code and perform such experiments that are not allowed in production-like environmnets.

It is possible to dynamically create arbitrary number of review environments (as resources permit). Application developer usually creates and terminates such environment using CI/CD system. Also review environment could be removed automatically when some time of inactivity passed.

Releases and CI/CD

Release — is a prepared application version that contains some changes since previous application release.

In waterfall model releases are rare (monthly, half-early, early, …) and each release usually contains big blob of changes. Deployment of such release is also a rare and special event. Developers team working hard to make new version work and fix new bugs. Usually this is separate and very important stage of development process. And while this stage is active no more new features for the user will be made (even if some of developers implement new cool feature instead of debugging new release — this feature will only be available after next release). New application version contains many changes and was not tested in real life yet. So the probability that new version will perform well is very low (even if application uses automatic tests). Application users are also suffer during this stage.

On the contrary, releases contain small portions of changes and releases are frequent in CI/CD practice. Developers are encouraged to implement new features in such a way so it is possible to instantly check and use new version in production-like or production environment. Moreover developers who are inspired by this approach usually want to push and check their newly written code to the production-like and production as fast as possible and then it is easier to perform new changes on top of previous changes, which have been proved to work well. Only code that is written and used in production can be considered as working.

The important moment to implement a real CI/CD process is to deploy new code to production-like environment (staging, testing or production itself) fast and early. Typical antipattern of CI/CD practice is to deploy to production-like or production environment many accumulated changes in the source code. In other words use something resembling waterfall model on top of components designed to implement CI/CD practice. Такое может происходить из-за неправильной организации управления проектом, в которой разработчикам не позволяется выкатывать на production-like окружения без каких-то лишних согласований (естественно проверку кода автоматическими тестами никто не отменял). Либо это может быть связано с тем, что CI/CD система технически построена на неудобных инструментах и примитивах, и со стороны кажется, что она похожа на CI/CD, а по факту неудобна для разработчиков (например, использование git-тегов с сообщением для каждого релиза).

Хорошая CI/CD система должна помогать разработчикам удобно доносить изменения до production в течение минут, иметь возможности отката, тестировать эти изменения на лету, но не ставить лишних барьеров и не требовать бессмысленных повторяющихся действий.

Также признаком хорошо построенной CI/CD системы является синхронизация состояния кода в git и выкаченного приложения на production-like и production окружениях. Например, приложение, выкаченное для staging соответствует последнему изменению сделанному в ветку staging (это лишь один из вариантов организации). Если код в ветке staging сломан, то и выкаченное приложение в окружении staging также сломано. Пользоваться приложением нельзя, но и пользоваться кодом из ветки staging тоже нельзя — ведь на нерабочем коде нельзя построить новых изменений. Поэтому мы держим код ветки staging (последний коммит в эту ветку) и приложение в синхронизированном состоянии, а не откатываем окружение staging на старый коммит. И поэтому в данной ситуации логично либо быстро фиксить проблему и выкатывать новое изменение в ветку с автоматическим выкатом на контур, либо делать revert внесённого изменения с автоматическим выкатом на контур — одно из двух.

В дальнейших разделах мы определим возможные варианты конфигураций workflow и насколько каждый из них соответствует подходам CI/CD.

Что такое pipeline и workflow

С помощью git пользователь вносит изменения в кодовую базу проекта. Каждый коммит в гит активирует так называемый pipeline со стороны CI/CD системы. Pipeline разбит на стадии, которые могут запускаться последовательно или параллельно.

Главное назначение pipeline — донести внесённое в гит изменение до некоторого окружения. В случае непрохождения какой-то стадии pipeline прерывается и пользователь тем самым получает обратную связь. Коммит, который успешно проходит по всем необходимым стадиям попадает на некоторый контур/окружение.

Бывают следующие основные типы стадий:

  • Build-and-Publish — сборка образов приложения и их публикация в хранилище образов.
  • Deploy — непосредственно выкат приложения на контур.
  • Cleanup — очистка неиспользуемых образов и связанного кеша из хранилища.

Pull request

Пользователь вносит изменения в кодовую базу путём создания коммитов в git и pull request-ов в CI/CD системе. Обычно pull request — это сущность, которая связывает коммит в git и pipeline (а также позволяет делать review, оставлять комментарии и пр.). В разных CI/CD системах pull request может называться по-разному (Merge Request в GItlab CI) или вообще отсутствовать (Jenkins).

Workflow

Pipeline-ы и стадии внутри pipeline-ов могут быть активированы как автоматически, так и вручную. Способы активации pipeline-ов, их устройство, связь с гит, требуемые действия со стороны пользователя — всё это будет определяться так называемым workflow. Возможно множество вариантов workflow для достижения одной и той же цели. Далее мы рассмотрим те варианты, которые можно реализовать с использованием werf.

Варианты ручного запуска pipeline

Ручной запуск pipeline предполагает:

  • Нажатие кнопки в CI/CD системе (например Gitlab CI).
  • Назначение label в CI/CD системе (например Gitlab CI или Github Actions). Label обычно назначается на pull request и снимается с pull request пользователем или автоматически CI/CD системой во время работы pipeline.
    • Например, пользователь назначает label “run tests” на его pull request и CI/CD система автоматически запускает соответствующий pipeline. Во время работы этого pipeline label “run tests” снимается с pull request. Далее для перезапуска пользователь может опять назначить этот label. И т.д.
    • Label используется как альтернатива кнопкам, либо в случаях когда кнопки не поддерживаются CI/CD системой (например, Github Actions). Для review окружений назначение пользователем label является сигналом к активации review окружения, а его снятие (вручную/автоматом) — к деактивации. Вариант будет подробнее рассмотрен (далее)(#автоматом-для-pull-request-после-ручной-активации).
  • Запрос через API CI/CD системы (например через HTTP по определённому url в Github Actions).

Стадия тестирования

Для правильной организации CI/CD критично во время внесения изменений в кодовую базу проекта получать быструю обратную связь в автоматическом режиме с помощью тестов. Причём стадию тестирования можно разбить на 2 условных этапа: на первичном этапе тесты проходят быстро и покрывают большую часть функций, на вторичном этапе тесты могут работать долго и проверять больше аспектов приложение. Первичные тесты обычно запускаются автоматически и их прохождение является обязательным условием для допуска изменений к релизу.

Что читать дальше

Дальше рекомендуется ознакомится с инструкцией по вашей CI/CD системе:

Если вы хотите узнать больше подробностей по методике составления workflow или для вашей CI/CD системы не нашлось инструкции, тогда можно ознакомится с дальнейшими разделами где определяются составляющие workflow и готовые конфигурации workflow. После этого вы будете готовы выбрать готовую конфигурацию или составить свою и реализовать её для вашей CI/CD системы с использованием werf.

Составляющие workflow для отдельных окружений

Далее рассмотрим различные варианты выката production и других окружений в связке с git. Каждый пункт определяет строительный блок, который можно использовать для работы с определённым окружением. Мы будем называть такой строительный блок блоком workflow. Из блоков workflow в дальнейшем можно собрать свой workflow или взять готовую конфигурацию (см. далее готовые конфигурации workflow).

Review окружения создаются и удаляются динамически по требованию разработчиков. С этим связаны особенности выката в эти окружения. В разделах, связанных с review, будет описано не только как создать review-окружение, но и как его удалить.

Выкат на production из master автоматически

Merge или коммит в ветку master вызывает pipeline выката непосредственно на production.

Состояние ветки в любой момент времени отражает состояние окружения. Поэтому данный вариант является соответствующим подходу true CI/CD.

Варианты отката:

  • Рекомендованный: откат через реверт коммита в ветке master. В этом случае поддерживается состояние ветки в синхронизированном с окружением состоянии, поэтому это предпочтительный вариант для сохранения целостности схемы.
  • Средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).

Выкат на production из master по кнопке

Pipeline выката в production может быть запущен вручную только на коммите из ветки master. Запуск pipeline производится средствами CI/CD системы вручную: кнопка в CI/CD системе или вызов API.

Варианты отката:

  • Рекомендованный: средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).
  • Реверт коммита в ветке master, затем запуск pipeline средствами CI/CD системы вручную: кнопка в CI/CD системе или вызов API. В данном случае вариант не рекомендован, т.к. состояние мастера не всегда соответствует состоянию окружения (в отличие от варианта master-автоматом), поэтому создавать лишний revert не имеет большого смысла именно для задачи отката.

Выкат на production из тега автоматически

Создание нового тега автоматически вызывает pipeline выката на production-окружение из коммита, связанного с этим тегом.

Варианты отката:

  • Рекомендованный: средствами CI/CD системы, повторный ручной вызов pipeline на старом теге.
  • Создание нового тега на старый коммит, далее автоматический вызов pipeline выката для нового тега. Не предпочтительный вариант, т.к. плодятся лишние теги.

Выкат на production из тега по кнопке

Pipeline выката в production-окружение может быть вызван только на существующем теге в git. Запуск pipeline производится средствами CI/CD системы вручную: кнопка в CI/CD системе или вызов API.

Варианты отката:

Выкат на production из ветки автоматически

Merge или коммит в специальную ветку вызывает pipeline выката непосредственно на production (вариант похож на (master-автоматически)(#master-автоматически), но используется отдельная ветка).

Состояние специальной ветки в любой момент времени отражает состояние окружения. Поэтому данный вариант является соответствующим подходу true CI/CD.

Варианты отката:

  • Рекомендованный: откат через реверт коммита в ветке. В этом случае поддерживается состояние ветки в синхронизированном с окружением состоянии, поэтому это предпочтительный вариант для сохранения целостности схемы.
  • Средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).
  • Реверт коммита в master, затем fast-forward merge в специальную ветку.
  • Удаление коммита в специальной ветке (через удаление коммита в git, затем процедура git push-force).

Выкат на production из ветки по кнопке

Pipeline выката в production может быть запущен вручную только на коммите из специальной ветки. Запуск pipeline производится средствами CI/CD системы вручную: кнопка в CI/CD системе или вызов API.

Варианты отката:

  • Рекомендованный: средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).
  • Реверт коммита в ветке, затем запуск pipeline средствами CI/CD системы вручную: кнопка в CI/CD системе или вызов API. В данном случае вариант не рекомендован, т.к. состояние мастера не всегда соответствует состоянию окружения (в отличие от варианта master-автоматом), поэтому создавать лишний revert не имеет большого смысла именно для задачи отката.

Выкат на production-like из pull request по кнопке

Pipeline выката в production может быть запущен на любом коммите в pull request. Запуск pipeline производится средствами CI/CD системы вручную: кнопка в CI/CD системе или вызов API.

Варианты отката:

  • Средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).

Выкат на staging из master автоматически

Merge или коммит в ветку master вызывает pipeline выката непосредственно на staging окружение.

Состояние ветки в любой момент времени отражает состояние окружения. Поэтому данный вариант является соответствующим подходу true CI/CD.

Варианты отката:

  • Рекомендованный: откат через реверт коммита в ветке master. В этом случае поддерживается состояние ветки в синхронизированном с окружением состоянии, поэтому это предпочтительный вариант для сохранения целостности схемы.
  • Средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).

Выкат на staging из master по кнопке

Pipeline выката в staging может быть запущен вручную только на коммите из ветки master. Запуск pipeline производится средствами CI/CD системы вручную: кнопка в CI/CD системе или вызов API.

Варианты отката:

  • Рекомендованный: средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).
  • Реверт коммита в ветке master, затем запуск pipeline средствами CI/CD системы вручную: кнопка в CI/CD системе или вызов API. В данном случае вариант не рекомендован, т.к. состояние мастера не всегда соответствует состоянию окружения (в отличие от варианта Выкат на staging из master автоматически), поэтому создавать лишний revert не имеет большого смысла именно для задачи отката.

Выкат на production-like из ветки автоматически

Merge или коммит в специальную ветку вызывает pipeline выката непосредственно на production-like окружение (вариант похож на (master-автоматически)(#master-автоматически), но используется отдельная ветка). Для каждого конкретного production-like окружения, как то: staging или testing — используется отдельная ветка.

Состояние специальной ветки в любой момент времени отражает состояние окружения. Поэтому данный вариант является соответствующим подходу true CI/CD.

Варианты отката:

  • Рекомендованный: откат через реверт коммита в ветке. В этом случае поддерживается состояние ветки в синхронизированном с окружением состоянии, поэтому это предпочтительный вариант для сохранения целостности схемы.
  • Средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).
  • Реверт коммита в master, затем fast-forward merge в специальную ветку.
  • Удаление коммита в специальной ветке (через удаление коммита в git, затем процедура git push-force).

Выкат на production-like из ветки по кнопке

Pipeline выката в production-like окружение может быть запущен вручную только на коммите из специальной ветки. Запуск pipeline производится средствами CI/CD системы вручную: кнопка в CI/CD системе или вызов API.

Варианты отката:

  • Рекомендованный: средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).
  • Реверт коммита в ветке, затем запуск pipeline средствами CI/CD системы вручную: кнопка в CI/CD системе или вызов API. В данном случае вариант не рекомендован, т.к. состояние ветки не всегда соответствует состоянию окружения (в отличие от варианта Выкат на production-like из ветки автоматически), поэтому создавать лишний revert не имеет большого смысла именно для задачи отката.

Выкат на review из pull request автоматически

Создание pull request автоматически вызывает выкат в отдельное review окружение. Название этого окружения связано с именем ветки. Дальнейшие коммиты в ветку, связанную с pull request автоматически вызывают выкат в review окружение.

Варианты отката:

  • Рекомендованный: откат через реверт коммита в ветке. В этом случае поддерживается состояние ветки в синхронизированном с окружением состоянии, поэтому это предпочтительный вариант для сохранения целостности схемы.
  • Средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).

Удаление review-окружения:

  • По закрытию или принятию PR.
  • Автоматически по истечению time-to-live с последнего выката на данное окружение (другими словами, при отсутствии активности в данном окружении).

Выкат на review из ветки по шаблону автоматически

Создание pull request для ветки, подходящей под определённый паттерн автоматически вызывает выкат в отдельное review окружение. Название этого окружения связано с именем ветки. Дальнейшие коммиты в ветку, связанную с pull request автоматически вызывают выкат в review окружение.

Например, для паттерна review_* создание pull request для ветки review_myfeature1 вызовет автоматическое создание соответствующего review окружения.

Варианты отката:

  • Рекомендованный: откат через реверт коммита в ветке. В этом случае поддерживается состояние ветки в синхронизированном с окружением состоянии, поэтому это предпочтительный вариант для сохранения целостности схемы.
  • Средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).

Удаление review-окружения:

  • По закрытию или принятию PR.
  • Автоматически по истечению time-to-live с последнего выката на данное окружение (другими словами, при отсутствии активности в данном окружении).

Выкат на review из pull request по кнопке

Pipeline выката в review-окружение может быть запущен вручную только на коммите из ветки соответствующей этому окружению. Название этого окружения связано с именем ветки. Запуск pipeline производится средствами CI/CD системы вручную: кнопка в CI/CD системе, повесить label или вызов API.

Варианты отката:

  • Рекомендованный: средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).
  • Реверт коммита в ветке, затем запуск pipeline средствами CI/CD системы вручную: кнопка в CI/CD системе или вызов API. В данном случае вариант не рекомендован, т.к. состояние ветки не всегда соответствует состоянию окружения (в отличие от вариантов “автоматом для pull-request” и “автоматом для pull-request по паттерну”), поэтому создавать лишний revert не имеет большого смысла именно для задачи отката.

Удаление review-окружения:

  • По закрытию или принятию PR.
  • Автоматически по истечению time-to-live с последнего выката на данное окружение (другими словами, при отсутствии активности в данном окружении).

Выкат на review из pull request автоматически после ручной активации

Review-окружение для pull request создаётся после его ручной активации средствами CI/CD системы. С этого момента любой коммит в ветку, связанную с pull request, вызывает автоматический выкат на review окружение. После работы с review его можно деактивировать вручную средствами CI/CD системы.

Pipeline выката в review-окружение может быть запущен только на коммите из ветки соответствующей этому окружению. Название этого окружения связано с именем ветки. Запуск pipeline для активации review окружения производится средствами CI/CD системы вручную: кнопка в CI/CD системе, повесить label или вызов API.

Варианты отката:

  • Рекомендованный: откат через реверт коммита в ветке. В этом случае поддерживается состояние ветки в синхронизированном с окружением состоянии, поэтому это предпочтительный вариант для сохранения целостности схемы.
  • Средствами CI/CD системы, повторный ручной вызов pipeline на старом коммите (например, в Gitlab CI кнопка “откатить” по факту выполняет именно эти шаги).

Удаление review-окружения:

  • Запуск pipeline для деактивации review окружения средствами CI/CD системы вручную: кнопка в CI/CD системе, снять ранее повешенный label или вызов API.
  • По закрытию или принятию PR.
  • Автоматически по истечению time-to-live с последнего выката на данное окружение (другими словами, при отсутствии активности в данном окружении).

Сравнение составляющих блоков для построения workflow

Степень управляемости через git

  Откат через git Ручной откат
Выкат через git Выкат на production из master автоматически;
Выкат на production из тега автоматически;
Выкат на production из ветки автоматически;
Выкат на staging из master автоматически;
Выкат на production-like из ветки автоматически;
Выкат на review из pull request автоматически;
Выкат на review из ветки по шаблону автоматически;
Выкат на review из pull request автоматически после ручной активации (полуавтоматический);
Выкат на production из master автоматически;
Выкат на production из тега автоматически;
Выкат на production из ветки автоматически;
Выкат на staging из master автоматически;
Выкат на production-like из ветки автоматически;
Выкат на review из pull request автоматически;
Выкат на review из ветки по шаблону автоматически;
Выкат на review из pull request автоматически после ручной активации (полуавтоматический);
Ручной выкат Выкат на review из pull request автоматически после ручной активации (полуавтоматический); Выкат на production из master по кнопке;
Выкат на production из тега по кнопке;
Выкат на production из ветки по кнопке;
Выкат на production-like из pull request по кнопке;
Выкат на review из pull request по кнопке;
Выкат на review из pull request автоматически после ручной активации (полуавтоматический);

Соответствие CI/CD

  True CI/CD Рекомендовано для werf
Выкат на production из master автоматически да да
Выкат на production из master по кнопке нет нет
Выкат на production из тега автоматически нет да
Выкат на production из тега по кнопке нет да
Выкат на production из ветки автоматически да нет
Выкат на production из ветки по кнопке нет нет
Выкат на production-like из pull request по кнопке нет да
Выкат на staging из master автоматически да да
Выкат на staging из master по кнопке нет нет
Выкат на production-like из ветки автоматически да нет
Выкат на production-like из ветки по кнопке нет нет
Выкат на review из pull request автоматически да нет
Выкат на review из ветки по шаблону автоматически да нет
Выкат на review из pull request по кнопке нет нет
Выкат на review из pull request автоматически после ручной активации да да

Готовые конфигурации workflow

Мы предлагаем пользователю на выбор несколько готовых конфигураций workflow для проекта. Эти конфигурации составлены из приведенных выше блоков workflow. В документации эти готовые конфигурации могут называться также стратегиями workflow.

Конкретные конфиги по каждой из конфигураций можно найти в инструкциях по конкретной CI/CD системе. Например, Gitlab CI: ссылка, Github Actions: ссылка.

№1 Fast and Furious

Конфигурация рекомендована в качестве наиболее соответствующей канонам CI/CD, которую можно реализовать с помощью werf.

В данной конфигурации может быть произвольное число production-like окружений, как то: testing, staging, development, qa, и т.д.

Окружение Блок workflow
Production Выкат на production из master автоматически + откат через revert
Staging / Testing / Development / QA Выкат на production-like из pull request по кнопке
Review Выкат на review из pull request автоматически после ручной активации

№2 Push the button

Окружение Блок workflow
Production Выкат на production из master по кнопке
Staging Выкат на staging из master автоматически
Testing / Development / QA Выкат на production-like из ветки автоматически
Review Выкат на review из pull request по кнопке

№3 Tag everything

Не все проекты сходу готовы к внедрению CI/CD. В таких проектах используется более классический метод создания релизов только после активной фазы разработки. Переход к CI/CD в таких проектах требует усилий по преодолению привычных вещей и переосмысления как от разработчиков, так и от devops. Поэтому для таких проектов мы предлагаем и классическую конфигурацию, которая также рекомендована для werf в случае невозможности использования fast & furious.

Окружение Блок workflow
Production Выкат на production из тега автоматически
Staging Выкат на staging из master автоматически или выкат на staging из master по кнопке
Review Выкат на review из pull request автоматически после ручной активации

№4 Branch, branch, branch

Управляем выкатом прямо через git с использованием веткок и процедур git merge, rebase и push-force. Через создание определённых имен веток получаем автоматический выкат на review окружения.

Рекомендуем для тех, кто хочет управлять CI/CD полностью из git. Отметим, что подход также является соответствующим канонам CI/CD, как и fast & furious.

Окружение Блок workflow
Production Выкат на production из master автоматически + откат через revert
Staging Выкат на staging из master автоматически
Review Выкат на review из ветки по шаблону автоматически