Как настраивал GitLab CI

Ответ

Я настраивал GitLab CI/CD для микросервисной архитектуры, где каждый сервис имел свой репозиторий, но общие требования к сборке, тестированию и деплою. Конфигурация строилась на принципах скорости, безопасности и воспроизводимости.

Пример .gitlab-ci.yml для Go-микросервиса, разворачиваемого в Kubernetes:

# 1. Определяем глобальные настройки и образы
default:
  image: golang:1.19-alpine
  before_script:
    - apk add --no-cache git
    - go version

# 2. Разбиваем pipeline на стадии
stages:
  - validate  # Линтинг, проверка зависимостей
  - test      # Unit и интеграционные тесты
  - build     # Сборка артефактов и Docker-образов
  - security  # Сканирование уязвимостей
  - deploy    # Деплой в окружения

# 3. Job'ы для каждой стадии

# 3.1 Валидация
lint:
  stage: validate
  script:
    - go mod tidy
    - go mod verify
    - go fmt ./...
    - go vet ./...
    - staticcheck ./...
  artifacts:
    when: always
    paths:
      - go.sum
    expire_in: 1 week

# 3.2 Тестирование с кэшированием зависимостей и сбором покрытия
test:
  stage: test
  script:
    - go test -race -coverprofile=coverage.txt -covermode=atomic ./...
  coverage: '/total:s*(statements)?s*d+.d+%/'
  artifacts:
    reports:
      cobertura: coverage.xml
    paths:
      - coverage.txt
  cache:  # Кэшируем модули Go для ускорения
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - .go/pkg/mod/

# 3.3 Сборка мультиархитектурного Docker-образа
build:
  stage: build
  image: docker:20.10
  services:
    - docker:20.10-dind
  variables:
    DOCKER_BUILDKIT: 1
    DOCKER_TARGET: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
  script:
    - |
      docker buildx create --use
      docker buildx build --platform linux/amd64,linux/arm64 
        --push 
        -t $DOCKER_TARGET 
        -f Dockerfile .
  only:
    - main
    - merge_requests

# 3.4 Сканирование образа на уязвимости с Trivy
trivy-scan:
  stage: security
  image: aquasec/trivy:latest
  variables:
    TRIVY_NO_PROGRESS: "true"
  script:
    - trivy image --exit-code 1 --severity HIGH,CRITICAL $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
  allow_failure: false  # Фейл пайплайна при критических уязвимостях

# 3.5 Деплой в staging через Helm
deploy-staging:
  stage: deploy
  image: alpine/helm:3.10
  environment:
    name: staging
    url: https://api-staging.example.com
  script:
    - helm upgrade --install 
        --namespace staging 
        --set image.tag=$CI_COMMIT_SHORT_SHA 
        --values .helm/values-staging.yaml 
        my-service .helm/
  only:
    - main

# 3.6 Ручное подтверждение для деплоя в production
deploy-production:
  stage: deploy
  image: alpine/helm:3.10
  environment:
    name: production
    url: https://api.example.com
  script:
    - helm upgrade --install 
        --namespace production 
        --set image.tag=$CI_COMMIT_SHORT_SHA 
        --values .helm/values-production.yaml 
        my-service .helm/
  when: manual  # Требует ручного подтверждения
  only:
    - main

Ключевые решения в этой конфигурации:

  • BuildKit и Buildx: Для мультиархитектурных сборок и эффективного кэширования слоев.
  • Кэширование зависимостей Go: Значительно ускоряет этап тестирования.
  • Security Scanning: Интеграция Trivy на ранней стадии для блокировки развертывания уязвимых образов.
  • Ручное подтверждение для production: Обязательный гейт для контроля над выпуском.
  • Environments: Использование встроенных окружений GitLab для отслеживания развертываний и их статусов.

Для управления общими шагами (например, деплоем Helm) я выносил их в шаблоны, подключаемые через include, как описано в предыдущем ответе.

Ответ 18+ 🔞

Э, слушай, вот это я понимаю — конфигурация! Не какая-то мартышлюшка из трёх строк, а нормальный, продуманный пайплайн. Прям видно, что человек не просто хуй с горы запилил, а реально думал головой, э бошка думай! Сейчас разберём, что тут к чему.

Первое, что бросается в глаза — структура. Чёткие стадии: проверили, протестировали, собрали, проверили безопасность, задеплоили. Всё логично, как по учебнику, только без учебнического занудства. before_script с установкой гита — мелочь, а приятно, не надо потом ебаться с тем, что зависимости не подтянутся.

Валидация (lint) — тут всё строго. go mod tidy, fmt, vet, staticcheck. Если код кривой — он сломается тут же, на берегу. И артефакты go.sum сохраняются, умно. Потому что если один джоб его поменял, а следующий будет с чистого листа — будет тебе хиросима и нигерсраки, всё разъедется.

Тестирование (test) — тут я оценил кэш для Go-модулей. Без этого каждый раз качать все зависимости — это ж пиздец, волнение ебать, пока всё скачается. А так — быстро. И покрытие собирают в формате, который GitLab умеет красиво показывать. Не просто "запустили и забыли".

А вот сборка (build) — это вообще песня! Используется docker buildx для мультиархитектурных образов. Смотри: один образ сразу и под обычные серверы (linux/amd64), и под ARM'ы (linux/arm64), которые сейчас везде лезут. И сразу пушится в registry. Красота! Раньше бы пришлось два образа отдельно собирать, овердохуища скриптов писать.

Безопасность (trivy-scan) — вот это критически важная штука! Образ сканируется на уязвимости (HIGH, CRITICAL), и если находит — пайплайн падает. allow_failure: false — это железно. Нельзя деплоить в прод с дырявым образом, это как вы ходите по охуенно тонкому льду. Лучше сломать сборку сейчас, чем потом ночью получать алерт, что сервис скомпрометировали.

Деплой — тут мудро разделили. В staging (deploy-staging) деплоится автоматом с каждого коммита в main. А вот в production (deploy-production) — стоит when: manual. То есть нужно ткнуть кнопку "Run". Это святое! Никакого авто-деплоя в прод без человеческого взгляда. Потому что доверия ебать ноль к автоматам, когда речь о продакшене. Всегда может вылезти какая-нибудь хитрая жопа, которую на стейджинге не отловили.

Ключевые решения, которые ты перечислил — это вообще золото.

  • BuildKit/Buildx — для скорости и мультиархитектурности. Без этого сейчас никуда.
  • Кэширование зависимостей Go — экономит кучу времени и нервов.
  • Security Scanning с Trivy — не как "для галочки", а как жёсткий гейт. Молодцом.
  • Ручное подтверждение для production — спасло уже, наверное, не один прод от пиздеца.
  • Environments в GitLab — чтобы прямо в интерфейсе видеть, что где задеплоено и какое состояние.

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

В общем, конфиг — огонь. Видно, что сделано с пониманием, а не просто "лишь бы работало". Так и надо делать.