CI/CD, инфраструктура и облака DevOps и доставка ПО: карта трека, культура и метрики
0%

DevOps и доставка ПО: карта трека, культура и метрики

DevOps и доставка ПО: карта трека, культура и метрики

Это вход в трек по эксплуатации. Дальше будет много конкретики — Jenkinsfile, манифесты Kubernetes, HCL, конфиги раннеров и счета за облако. Но если начать сразу с инструментов, получится набор рецептов без критерия «зачем». Эта статья даёт критерий: как измерять доставку, какие силы на неё действуют и как выбирать инструмент под свой масштаб. Она нужна ровно один раз, зато сильно экономит время на остальных семнадцати.

1. Что такое DevOps, если убрать маркетинг

Начнём с исходной боли. Классическая организация делила ответственность так: разработка отвечает за изменения, эксплуатация — за стабильность. Это ровно противоположные цели, зашитые в KPI разных отделов. Разработчик получает премию за фичи, админ — за аптайм. Оптимальная стратегия админа — не пускать релизы; оптимальная стратегия разработчика — перебросить код «через стену» и объявить задачу выполненной. Оба ведут себя рационально, а система в целом деградирует.

Стандартный ответ на такой конфликт — не «подружить людей», а изменить структуру выигрышей. DevOps — это набор практик, который делает так, что быстрая доставка и стабильность перестают быть противоположностями. Ключевой контринтуитивный результат исследований DORA (Google Cloud, семь с лишним лет опросов десятков тысяч инженеров, книга «Accelerate» Форсгрен, Хамбла и Кима) звучит так:

Скорость и стабильность не находятся в trade-off. Команды, которые деплоят чаще, одновременно имеют меньше отказов и быстрее восстанавливаются.

Почему так — объясняется не культурой, а размером партии. Релиз раз в квартал содержит тысячи изменений: если он падает, вы не знаете, какое из них виновато, откат тянет за собой всё остальное, а миграции БД необратимы. Релиз из одного коммита при падении даёт мгновенную локализацию — виноват тот единственный коммит. Риск релиза растёт быстрее, чем линейно от количества изменений в нём, потому что растёт число взаимодействий между ними. Отсюда весь инженерный аппарат трека: чтобы уменьшить партию, нужна автоматизация; чтобы автоматизация была надёжной — тесты, воспроизводимые окружения, наблюдаемость и обратимые деплои.

Вторая опора — теория потока. Работа программиста — это поток заявок через систему с очередями. Закон Литтла связывает три величины: L = λ × W, где L — среднее число задач в работе, λ — пропускная способность, W — среднее время прохождения. Перепишем: W = L / λ. Время доставки одной задачи прямо пропорционально количеству задач, которые вы держите в работе одновременно. Не «пишите код быстрее» — уменьшайте WIP. Это же объясняет, почему очередь перед ревью или перед релизным окном стоит дороже, чем медленные тесты.

Разложение lead time: ожидание против работы

Картинка выше — типичный замер по реальному репозиторию. Инженерная интуиция подсказывает оптимизировать сборку, потому что она видна и раздражает. Но сборка занимает 9% времени, а ожидание — 69%. Ускорив тесты на треть, вы сократите lead time на 2.7%. Убрав недельное релизное окно — на 30%. Сначала измеряйте, потом оптимизируйте, и измеряйте именно ожидание.

2. Карта трека

Трек читается по четырём смысловым блокам, и порядок внутри блока важнее порядка между блоками:

Блок Статьи Главный вопрос
Конвейер https://courses.digitable.life/post/devops/01-ci-fundamentals/ → https://courses.digitable.life/post/devops/04-cd-and-release-strategies/, https://courses.digitable.life/post/devops/17-security-in-pipeline/ как код становится проверенным артефактом и попадает в прод
Упаковка и запуск https://courses.digitable.life/post/devops/05-containers-and-registries/ → https://courses.digitable.life/post/devops/08-helm-and-gitops/ во что упаковать и что этим управляет
Инфраструктура как код https://courses.digitable.life/post/devops/09-terraform-and-iac/, https://courses.digitable.life/post/devops/10-configuration-management/ как описать окружение текстом и воспроизвести
Площадка и деньги https://courses.digitable.life/post/devops/11-aws/ → https://courses.digitable.life/post/devops/15-cloud-cost-and-tradeoffs/ где это разместить и за сколько
Эксплуатация https://courses.digitable.life/post/devops/16-observability-and-oncall/ как понять, что всё работает, и жить с дежурствами

Если вы приходите с конкретной задачей, маршруты короче:

  • «У нас нет CI вообще» — 01 → 03 → 05. Три статьи дают рабочий пайплайн со сборкой образа.
  • «CI есть, деплой руками» — 04 → 05 → 08. Ключ здесь GitOps: он убирает kubectl apply с ноутбука.
  • «Всё в облаке, счёт растёт» — 15 → 14 → 11/12/13. Сначала методика счёта, потом альтернативы.
  • «Нас будят по ночам» — 16 → 04. Наблюдаемость плюс обратимые релизы, именно в таком порядке.
  • «Пришёл аудит» — 17 → 08. Секреты, подпись образов, аудируемый след изменений.

3. Поток создания ценности: от идеи до работающего кода

Полезно один раз нарисовать всю цепочку и понять, какая статья трека отвечает за какой её кусок.

Три наблюдения по этой схеме, которые стоят целого трека.

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

Артефакт собирается один раз. Образ, попавший в реестр, — тот же самый на стейджинге и в проде. Пересборка «того же кода» под прод убивает смысл тестирования: вы протестировали один бинарник, а выкатили другой. Это правило Хамбла и Фарли из «Continuous Delivery»: build binaries once.

Решение о выкате принимают метрики, а не человек. Строка O{Метрики в норме?} — самая недооценённая часть схемы. Пока откат делает человек по интуиции, время восстановления измеряется десятками минут и зависит от того, кто на дежурстве.

4. Четыре метрики, которыми меряют доставку

DORA свела оценку к четырём числам. Они хороши тем, что их сложно накрутить, не улучшив систему по-настоящему, и тем, что покрывают обе оси — скорость и стабильность.

Метрика Что это Что показывает
Deployment Frequency как часто код доезжает до прода размер партии, зрелость автоматизации
Lead Time for Changes от коммита до работы в проде длина и заторы конвейера
Change Failure Rate доля деплоев, вызвавших сбой качество тестов и обратимость релизов
Failed Deployment Recovery Time сколько чинится после сбоя обратимость и качество наблюдаемости

Пороговые значения (по отчётам DORA / State of DevOps, кластеры за 2023–2024 годы; цифры сдвигаются год от года, но порядки устойчивы):

Кластер Частота деплоев Lead time Change failure rate Восстановление
Elite по требованию, много раз в день менее суток ~5% менее часа
High от раза в день до раза в неделю 1–7 дней ~10% менее суток
Medium раз в неделю — раз в месяц 1–4 недели ~15% 1–7 дней
Low реже раза в месяц более месяца 20%+ более недели

Важная поправка, которую часто теряют: в отчёте 2024 года DORA добавила пятую метрику — rework rate, долю деплоев, сделанных только чтобы починить предыдущий деплой. Она ловит команду, которая накрутила частоту деплоев хотфиксами. Ещё DORA прямо предупреждает: метрики — инструмент диагностики для команды, а не рычаг сравнения команд между собой. Как только Deployment Frequency попадает в отчёт руководству, включается закон Гудхарта, и через месяц у вас тридцать деплоев пустых коммитов в день.

Чем считать. Всё, что нужно, лежит в git и в системе деплоя, поэтому первую версию делают скриптом, а не покупкой платформы:

"""Расчёт lead time for changes по данным git и журнала деплоев.

Lead time = момент попадания коммита в прод − момент авторства коммита.
Считаем медиану и p85: среднее по этой величине бессмысленно — распределение
имеет тяжёлый правый хвост (забытые PR тянут среднее вверх на порядок).
"""
import subprocess
from datetime import datetime, timezone
from statistics import median


def commits_between(old_sha: str, new_sha: str) -> list[tuple[str, datetime]]:
    """Коммиты, вошедшие в релиз: диапазон old..new с датой авторства."""
    out = subprocess.run(
        ["git", "log", "--pretty=format:%H|%aI", f"{old_sha}..{new_sha}"],
        capture_output=True, text=True, check=True,
    ).stdout
    result = []
    for line in out.splitlines():
        sha, iso = line.split("|")
        result.append((sha, datetime.fromisoformat(iso)))
    return result


def lead_times(deploys: list[tuple[str, str, datetime]]) -> list[float]:
    """deploys — список (предыдущий_sha, выкаченный_sha, время_выката).

    Сложность: O(D + C), где D — число деплоев, C — суммарное число коммитов;
    git log по диапазону линеен по длине диапазона.
    """
    hours = []
    for old_sha, new_sha, deployed_at in deploys:
        for _sha, authored_at in commits_between(old_sha, new_sha):
            delta = deployed_at - authored_at.astimezone(timezone.utc)
            hours.append(delta.total_seconds() / 3600)
    return hours


if __name__ == "__main__":
    # В реальности журнал деплоев берут из БД CD-системы или из аннотированных тегов.
    journal = [
        ("v1.4.0", "v1.4.1", datetime(2026, 7, 10, 12, 0, tzinfo=timezone.utc)),
        ("v1.4.1", "v1.5.0", datetime(2026, 7, 14, 9, 30, tzinfo=timezone.utc)),
    ]
    lt = sorted(lead_times(journal))
    print(f"деплоев:  {len(journal)}")
    print(f"коммитов: {len(lt)}")
    print(f"медиана:  {median(lt):.1f} ч")
    print(f"p85:      {lt[int(len(lt) * 0.85)]:.1f} ч")
$ python lead_time.py
деплоев:  2
коммитов: 37
медиана:  18.4 ч
p85:      96.2 ч

Разрыв между медианой и p85 в пять раз — самый частый и самый информативный результат. Он означает, что типичное изменение проезжает быстро, а каждый седьмой PR застревает на неделю. Чинить надо не среднюю скорость, а хвост: как правило, там висят ревью без назначенного ревьюера и задачи, требующие миграции БД.

Change failure rate считают проще, но аккуратнее с определением: сбоем считается деплой, потребовавший отката, хотфикса или вызвавший деградацию SLO. Не «баг нашли через месяц» — иначе метрика перестанет быть про деплой.

5. Минимальный рабочий конвейер целиком

Теория без работающего файла бесполезна. Вот сквозной пайплайн на GitHub Actions: сборка, тесты, образ, деплой через обновление манифеста в Git. Он намеренно небольшой, но содержит все обязательные элементы, которые дальше по треку разбираются подробно.

# .github/workflows/delivery.yml
name: delivery

on:
  push:
    branches: [main]
  pull_request:

# Отменяем предыдущие запуски на той же ветке: очередь CI — это деньги и время.
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

permissions:
  contents: read
  packages: write
  id-token: write        # нужен для OIDC: подпись образа без долгоживущих ключей

env:
  REGISTRY: ghcr.io
  IMAGE: ${{ github.repository }}

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-go@v5
        with:
          go-version: '1.23'
          cache: true                     # кэш модулей и build cache

      - name: Юнит-тесты с гонками и покрытием
        run: go test -race -coverprofile=cover.out ./...

      - name: Порог покрытия
        run: |
          pct=$(go tool cover -func=cover.out | awk '/^total:/ {print substr($3, 1, length($3)-1)}')
          echo "покрытие: ${pct}%"
          # Порог фиксирует достигнутый уровень, а не требует 100%.
          awk -v p="$pct" 'BEGIN { exit (p >= 65) ? 0 : 1 }'

      - name: Статический анализ
        uses: golangci/golangci-lint-action@v6
        with:
          version: v1.61

  build:
    needs: test
    if: github.ref == 'refs/heads/main'    # образы собираем только из main
    runs-on: ubuntu-latest
    outputs:
      digest: ${{ steps.push.outputs.digest }}
    steps:
      - uses: actions/checkout@v4

      - uses: docker/setup-buildx-action@v3

      - uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Сборка и публикация
        id: push
        uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          # Тег — SHA коммита. Никаких :latest в проде: тег должен быть неизменяемым.
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
          provenance: true                # SLSA-провенанс прямо из билдера

      - name: Скан образа на уязвимости
        uses: aquasecurity/trivy-action@0.28.0
        with:
          image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE }}:${{ github.sha }}
          severity: CRITICAL,HIGH
          exit-code: '1'                  # красный билд при критических CVE
          ignore-unfixed: true            # но не за то, что патча ещё нет

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment: production               # ручное подтверждение настраивается здесь
    steps:
      - uses: actions/checkout@v4
        with:
          repository: ${{ github.repository_owner }}/infra
          token: ${{ secrets.INFRA_PUSH_TOKEN }}

      - name: Обновить образ в манифесте
        run: |
          cd apps/api
          # Никакого kubectl: меняем декларацию в Git, выкат сделает GitOps-контроллер.
          yq -i '.images[0].newTag = "${{ github.sha }}"' kustomization.yaml
          git config user.name  "ci-bot"
          git config user.email "ci-bot@example.com"
          git commit -am "deploy api ${{ github.sha }}"
          git push

Чему учит этот файл, помимо синтаксиса:

  • concurrency с cancel-in-progress — самая дешёвая оптимизация счёта за CI. На активном репозитории она срезает 20–40% минут, потому что устаревшие запуски перестают докручиваться.
  • Тег образа — SHA коммита. Плавающие теги (latest, prod) ломают воспроизводимость и делают откат невозможным: вы не сможете сказать, что именно сейчас работает.
  • Деплой — это коммит в другой репозиторий, а не команда к кластеру. Отсюда бесплатно берётся аудит: git log в репозитории инфраструктуры и есть журнал выкатов. Подробно в https://courses.digitable.life/post/devops/08-helm-and-gitops/.
  • exit-code: 1 в сканере — политика, а не отчёт. Отчёт, который никого не блокирует, читают ровно ноль раз.

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

Главная ошибка при выборе инструментов — считать только лицензию. Реальная стоимость складывается из трёх частей: подписка + инфраструктура + время инженеров. Третья почти всегда крупнее первых двух и почти всегда не считается.

Порядок цифр по состоянию на 2025 год (проверяйте актуальные прайсы, они меняются):

Вариант Прямая цена Инфраструктура Эксплуатация Кому подходит
GitHub Actions, публичный репозиторий 0 $ ~0 OSS, обучение
GitHub Actions, приватный, Free 2000 мин/мес бесплатно, далее ~0.008 $/мин Linux ~0 до 10 человек
GitHub Actions + свои раннеры минуты не тарифицируются сервер от €4/мес 4–8 ч/мес 10–100 человек
GitLab CI SaaS Free 400 мин/мес; Premium от 29 $/юзер/мес ~0 нужны встроенный реестр и окружения
GitLab CI self-hosted (CE) 0 $ лицензии 4–8 vCPU под сервер + раннеры 1–3 дня/мес требования к данным на своей площадке
Jenkins 0 $ сервер + агенты 2–5 дней/мес легаси, экзотические агенты, жёсткий контроль
Managed Kubernetes + Tekton/Argo плата за кластер кластер 3–7 дней/мес вы и так живёте в k8s

Пересчитайте последнюю колонку в деньги, и картина меняется. Инженер стоит условно 40 $/час полной стоимости. Jenkins с тремя днями обслуживания в месяц — это 24 часа, около 960 $/мес сверх «бесплатной» лицензии. За те же деньги SaaS даёт 120 000 минут Linux-раннеров. Jenkins всё ещё бывает правильным выбором (об этом честно в https://courses.digitable.life/post/devops/02-jenkins/), но выбирать его «потому что бесплатно» — арифметическая ошибка.

Та же логика для раннеров:

Точка окупаемости собственных CI-раннеров

Голое сравнение цены железа и цены минут даёт окупаемость около 6 000 минут в месяц — примерно 100 часов сборок, что набирает команда из 8–10 человек с ночными прогонами. Но если добавить в модель хотя бы 8 часов в месяц на патчинг, чистку дисков, обновление тулчейна и разбор зависших джоб, точка сдвигается к 27 000 минут. Между этими двумя числами лежит зона, где «сэкономить на раннерах» означает потратить больше.

Практическое правило: свои раннеры берут не ради экономии, а ради того, чего SaaS не даёт — специфического железа (GPU, ARM, много памяти), доступа во внутреннюю сеть, тёплых кэшей на локальном диске, требований по размещению данных. Если ни одного из этих пунктов нет, оставайтесь на SaaS дольше, чем кажется разумным.

7. Стадии зрелости и куда двигаться

Организация проходит примерно одни и те же ступени. Полезно честно определить свою: попытка перепрыгнуть через ступень обычно заканчивается дорогим и заброшенным Kubernetes.

Обратные переходы на схеме — не украшение. Это два самых частых способа потерять уже построенное:

Флакующие тесты убивают CI. Как только красный билд начинают перезапускать «потому что оно иногда падает», сигнал теряет смысл, и через месяц никто не смотрит на статус. Флакующий тест хуже отсутствующего: он тратит время и обучает команду игнорировать сигналы. Правило простое — тест, упавший дважды без изменения кода, карантинится в тот же день и чинится или удаляется в течение недели.

Необратимые миграции убивают CD. Первый же деплой, который нельзя откатить из-за схемы БД, возвращает практику «деплоим руками в субботу». Лечится дисциплиной обратной совместимости: сначала добавляем колонку, потом код, который её пишет, потом код, который её читает, и только потом удаляем старую — растянуто на несколько релизов. Детали в https://courses.digitable.life/post/devops/04-cd-and-release-strategies/.

8. Стратегия ветвления как часть доставки

Модель ветвления определяет размер партии не меньше, чем инструменты. Сравним две крайности.

Ветка feature-a живёт три коммита и уже ловит конфликт с хотфиксом. Коммиты small-1 и small-2 идут в main напрямую и релизятся сразу. Trunk-based development — короткие ветки, живущие часы, а не недели — это не вопрос вкуса: DORA стабильно показывает его как один из предикторов высокой производительности доставки. Механизм понятен из закона Литтла: длинная ветка — это WIP, лежащий в очереди на интеграцию, и стоимость слияния растёт с возрастом ветки.

Неготовый код при этом прячут не веткой, а feature flag: код в main, поведение выключено, включается для 1% пользователей конфигом. Это отделяет деплой (техническая операция) от релиза (продуктовое решение) — фундаментальная развязка, разбираемая в https://courses.digitable.life/post/devops/04-cd-and-release-strategies/.

9. Инцидент: где культура становится инженерией

Слово «культура» в DevOps звучит расплывчато ровно до момента, когда вы посмотрите на жизненный цикл инцидента.

Три вещи здесь не про инструменты, а про договорённости, и именно они отличают работающую эксплуатацию от героической.

Митигация раньше диагностики. Инстинкт инженера — понять причину. Правильное поведение дежурного — вернуть систему в рабочее состояние (откат, переключение трафика, отключение флага), и только потом разбираться. Это возможно, только если откат дешёвый и заранее отрепетированный.

Постмортем без виноватых. Не благородство, а механика получения информации: в организации, где за инцидент наказывают, инженеры перестают сообщать о проблемах, и вы теряете входные данные. Веструм классифицировал такие культуры как патологические — информацию в них прячут. Ссылки и шаблон — в https://courses.digitable.life/post/devops/16-observability-and-oncall/ и в открытой Google SRE Book, глава Postmortem Culture.

Алерт по симптому, а не по причине. «Error rate выше SLO» будит человека, потому что страдают пользователи. «CPU выше 80%» будит его зря — это может быть нормальной работой. Алерты, которые срабатывают вхолостую, приводят к усталости от алертов, а она — к пропущенному настоящему инциденту.

10. Типичные ошибки

«DevOps-отдел». Создать между разработкой и эксплуатацией третий отдел — значит поставить вторую стену вместо одной. Признак: тикет «задеплойте нам, пожалуйста». Рабочий вариант — платформенная команда, которая делает самообслуживание: не деплоит за других, а даёт инструмент, которым разработчик деплоит сам. Хорошее описание модели — Team Topologies Скелтона и Пайса.

Kubernetes для трёх сервисов. Кластер — это отдельная система с собственной эксплуатацией: обновления, CNI, ingress, storage, RBAC, сертификаты. Для трёх сервисов и двух разработчиков нагрузка на эксплуатацию превысит выгоду многократно. Сначала прочитайте https://courses.digitable.life/post/devops/07-k3s-and-lightweight/ и https://courses.digitable.life/post/devops/14-vps-vds-and-bare-metal/ — Docker Compose на паре машин закрывает больше сценариев, чем принято признавать.

Секреты в переменных CI навсегда. Долгоживущий токен с правами на прод, лежащий в настройках проекта, — типовая точка компрометации. Современный ответ — OIDC-федерация: CI получает короткоживущий токен под конкретный workflow. Разбор в https://courses.digitable.life/post/devops/17-security-in-pipeline/.

Оптимизация видимого вместо узкого. Возвращаясь к первой картинке: неделя, потраченная на ускорение сборки с 12 до 7 минут, при недельном релизном окне не даёт ничего. Стройте карту потока и меряйте ожидание.

Метрики как средство оценки людей. Deployment Frequency в отчёте для руководства превращается в накрутку. Метрики DORA — термометр для команды, а не KPI для премии.

Мониторинг вместо наблюдаемости. Тысяча дашбордов отвечает на вопросы, которые вы придумали заранее. Инциденты же обычно про то, чего вы не предусмотрели, — там нужны структурные логи, трейсы и возможность задать новый вопрос данным. Разница подробно в https://courses.digitable.life/post/devops/16-observability-and-oncall/.

Дрейф инфраструктуры. Один kubectl edit вручную «на пять минут» — и состояние прода расходится с описанием в Git. Через полгода воспроизвести окружение невозможно. Лечится GitOps-контроллером, который возвращает состояние к декларации, и Terraform-планом в CI, который показывает дрейф (https://courses.digitable.life/post/devops/09-terraform-and-iac/).

11. Практика: с чего начать в понедельник

Порядок действий для команды, у которой ничего из этого нет. Каждый шаг даёт измеримый результат сам по себе, поэтому проект не разваливается посередине.

  1. Замерьте базовую линию. Скрипт из раздела 4, лучше руками по последним 50 PR. Без этого вы не докажете прогресс и не выберете, что чинить.
  2. Тесты на каждый PR, красный билд блокирует слияние. Один YAML-файл и настройка branch protection. Часто это единственное, что нужно, чтобы CFR упал вдвое.
  3. Соберите образ один раз и тегируйте SHA. Убирает целый класс расследований «а что вообще в проде».
  4. Автоматизируйте выкат на стейдж. Полностью, без кнопок. Прод оставьте по кнопке — это нормальная промежуточная точка на годы.
  5. Сделайте откат одной командой и отрепетируйте его. Не документ, а реальный прогон в рабочее время. Пока откат не проверен, его не существует.
  6. Заведите один SLO и один алерт по симптому. Ровно один. Десять алертов на старте гарантируют, что через месяц их будут игнорировать все.
  7. Первый постмортем — на ближайший инцидент. Шаблон на полстраницы, обязательные поля: хронология, влияние на пользователей, что помогло восстановиться, экшены с владельцем и сроком.

Шаги 1–3 занимают недели, 4–7 — месяцы. Kubernetes, Terraform и GitOps в этом списке отсутствуют намеренно: они решают проблемы масштаба, которых у вас пока может не быть, и добавляют собственную эксплуатационную нагрузку.

12. Мини-итог

  • DevOps — это не должность и не набор инструментов, а способ убрать конфликт между скоростью и стабильностью за счёт уменьшения размера партии и автоматизации проверок.
  • Скорость и надёжность растут вместе — данные DORA за много лет устойчиво это показывают.
  • Четыре метрики (частота деплоев, lead time, change failure rate, время восстановления) диагностируют доставку; считать их можно скриптом на git-истории, покупать платформу для этого не нужно.
  • Большую часть lead time занимают очереди, а не работа. Меряйте ожидание, оптимизируйте узкое место.
  • Артефакт собирается один раз, тег неизменяемый, деплой — это изменение декларации в Git, а не команда к серверу.
  • Выбор инструментов считается по полной стоимости владения: подписка плюс инфраструктура плюс часы инженеров. «Бесплатное» self-hosted-решение регулярно оказывается самым дорогим.
  • Культура измерима: постмортем без виноватых, алерты по симптомам, митигация раньше диагностики.

Источники

  • Nicole Forsgren, Jez Humble, Gene Kim. Accelerate: The Science of Lean Software and DevOps. IT Revolution, 2018 — itrevolution.com
  • Jez Humble, David Farley. Continuous Delivery. Addison-Wesley, 2010 — continuousdelivery.com
  • DORA. State of DevOps Reports и определения метрик — dora.dev/research
  • Google. Site Reliability Engineering и The SRE Workbook (полные тексты бесплатно) — sre.google/books
  • Gene Kim, Jez Humble, Patrick Debois, John Willis. The DevOps Handbook, 2nd ed. IT Revolution, 2021
  • Matthew Skelton, Manuel Pais. Team Topologies. IT Revolution, 2019 — teamtopologies.com
  • Donald Reinertsen. The Principles of Product Development Flow. Celeritas, 2009 — теория очередей и размера партии
  • Martin Fowler. Continuous Integration, Trunk Based Development, Blue Green Deploymentmartinfowler.com
  • Ron Westrum. A typology of organisational cultures. BMJ Quality & Safety, 2004 — qualitysafety.bmj.com

Что дальше

Мы построили систему координат: поток, метрики, стадии зрелости и способ считать стоимость решений. Дальше — вглубь конвейера, начиная с его первого звена. Что именно должно происходить на каждый коммит, как устроены триггеры, почему кэш зависимостей окупается за день и как матрицы сборок ловят то, что не ловит один прогон.

Непрерывная интеграция: принципы, триггеры, кэш, матрицы сборок

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов