Урок по треку DevOps: CI/CD, IaC, облака 7 мин

CI-пайплайны и артефакты за 7 минут

GitHub Actions и GitLab CI, стадии и джобы, кеш против артефактов, раннеры, матрицы, версии и реестры.

Пайплайн это описанный кодом путь от коммита до готового артефакта (и дальше до деплоя). Он лежит в репозитории рядом с кодом: .github/workflows/*.yml в GitHub Actions, .gitlab-ci.yml в GitLab CI. Значит, его ревьюят, версионируют и откатывают, как обычный код.

Из чего состоит пайплайн

  • Триггер: push, pull/merge request, тег, расписание, ручной запуск.
  • Джоба (job): набор шагов, который выполняется на одном раннере в чистом окружении.
  • Стадии и зависимости: в GitLab джобы группируются в stages (build, test, deploy), а needs строит граф, чтобы джоба стартовала сразу после нужных, не дожидаясь всей стадии. В GitHub Actions джобы по умолчанию параллельны, порядок задаёт needs.
  • Раннер: машина, где выполняется джоба. Облачные (GitHub-hosted, shared runners GitLab) или свои (self-hosted).
# GitHub Actions
name: ci
on:
  pull_request:
  push:
    branches: [main]
concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true
permissions:
  contents: read
jobs:
  test:
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        node: [20, 22]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
          cache: npm
      - run: npm ci
      - run: npm test
  build:
    needs: test
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
      - run: docker build -t registry.example.ru/app:${{ github.sha }} .
# GitLab CI
stages: [build, test, deploy]
build:
  stage: build
  script: npm ci && npm run build
  artifacts:
    paths: [dist/]
    expire_in: 1 week
test:
  stage: test
  needs: [build]
  script: npm test
deploy:
  stage: deploy
  script: ./deploy.sh
  environment: production
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: manual

Кеш и артефакты: не путать

  • Кеш ускоряет: папка зависимостей (~/.npm, .m2, ~/.cache/pip) переиспользуется между запусками. Он может не найтись, и джоба обязана работать и без него. Ключ кеша строят из хеша lock-файла.
  • Артефакт передаёт результат: собранный dist/, бинарник, отчёт тестов. Он гарантированно доступен следующим джобам и скачивается из интерфейса.

Ошибка: передавать сборку между стадиями через кеш. Однажды кеш промахнётся, и деплой уедет без файлов.

Собрать один раз, выкатывать везде

Артефакт (образ, пакет) собирается один раз и продвигается по окружениям: stage, затем prod. Пересборка под каждое окружение означает, что в прод уходит не то, что тестировали. Различия окружений задаются конфигом и переменными, а не разными сборками.

Образы тегируются неизменяемо: SHA коммита или версия 1.4.2. Тег latest для деплоя плох: непонятно, что именно запущено, и откат «на прошлый latest» невозможен. Самый надёжный способ сослаться на образ это digest @sha256:....

Версии

Semantic Versioning: MAJOR.MINOR.PATCH. MAJOR при ломающих изменениях, MINOR при новых возможностях с обратной совместимостью, PATCH при исправлениях. Версию часто вычисляют автоматически из Conventional Commits (feat: поднимает minor, fix: patch, feat!: или BREAKING CHANGE major).

Быстрый и надёжный пайплайн

  • Дешёвые проверки первыми: линтер и юнит-тесты до долгих e2e.
  • Параллелить независимые джобы, матрица для версий.
  • Кешировать зависимости и слои Docker.
  • concurrency с отменой устаревших запусков на ту же ветку.
  • Флаки-тесты чинить или помечать, а не перезапускать до зелёного.
  • Ограничить права токена: permissions: contents: read по умолчанию.
  • Сторонние actions фиксировать по SHA коммита, а не по плавающему тегу.

Монорепозиторий

В монорепо пайплайн собирает только то, что изменилось: paths в GitHub Actions, rules: changes в GitLab, или инструменты сборки с графом зависимостей (Nx, Turborepo, Bazel).

Частые ошибки

  • Секреты в логах: echo $TOKEN или set -x в скрипте.
  • npm install вместо npm ci в CI: lock-файл может измениться, сборка не воспроизводима.
  • Деплой тегом latest.
  • Self-hosted раннер на публичном репозитории: любой форк может выполнить код на вашей машине.

Что спросят на собесе

  • Из чего состоит ваш пайплайн и сколько он идёт.
  • Чем кеш отличается от артефакта.
  • Как ускорить пайплайн, который идёт 40 минут.
  • Почему не стоит деплоить тег latest и как делать откат.
  • Как хранить секреты в CI.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.