CI/CD для Go проектов: GitHub Actions от А до Я
В современной разработке программного обеспечения автоматизация процессов сборки, тестирования и развертывания (CI/CD) стала не просто удобством, а необходимостью. Для проектов на Go (Golang) использование GitHub Actions — это один из самых простых и эффективных способов организовать непрерывную интеграцию и доставку. В этой статье мы разберем полный цикл настройки CI/CD пайплайна для Go-приложений, начиная с базовой конфигурации и заканчивая автоматическим деплоем.
Что такое GitHub Actions и почему это важно для Go?
GitHub Actions — это встроенная платформа для автоматизации рабочих процессов (workflows) в репозиториях GitHub. Она позволяет создавать пайплайны, которые срабатывают на определенные события: push в ветку, создание pull request, публикация релиза и т.д.
Для Go-проектов GitHub Actions предлагает несколько ключевых преимуществ:
- Быстрая компиляция — Go компилируется очень быстро, что сокращает время выполнения пайплайна.
- Статическая линковка — Go-бинарники не требуют внешних зависимостей, что упрощает деплой.
- Встроенное тестирование — утилита
go testотлично интегрируется с CI-системами. - Кроссплатформенность — легко собирать бинарники под разные ОС и архитектуры.
Настройка базового CI пайплайна
Начнем с создания простого workflow, который будет запускать тесты и проверять код на соответствие стандартам Go. Для этого в корне вашего репозитория создайте директорию .github/workflows и файл ci.yml.
Пример базовой конфигурации:
name: CI Pipeline for Go
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Cache Go modules
uses: actions/cache@v4
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Download dependencies
run: go mod download
- name: Run vet
run: go vet ./...
- name: Run tests
run: go test -v -race -count=1 ./...
- name: Build
run: go build -o myapp ./cmd/app
Этот workflow выполняет следующие шаги:
- Клонирует репозиторий.
- Устанавливает Go версии 1.22.
- Кэширует модули для ускорения последующих запусков.
- Загружает зависимости через
go mod download. - Запускает
go vetдля статического анализа. - Выполняет тесты с флагом
-raceдля обнаружения гонок данных. - Собирает бинарный файл.
Продвинутая конфигурация: кроссплатформенная сборка и линтеры
Go позволяет легко собирать приложения для разных платформ. Добавим в пайплайн матрицу сборки (build matrix) и запуск линтера golangci-lint.
Обновленный файл ci.yml:
name: Advanced Go CI/CD
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: golangci-lint
uses: golangci/golangci-lint-action@v4
with:
version: latest
args: --timeout=5m
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./...
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
file: ./coverage.txt
build:
needs: [lint, test]
runs-on: ubuntu-latest
strategy:
matrix:
goos: [linux, darwin, windows]
goarch: [amd64, arm64]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Build for ${{ matrix.goos }}/${{ matrix.goarch }}
run: |
GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} \
go build -o myapp-${{ matrix.goos }}-${{ matrix.goarch }} ./cmd/app
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: myapp-${{ matrix.goos }}-${{ matrix.goarch }}
path: myapp-${{ matrix.goos }}-${{ matrix.goarch }}
Что мы добавили:
- Линтер — отдельная джоба для
golangci-lint, которая проверяет стиль кода и потенциальные ошибки. - Покрытие кода — тесты с генерацией отчета и отправкой в Codecov.
- Матрица сборки — параллельная сборка для Linux, macOS и Windows на архитектурах amd64 и arm64.
- Артефакты — сохранение собранных бинарников для последующего использования.
Автоматический деплой с GitHub Actions и Docker
Финальный этап — непрерывная доставка (CD). Рассмотрим деплой Go-приложения в Docker-образ и публикацию в Docker Hub или GitHub Container Registry.
Создайте файл Dockerfile в корне проекта:
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
FROM alpine:3.19
RUN apk --no-cache add ca-certificates tzdata
WORKDIR /root/
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]
Теперь добавим workflow для деплоя:
name: Deploy to Docker Hub