Непрерывная интеграция и непрерывное развертывание в SourceCraft

Непрерывная интеграция и непрерывное развертывание (CI/CD, Continuous Integration/Continuous Deployment) — это набор практик и инструментов, с помощью которых вы можете автоматически вносить изменения, тестировать и развертывать код. Такой подход позволяет постоянно улучшать качество программного обеспечения, а также ускорить разработку.

Непрерывная интеграция (CI)

Цель CI заключается в частой и регулярной интеграции изменений кода в основную ветку репозитория. Каждый коммит проходит автоматические проверки, например юнит-тесты и статический анализ кода. Таким образом можно убедиться в корректности коммита и стабильности кода. Это снижает риски интеграционных проблем, а разработчики быстрее получают обратную связь.

Непрерывное развертывание (CD)

Подход CD строится на автоматизации развертывания кода на продуктовые серверы после проверки качества кода. Это обеспечивает уверенность в том, что приложения всегда находятся в развернутом состоянии с последними обновлениями и исправлениями.

Конфигурация CI/CD

В SourceCraft встроен механизм для работы с CI/CD-процессами.

Конфигурация CI/CD задается для конкретного репозитория и хранится в файле .sourcecraft/ci.yaml.

Общий вид конфигурационного файла .sourcecraft/ci.yaml:

on:
  pull_request:
    - workflows: [<список_рабочих_процессов>]
      filter:
        source_branches: [<список_исходных_веток>]
        target_branches: [<список_целевых_веток>]
        paths: [<список_путей>]

  push:
    - workflows: [<список_рабочих_процессов>]
      filter:
        branches: [<список_веток>]
        paths: [<список_путей>]

workflows:
  <имя_рабочего_процесса>:

    tasks:
      - name: <имя_задания>
        
        cubes:
          - name: <имя_кубика>
            image: <путь_к_Docker-образу>
            script:
              - <выполняемый_скрипт>
...

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

Пример конфигурации СI/CD в виде отдельных блоков
on:
  pull_request:
    - workflows: my-test-workflow
      filter:
        source_branches: ["**", "!test**"]
        target_branches: "main"

workflows:
  my-test-workflow:
    tasks:
      - my-test-task

tasks:
  - name: my-test-task
    cubes:
      - name: my-test-cube
        image: docker.io/library/node
        script:
          - echo Hello, world!

В конфигурационном файле поддерживается использование секретов. Подробнее см. в разделе Использовать значение секрета в CI/CD.

Полную спецификацию файла .sourcecraft/ci.yaml см. в репозитории templates в SourceCraft.

Важно

Скоро перестанет поддерживаться хранение конфигурации CI/CD, правил ревью кода и политик веток в едином файле .src.ci.yaml в корне репозитория. Используйте отдельные файлы .sourcecraft/ci.yaml, .sourcecraft/review.yaml и .sourcecraft/branches.yaml.

Подробнее о работе с CI/CD см. на странице Настроить CI/CD в репозитории SourceCraft.

События-триггеры (on)

В блоке on настраиваются события-триггеры, которые будут запускать рабочие процессы CI/CD в репозитории.

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

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

Подробнее см. на странице События-триггеры (on) в справочнике CI/CD.

Рабочие процессы (workflows)

В блоке workflows определяется перечень рабочих процессов CI/CD.

Рабочий процесс предназначен для логического объединения заданий, связанных с определенным этапом CI/CD.

Например, один рабочий процесс может выполняться для сборки, тестов, линтинга, проверок покрытия кода (code coverage) и т. д. Перечисленные этапы будут разными заданиями, объединенными в один рабочий процесс. Другой рабочий процесс будет выполняться, например, для генерации документации и развертывания новой версии ПО в промышленную эксплуатацию.

Все рабочие процессы запускаются параллельно.

Подробнее см. на странице Рабочие процессы (workflows) в справочнике CI/CD.

Задания (tasks)

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

Каждое задание содержит в себе набор минимальных логических действий — кубиков. Результатом задания является выполнение всех кубиков.

Примечание

Все кубики одного задания запускаются на одной и той же виртуальной машине (воркере). Поэтому если один кубик изменит окружение воркера, например, установит пакет, создаст или удалит файл и т. д., это окружение останется для всех последующих кубиков, которые выполняются в рамках одного задания. Например, в первом кубике устанавливается пакет runtime для языка Go, во втором выполняется команда go build, а в следующем — go test. Подробнее о наследовании окружения см. на странице Кубики (cubes).

Если кубики запущены в разных заданиях, то они гарантированно будут исполняться на разных воркерах.

По умолчанию задание начинается с клонирования репозитория.

Все задания рабочего процесса запускаются параллельно.

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

Подробнее о заданиях см. на странице Задания (tasks) в справочнике CI/CD.

Кубики (cubes)

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

Минимальным действием может быть вызов скрипта или запуск Docker-контейнера. Также может быть вариант вызова скрипта в Docker-контейнере.

Есть следующие виды кубиков:

  • Нативный — выполняется напрямую на воркере.

    Если нативный кубик в процессе выполнения изменит окружение воркера, например, установит пакет, создаст или удалит файл и т. д., это окружение останется для всех последующих кубиков, которые выполняются в рамках одного задания.

  • Docker-кубик — выполняется внутри Docker-контейнера, который запускается на воркере. Внутри контейнера запускается пользовательский скрипт или скрипт контейнера, если для контейнера предусмотрена точка входа (entrypoint).

    Если Docker-кубик в процессе выполнения изменит окружение, оно будет доступно последующим кубикам задания, только если изменения производятся внутри директории /sourcecraft. Все остальные изменения удаляются вместе с Docker-контейнером.

    При работе из контейнера директории монтируются следующим образом:

    • директория, в которой находятся связанные с выполняемым заданием файлы, монтируется по пути /sourcecraft;
    • директория, в которую клонируется репозиторий, и которая по умолчанию назначается рабочей (workdir), монтируется по пути /sourcecraft/workspace.

    Пути указанных директорий можно получить из предопределенных переменных окружения $SOURCECRAFT_ROOT_DIRECTORY и $SOURCECRAFT_WORKSPACE соответственно.

    Docker-кубик задается с помощью параметра image, в котором указывается название Docker-образа, а также опционально логин, пароль, точка входа и аргументы.

В кубиках вы можете использовать переменные окружения, а также секреты. Для передачи переменных окружения от одного кубика к последующим в виде пар KEY=VALUE предусмотрена предопределенная переменная $SOURCECRAFT_ENV.

Кубики внутри одного задания по умолчанию запускаются последовательно. Кубики могут быть связаны между собой через параметр needs. В параметре указывается список кубиков, которые должны быть выполнены до запуска текущего. Если параметр не указан, кубик будет зависеть от кубика, который определен непосредственно перед ним.

Артефакты, которые могут быть созданы в результате работы кубика, сохраняются для дальнейшего использования. Их можно скачать из конкретного кубика в секции Автоматизации репозитория в течение 14 дней.

Подробнее о кубиках см. на странице Кубики (cubes) в справочнике CI/CD.

Переменные окружения в CI/CD

В CI/CD-процессах SourceCraft поддерживаются переменные окружения. Переменные можно задать в следующих элементах конфигурации .sourcecraft/ci.yaml:

  • Задание — переменные будут переданы во все связанные с заданием кубики.
  • Кубик — переменные будут переданы только в конкретный кубик.

Также вы можете использовать предопределенные переменные окружения.

Важно

Не храните в переменных окружения конфиденциальные данные, например пароли, ключи доступа, токены и т. д. Для хранения таких данных используйте секреты.

Пример конфигурации с переменными окружения

tasks:
  - name: my-task
    # Здесь определяются переменные, которые будут переданы во все связанные с заданием кубики.
    env:
      TASK_VAR: test-var-'test'-\"test\"
      MULTILINE_VAR: |
        multi-var
        multi-var
        this is my multi-var

    cubes:
      - name: my-cube
        # Здесь определяются переменные, которые будут переданы только в конкретный кубик.
        env:
          CUBE_VAR: "you can see me here only"
          SECRET_VAR: ${{ secrets.<название_секрета> }}
        script:
          - echo "$TASK_VAR"
          - echo "$MULTILINE_VAR"
          - echo "$CUBE_VAR"
          - echo "$SECRET_VAR"

Подробнее об использовании переменных окружения см. на странице Работа с переменными окружения в SourceCraft.

Воркеры

Воркер — это виртуальная машина, физический сервер или serverless-контейнер, на которых выполняются CI/CD-процессы.

Все кубики одного задания запускаются на одном и том же воркере.

Поддерживаются следующие типы воркеров:

Облачные воркеры

Облачные воркеры — виртуальные машины в облаке, предоставляемые SourceCraft. Являются ресурсом для выполнения CI/CD-процессов по умолчанию.

Конфигурация вычислительных ресурсов облачных воркеров: 4 vCPU, 8 ГБ RAM.

Serverless-воркеры

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

Ограничения:

  • Для Docker-кубиков поддерживается только реестр Yandex Container Registry.
  • Внутри кубика нельзя запускать docker и docker-compose.
  • В одном задании может быть не более 9 уникальных пользовательских Docker-образов.

Чтобы запустить CI/CD-процесс на serverless-воркере, в параметрах рабочего процесса (workflow) или задания (task) укажите runs_on: serverless.

Если в task не указан параметр runs_on, по умолчанию будет выставлен параметр из workflow:runs_on.

Пример запуска всего рабочего процесса на serverless-воркере

workflows:
  workflow-in-serverless-mode:
    runs_on: serverless
  
    tasks:
      - name: task1-in-serverless-mode
        cubes:
          - name: hello
            script:
              - echo "hello from serverless"

      - name: task2-in-serverless-mode
        cubes:
          - name: hello
            script:
              - echo "hello from serverless again"

Пример запуска отдельного задания на serverless-воркере

workflows:
  workflow1:
  
    tasks:
      - name: task1-in-compute-mode
        cubes:
          - name: hello
            script:
              - echo "hello from compute"

      - name: task2-in-serverless-mode
        runs_on: serverless
        cubes:
          - name: hello
            script:
              - echo "hello from serverless"

Пользовательские (self-hosted) воркеры

Пользовательские (self-hosted) воркеры — личные серверы пользователей, как виртуальные, так и физические, на которых выполняются CI/CD-процессы. В этом случае для процессов будет доступно окружение пользовательского сервера.

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

Подробнее см. Настроить пользовательский (self-hosted) воркер для SourceCraft.

Чтобы запустить CI/CD-процесс на пользовательском воркере, в параметрах рабочего процесса (workflow) или задания (task) укажите runs_on: self-hosted.

Если в task не указан параметр runs_on, по умолчанию будет выставлен параметр из workflow:runs_on.

Пример запуска всего рабочего процесса на пользовательском воркере

workflows:
  my-awesome-workflow:
    runs_on: self-hosted
    
    tasks:
      - name: self-hosted-task
        cubes:
          - name: hello
            script:
              - echo "hello from self-hosted"

      - name: self-hosted-go-builder-task
        runs_on: [self-hosted, go-builder]
        cubes:
          - name: hello
            script:
              - echo "hello from self-hosted go builder"

В этом случае задания из рабочего процесса my-awesome-workflow, если у них не переопределен параметр runs_on, по умолчанию будут выполняться на любом из ваших пользовательских воркеров. А задание self-hosted-go-builder-task будет выполнено только на пользовательском воркере, которому при инициализации был присвоен тег go-builder.

См. также