Ах, CI/CD-пайплайны — магические конвейеры, которые превращают наши хаотичные коммиты кода в отполированные производственные артефакты. Давайте создадим такой, который заставил бы даже талисмана Go — гофера — весело танцевать. Я обещаю, что это не будет ещё одним туториалом «Hello World» — мы создаём пайплайн, который действительно выполняет полезную работу, сохраняя вашу кодовую базу здоровее, чем запас чайного гриба у хипстера.
Набор инструментов гофера: предварительные требования
Перед тем как начать наше веселье с пайплайнами, вам понадобятся:
- Учётная запись GitLab (бесплатный уровень подойдёт);
- Проект на Go, который хотя бы немного интересен;
- Установленный Docker (потому что контейнеры — это сегодняшние транспортные контейнеры);
- Кофемашина в пределах 10 шагов (необязательно, но рекомендуется).
Шаг 1: Настройка проекта в стиле гофера
Создайте .gitlab-ci.yml
в корне вашего проекта — это ДНК нашего пайплайна. Начнём с чего-то, что заставило бы Роба Пайка одобрительно кивнуть:
image: golang:1.21-alpine
stages:
- dependencies
- build
- test
- lint
- deploy
variables:
GOPROXY: "https://proxy.golang.org"
GOFLAGS: "-mod=readonly"
Эта основа даёт нам стройность Alpine и правильную конфигурацию модулей Go. Этапы представляют жизненный цикл нашего пайплайна — от управления зависимостями до развёртывания.
Симфония пайплайна
Давайте визуализируем наш шедевр:
Это гарантирует, что мы не развернём код, который либо сломан, либо стилистически оскорбителен. Теперь давайте наполним каждый этап заданиями, которые действительно оправдывают своё существование.
Управление зависимостями: Этап взросления
resolve_dependencies:
stage: dependencies
script:
- go mod download
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- .cache/go-build
- go/pkg/mod
Это задание подобно ответственному соседу по комнате — оно загружает зависимости один раз и кэширует их для будущих запусков. Ключ кэша гарантирует, что разные ветки не будут мешать друг другу.
Сборка и тестирование: Где резина встречается с дорогой
build_binary:
stage: build
script:
- go build -v -ldflags "-s -w" -o my-app
artifacts:
paths:
- my-app
Наше задание по сборке компилирует двоичный файл с оптимизацией размера и сохраняет его как артефакт. Теперь для тестового набора:
run_tests:
stage: test
script:
- go test -v -race ./...
coverage: '/^coverage: \d+\.\d+\% of statements/'
artifacts:
reports:
cobertura: coverage.xml
Это запускает тесты с обнаружением гонок и собирает данные о покрытии. Регулярное выражение coverage
заставляет GitLab отображать красивые значки покрытия — потому что метрики важны!
Linting: Спа-процедуры для кода
golangci_lint:
stage: lint
image: golangci/golangci-lint:latest
script:
- golangci-lint run --out-format checkstyle ./... > report.xml
artifacts:
reports:
codequality: report.xml
Используя официальный образ линтера, это задание проводит полную спа-процедуру для вашего кода. Формат checkstyle хорошо интегрируется с отчётами GitLab о качестве кода.
Развёртывание: Освободите гофера!
deploy_production:
stage: deploy
image: docker:20.10
services:
- docker:20.10-dind
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
script:
- docker build -t $IMAGE_TAG .
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $IMAGE_TAG
only:
- main
Это задание по развёртыванию на базе Docker запускается только при коммитах в ветку main. Оно собирает, помечает тегом и отправляет ваш контейнеризированный Go-приложение в реестр GitLab. Про-совет: добавьте --pull
к аргументам сборки, чтобы избежать устаревших базовых образов.
Оптимизация пайплайна: Турбо-режим
- Параллельное тестирование: Разбейте ваш тестовый набор на несколько заданий, используя
parallel
иgo test -shuffle
. - Предварительный подогрев кэша: Добавьте запланированный пайплайн, который обновляет зависимости ежедневно.
- Многоступенчатые сборки: Используйте
--target
Docker для создания компактных производственных образов. - Управление секретами: Используйте маскированные переменные GitLab для учётных данных.
- Запуск пайплайна: Добавьте
rules
, чтобы предотвратить ненужные сборки при изменении документации.
Когда что-то идёт не так: Советы по отладке
- Доступ к оболочке: Используйте
SSH в работающие задания
для отладки в реальном времени. - Исследование артефактов: Загрузите артефакты сборки, чтобы проверить двоичные файлы.
- Локальное тестирование: Запустите
gitlab-runner exec docker your-job
для локальной проверки. - Визуализация зависимостей: Добавьте задание
go mod graph
, чтобы отслеживать отношения между модулями.
Финальное countdown
Помните: хороший пайплайн — как надёжный друг — он сообщает, когда что-то не так, но не докучает по мелочам. Наш финальный пайплайн будет:
- Поддерживать актуальность зависимостей.
- Соблюдать стандарты качества кода.
- Обеспечивать покрытие тестами.
- Создавать готовые к производству артефакты.
- Развёртывать безопасно и повторяемо.
Теперь вперёд и создавайте пайплайны! И помните — если ваш CI занимает больше времени, чем перерыв на кофе, вы делаете что-то не так. Сохраняйте спокойствие и включайте CI/CD!