Расскажите о вашем опыте настройки и использования CI/CD для Go-проектов.

Ответ

Это отличный шаблонный ответ, который можно адаптировать под свой реальный опыт.


На моих проектах мы выстраивали CI/CD пайплайны, как правило, с использованием GitLab CI/CD или GitHub Actions. Основная цель — полная автоматизация от коммита до развертывания в production.

Процесс обычно состоял из следующих этапов (stages):


  1. Lint & Static Analysis: Первый и самый быстрый этап. Мы использовали golangci-lint для проверки стиля кода, поиска ошибок и потенциальных проблем. Это позволяет отсечь ошибки до начала тестов.


  2. Test: На этом этапе запускались все виды тестов:

    • Unit-тесты: go test ./... -v
    • Проверка на состояние гонки (race condition): go test ./... -race
    • Анализ покрытия кода: go test ./... -coverprofile=coverage.out. Результаты часто загружались в инструменты вроде SonarQube или Codecov для анализа динамики покрытия.
  3. Build: Сборка артефакта. Для Go-сервисов это обычно статически скомпилированный бинарный файл, который упаковывается в Docker-образ. Мы использовали многоступенчатые (multi-stage) Docker-сборки, чтобы итоговый образ был минимальным и безопасным:

    • Этап сборки (build stage): использовал полный образ Go для компиляции приложения.
    • Итоговый этап (final stage): копировал скомпилированный бинарник в минимальный образ, например, scratch или alpine.
  4. Deploy: Развертывание приложения. Процесс отличался для разных окружений:

    • Staging/Dev: Деплой происходил автоматически после успешного слияния в main или develop ветку. Обычно мы использовали Helm для управления релизами в Kubernetes.
    • Production: Деплой инициировался вручную (manual trigger в GitLab/GitHub) или по тегу. Иногда применяли стратегии Canary или Blue-Green для минимизации рисков.

Пример .gitlab-ci.yml:

stages:
  - test
  - build
  - deploy

lint-and-test:
  stage: test
  image: golang:1.21
  script:
    - go mod download
    - go test ./... -race -cover
    - go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
    - golangci-lint run

build-image:
  stage: build
  script:
    # $CI_REGISTRY_IMAGE и $CI_COMMIT_SHA - переменные GitLab CI
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

deploy-staging:
  stage: deploy
  environment: staging
  script:
    - helm upgrade --install my-app ./charts --set image.tag=$CI_COMMIT_SHA
  only:
    - main # Запускать только для ветки main

Ключевые инструменты и практики:

  • Контейнеризация: Docker.
  • Оркестрация: Kubernetes.
  • Управление релизами: Helm.
  • Мониторинг и алертинг: Prometheus для сбора метрик, Grafana для дашбордов и Alertmanager для оповещений.