GH GambleHub

CI/CD конвейеры: GitHub Actions, GitLab CI

CI/CD конвейеры: GitHub Actions, GitLab CI

1) Задача CI/CD и место в платформе

CI/CD — это непрерывная сборка, тестирование и доставка изменений из репозитория в рабочие окружения. Цели:
  • Скорость и предсказуемость релизов (короткий lead time).
  • Качество (автотесты, статический/динамический анализ).
  • Безопасность цепочки поставки (подпись артефактов, контроль доступов).
  • Надежность (канареечные деплои, быстрый откат).
  • Наблюдаемость (трассировка и метрики на каждом этапе).

Ключевые принципы: «pipeline as code», иммутабельные артефакты, «build once — run many», «shift-left security», «least privilege», детерминированные сборки.

2) Архитектурные паттерны конвейеров

Stage-gate: build → test → security → package → deploy → post-deploy checks.
Fan-out/Fan-in: параллельные матричные сборки (языки/платформы) с объединением результатов.
Promotion: один и тот же артефакт продвигается через окружения (dev → stage → prod), а не пересобирается.
Trunk-based + короткие ветки: минимизация дрейфа, автоматизированные проверки на PR/MR.
Reusable: переиспользуемые workflow/шаблоны (Actions: reusable workflows; GitLab: includes/child-pipelines).
GitOps (опционально): разделение «сборки» и «доставки» (Argo CD/Flux следят за декларативным репо окружений).

3) Безопасность цепочки поставки (supply chain)

Идентификация: OIDC-федерация от runner’а к облаку (без долгоживущих ключей).
Секреты: централизованное хранилище, ограничение контекста, запрет на вывод в логи.
Подпись артефактов/контейнеров (cosign/Sigstore), проверка подписи в admission-контроле.
SBOM (CycloneDX/SPDX) и SCA, SAST/DAST/Container Scan — «обязательные ворота».
Политики: OPA/Conftest для IaC/манифестов, «no latest», запрет привилегированных контейнеров.
Изоляция runner’ов: prod-раннеры в приватной сети, отделить от публичного интернета исходящих доступов.

4) GitHub Actions — структура и практики

4.1 Структура workflows

`.github/workflows/.yml` — триггеры (`on: push, pull_request, schedule, workflow_call`).
Reusable workflows для стандартизации (линтер, SCA, контейнерная сборка, деплой).

4.2 Пример: многостадийный пайплайн с OIDC и подписью образа

yaml name: ci-cd

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

permissions:
id-token: write  # для OIDC contents: read packages: write

jobs:
build_test_matrix:
runs-on: ubuntu-latest strategy:
matrix:
node: [18, 20]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4 with: { node-version: ${{ matrix. node }} }
- name: Cache npm uses: actions/cache@v4 with:
path: ~/.npm key: npm-${{ runner. os }}-${{ matrix. node }}-${{ hashFiles('/package-lock. json') }}
- run: npm ci
- run: npm run lint && npm test -- --ci

docker_build_sign:
runs-on: ubuntu-latest needs: build_test_matrix steps:
- uses: actions/checkout@v4
- name: Login to GHCR uses: docker/login-action@v3 with:
registry: ghcr. io username: ${{ github. actor }}
password: ${{ secrets. GITHUB_TOKEN }}
- name: Build image run:
docker build --pull --no-cache -t ghcr. io/org/app:${{ github. sha }}.
docker push ghcr. io/org/app:${{ github. sha }}
- name: Generate SBOM uses: anchore/syft-action@v0 with:
image: ghcr. io/org/app:${{ github. sha }}
format: cyclonedx-json output-file: sbom. json
- name: Cosign sign (OIDC)
uses: sigstore/cosign-installer@v3
- name: Sign image run:
cosign sign ghcr. io/org/app:${{ github. sha }} \
--yes \
--identity-token $ACTIONS_ID_TOKEN_REQUEST_TOKEN \
--rekor-url https://rekor. sigstore. dev

deploy_stage:
runs-on: ubuntu-latest needs: docker_build_sign environment:
name: stage url: https://stage. example. com steps:
- uses: actions/checkout@v4
- name: Assume cloud role via OIDC uses: aws-actions/configure-aws-credentials@v4 with:
role-to-assume: arn:aws:iam::123456789012:role/github-deployer aws-region: eu-central-1
- name: Helm deploy (canary 10%)
run:
helm upgrade --install app charts/app \
--set image. tag=${{ github. sha }} \
--set canary. enabled=true --set canary. traffic=10
- name: Smoke checks run:./scripts/smoke. sh

promote_prod:
runs-on: ubuntu-latest needs: deploy_stage environment:
name: production url: https://app. example. com concurrency: prod-release steps:
- name: Manual approval gate run: echo "Requires environment approvers in repo settings"
- name: Promote canary → 100% (blue-green)
run:
helm upgrade --install app charts/app \
--set image. tag=${{ github. sha }} \
--set canary. enabled=false
- name: Post-deploy checks & rollback on SLO breach run:./scripts/verify_or_rollback. sh
Ключи:
  • `permissions` сведены к минимуму, включен `id-token: write` для OIDC.
  • Environments с approvers и URL, `concurrency` защищает от гонок.
  • Канареечное включение трафика и автоматический откат по SLO.

4.3 Reusable workflow (пример вызова)

yaml jobs:
security_suite:
uses: org/.github/.github/workflows/security. yml@v1 with:
severity_threshold: high

5) GitLab CI — структура и практики

5.1 Базовая структура

`.gitlab-ci.yml` в корне; ключевые сущности: `stages`, `jobs`, `rules`, `needs`, `artifacts`, `environments`, `manual`.
Reuse: `include:` (локальные/remote шаблоны), child/parent pipelines для сложных монорепо.

5.2 Пример: матрица, кэш, подпись, окружения и approvals

yaml stages: [lint, test, build, security, deploy]

variables:
DOCKER_TLS_CERTDIR: "" # docker: dind acceleration
IMAGE_TAG: $CI_COMMIT_SHA

lint:
stage: lint image: node:20 script:
- npm ci
- npm run lint cache:
key: "npm-${CI_COMMIT_REF_SLUG}"
paths: [node_modules/]
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"

test:
stage: test image: node:20 parallel:
matrix:
- NODE_VERSION: ["18", "20"]
script:
- nvm install $NODE_VERSION          true
- npm ci
- npm test -- --ci artifacts:
when: always reports:
junit: report. xml

build_image:
stage: build image: docker:26. 1 services: [ "docker:26. 1-dind" ]
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG.
- docker push $CI_REGISTRY_IMAGE:$IMAGE_TAG artifacts:
expire_in: 1 week paths: [ "sbom. json" ]
after_script:
- syft $CI_REGISTRY_IMAGE:$IMAGE_TAG -o cyclonedx-json > sbom. json

security_scans:
stage: security image: alpine:3. 20 script:
- trivy image --exit-code 0 --severity HIGH,CRITICAL $CI_REGISTRY_IMAGE:$IMAGE_TAG rules:
- if: '$CI_COMMIT_BRANCH == "main"'

deploy_stage:
stage: deploy image: bitnami/kubectl:1. 30 environment:
name: stage url: https://stage. example. com on_stop: stop_stage script:
- kubectl set image deploy/app app=$CI_REGISTRY_IMAGE:$IMAGE_TAG -n stage
-./scripts/smoke. sh needs: [build_image, security_scans]
when: manual allow_failure: false

stop_stage:
stage: deploy image: bitnami/kubectl:1. 30 environment:
name: stage action: stop script:
- kubectl rollout undo deploy/app -n stage

deploy_prod:
stage: deploy image: alpine/k8s:1. 30. 2 environment:
name: production url: https://app. example. com rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual allow_failure: false script:
-./scripts/canary_traffic. sh 10
-./scripts/verify_or_rollback. sh
Ключи:
  • `parallel.matrix` имитирует матричные сборки.
  • `artifacts` + отчеты тестов.
  • Environments с `on_stop`, ручные `when: manual` для approvals.
  • DIND для сборки образа (лучше — Kaniko/BuildKit в k8s-раннере).

5.3 Child pipelines и include для монорепо

yaml include:
- local:.gitlab/ci/includes/security. yml
- project: org/platform/pipelines file: /k8s/deploy. yml ref: v1

stages: [prepare, component_a, component_b, deploy]

component_a:
stage: component_a trigger:
include:.gitlab/ci/component_a. yml strategy: depend

component_b:
stage: component_b trigger:
include:.gitlab/ci/component_b. yml strategy: depend

6) Монорепозитории и многосервисность

Directory-based ownership: CODEOWNERS и scoped-тесты по путям.
Incremental builds: определяем затронутые пакеты/чарты; кэш по ключам путей и lock-файлам.
Dynamic pipelines: child-pipelines/`workflow_call` запускаются только для измененных компонентов.
Версионирование: semver по каждому модулю, changelog на release-этапе.

7) Кэширование и ускорение

Контент-адресные кэши (hashFiles/lockfile).
Раздельный кэш для зависимостей и артефактов.
Pre-warm runner images (toolchains, SDK).
Локальные зеркала пакетов (npm/pip/maven) и контейнерный registry-кеш.

8) Релизные стратегии и откат

Canary: постепенное наращивание процента трафика; авто-стоп при деградации SLO.
Blue-Green: параллельные стеки, мгновенное переключение.
Shadow: дублирование запросов без влияния на клиента.
Feature flags: rollout на уровне флага, а не релиза.
Rollback: четкие скрипты «одной кнопкой», версия артефакта хранится в метаданных релиза.

9) Инфраструктура и GitOps

IaC: Terraform/Ansible/Helm управляются в отдельных репо; policy-as-code как ворота.
GitOps-контур: Argo CD/Flux наблюдают репо с манифестами окружений; конвейер лишь создает артефакт и обновляет версии в Git.
Преимущества: явная история изменений окружения, идемпотентность, стандартные откаты через Git.

10) Наблюдаемость CI/CD

DORA-метрики: частота деплоев, время от коммита до продакшна, процент отказов, MTTR.
Telemetry: время очередей job’ов, длительность стадий, hit-rate кэша, частота flaky-тестов.
Логи безопасности: кто инициировал релиз, какие ворота пройдены, какие исключения выданы.

11) Управление доступом и approvals

Branch protection и обязательные проверки.
Environment-approvals: отдельные списки approvers на stage/prod.
JIT-доступ для ручных шагов, журналирование сессий.
Разделение обязанностей: разные роли для «пишет код», «одобряет», «выпускает».

12) Частые ошибки (анти-паттерны)

Долгоживущие облачные ключи в секретах репо вместо OIDC-ролей.
Сборка разных артефактов для stage и prod (нарушение «build once»).
`latest` теги и mutable-образы.
Публикация секретов в логах шагов (неотключенный masking).
Один общий public-runner для прод-деплоев.
Отсутствие «ворот» безопасности (SAST/SCA/Policy) и post-deploy проверок.

13) Чек-лист внедрения (0–60 дней)

0–15 дней

Настроить trunk-based, PR/MR правила, обязательные статические проверки.
Включить OIDC-федерацию к облаку; минимальные `permissions`.
Разнести runner’ы: публичные — для CI, приватные — для CD.

16–30 дней

Добавить SBOM, подпись образов; в кластере — проверка подписи.
Ввести canary/blue-green; авто-rollback по SLO.
Кэш зависимостей и артефактов, pre-warm образов.

31–60 дней

Разделить сборку и доставку (GitOps), policy-as-code ворота.
Наладить DORA-метрики и алерты по деградации пайплайнов.
Шаблонизировать пайплайны (reusable/child) для всех сервисов.

14) Практические советы по надежности

Поддерживайте маленькие, быстрые пайплайны (10–12 мин до сигнала на PR).
Убивайте flaky-тесты: quarantine-метки + параллельный фикс.
Не смешивайте CI-артефакты и release-артефакты; храните метаданные (commit, времени, SBOM, подписи).
Дайте разработчикам локальные скрипты, идентичные шагам конвейера (dev-prod parity).

15) Шаблоны для переиспользования

15.1 GitHub Actions — security reusable workflow (упрощенно)

yaml name: security-suite on:
workflow_call:
inputs:
severity_threshold:
type: string required: false default: high jobs:
sast_sca:
runs-on: ubuntu-latest steps:
- uses: actions/checkout@v4
- run:./sec/sast. sh --threshold ${{ inputs. severity_threshold }}
- run:./sec/sca. sh --format cyclonedx-json --out sbom. json artifacts: # if using actions/upload-artifact
- sbom. json

15.2 GitLab — включаемый шаблон deploy (упрощенно)

yaml
.deployment_template:
image: alpine/k8s:1. 30 script:
- helm upgrade --install $APP charts/$APP --set image. tag=$IMAGE_TAG rules:
- if: '$CI_COMMIT_BRANCH == "main"'

16) Заключение

GitHub Actions и GitLab CI предоставляют зрелые механизмы для быстрого и безопасного цикла «код → прод». Ключ к успеху — стандартизация и безопасность: OIDC вместо ключей, подпись и SBOM, ворота качества, единый артефакт с промоушеном, GitOps-доставка и наблюдаемость через DORA. Стройте пайплайны как продукт: измеряйте, упрощайте, ускоряйте — и релизы станут рутиной, а не событием.

Contact

Свяжитесь с нами

Обращайтесь по любым вопросам или за поддержкой.Мы всегда готовы помочь!

Telegram
@Gamble_GC
Начать интеграцию

Email — обязателен. Telegram или WhatsApp — по желанию.

Ваше имя необязательно
Email необязательно
Тема необязательно
Сообщение необязательно
Telegram необязательно
@
Если укажете Telegram — мы ответим и там, в дополнение к Email.
WhatsApp необязательно
Формат: +код страны и номер (например, +380XXXXXXXXX).

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