Введение в CI/CD для Go проектов
Современная разработка на Go (Golang) требует не только качественного кода, но и надёжной автоматизации процессов сборки, тестирования и развёртывания. CI/CD (Continuous Integration / Continuous Deployment) — это подход, который позволяет автоматически проверять каждое изменение в коде, запускать тесты и доставлять готовое приложение пользователям. В этой статье мы подробно разберём, как настроить CI/CD пайплайн для Go проектов с помощью GitHub Actions.
GitHub Actions — это встроенная система CI/CD, которая позволяет создавать рабочие процессы (workflows) прямо в репозитории GitHub. Для Go-разработчиков это особенно удобно, так как не требует настройки внешних сервисов и легко интегрируется с существующей инфраструктурой.
Почему именно GitHub Actions для Go?
- Бесплатно для публичных репозиториев — до 2000 минут сборок в месяц бесплатно
- Встроенная поддержка Go — официальные экшены для настройки окружения
- Гибкость — можно запускать на Ubuntu, Windows, macOS
- Кэширование — ускорение сборок за счёт кэша Go modules
- Матричное тестирование — параллельный запуск на разных версиях Go
Создание базового CI/CD пайплайна
Начнём с создания простого workflow, который будет запускаться при каждом push в репозиторий. Для этого нужно создать файл .github/workflows/go.yml в корне вашего проекта.
Пример базового workflow
name: Go CI/CD
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
go-version: [ '1.21', '1.22' ]
steps:
- uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
- name: Cache Go modules
uses: actions/cache@v3
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Install dependencies
run: go mod download
- name: Build
run: go build -v ./...
- name: Test
run: go test -v -race -coverprofile=coverage.txt ./...
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
file: ./coverage.txt
flags: unittests
Этот workflow делает следующее:
- Запускается при push в main/develop или при создании pull request
- Тестирует на двух версиях Go (1.21 и 1.22)
- Кэширует модули для ускорения последующих сборок
- Собирает проект и запускает тесты с флагами
-race(детектор гонок) и-cover(покрытие кода) - Загружает отчёт о покрытии в Codecov
Продвинутые настройки: линтинг и безопасность
Для профессионального Go-проекта недостаточно просто собрать и протестировать код. Добавим статический анализ и проверку безопасности.
Добавление линтинга с golangci-lint
- name: Lint
uses: golangci/golangci-lint-action@v3
with:
version: latest
args: --timeout=5m --out-format=colored-line-number
skip-pkg-cache: true
golangci-lint объединяет десятки линтеров (govet, staticcheck, errcheck и другие) и выдаёт единый отчёт. Это помогает находить потенциальные ошибки, неиспользуемый код и проблемы со стилем.
Проверка безопасности с govulncheck
- name: Check vulnerabilities
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
Утилита govulncheck анализирует зависимости проекта на наличие известных уязвимостей из базы Go Vulnerability Database. Это критически важно для production-проектов.
Автоматическая сборка и публикация Docker образа
Один из самых популярных способов деплоя Go-приложений — использование Docker. Настроим автоматическую сборку образа и публикацию в Docker Hub или GitHub Container Registry.
Пример Dockerfile для Go приложения
# Stage 1: Build
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server ./cmd/server
# Stage 2: Run
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]
Workflow для сборки и публикации Docker образа
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ secrets.DOCKER_USERNAME }}/my-go-app:latest
${{ secrets.DOCKER_USERNAME }}/my-go-app:${{ github.sha }}
Обратите внимание на использование secrets для хранения паролей — это стандартная практика безопасности. Все чувствительные данные должны храниться в настройках репозитория GitHub (Settings → Secrets and variables → Actions).
Матричное тестирование и параллельные сборки
GitHub Actions позволяет запускать тесты на разных операционных системах и версиях Go параллельно. Это гарантирует, что ваше приложение работает везде одинаково.
Пример матрицы для кросс-платформенного тестирования
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
go-version: ['1.21', '1.22']
exclude:
- os: windows-latest
go-version: '1.21'
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name