Введение: Почему CI/CD важен для Go проектов
Современная разработка на Go (Golang) требует не только написания чистого и эффективного кода, но и настройки процессов, которые автоматизируют проверку, сборку и доставку приложений. CI/CD (Continuous Integration / Continuous Delivery) — это набор практик, позволяющий быстро и безопасно поставлять изменения в продакшн. Для Go-разработчиков GitHub Actions стал одним из самых популярных инструментов благодаря тесной интеграции с репозиториями и простоте настройки.
В этой статье мы разберём, как создать полноценный CI/CD пайплайн для Go-проекта с использованием GitHub Actions. Вы узнаете, как автоматизировать тестирование, сборку бинарных файлов и деплой на сервер. Все примеры будут на Go (Golang) с практическими шагами.
1. Основы GitHub Actions для Go
GitHub Actions — это встроенная система автоматизации рабочих процессов (workflows). Каждый workflow представляет собой YAML-файл, который описывает шаги сборки, тестирования и развёртывания. Для Go-проектов минимальный пайплайн включает:
- Установку Go
- Кэширование зависимостей
- Запуск тестов
- Сборку приложения
Структура workflow-файла
Создайте в корне репозитория директорию .github/workflows/ и файл ci.yml. Вот базовая конфигурация для Go:
name: CI для Go проекта
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Установка Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Кэширование модулей
uses: actions/cache@v3
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Загрузка зависимостей
run: go mod download
- name: Линтинг кода
run: go vet ./...
- name: Запуск тестов
run: go test -v -race -coverprofile=coverage.out ./...
- name: Сборка бинарного файла
run: go build -o myapp ./cmd/main.go
Этот workflow запускается при пуше в main или develop, а также при создании pull request. Он проверяет код на ошибки, запускает тесты с флагом race (детектор гонок данных) и собирает бинарник.
2. Расширенный пайплайн: тестирование и качество кода
Базовая проверка — это хорошо, но для серьёзного Go-проекта нужно больше. Добавим статический анализ и проверку покрытия кода.
Добавление golangci-lint
golangci-lint — это агрегатор линтеров, который включает в себя go vet, errcheck, staticcheck и другие. Добавим его в workflow:
- name: Установка golangci-lint
uses: golangci/golangci-lint-action@v4
with:
version: latest
- name: Запуск линтера
run: golangci-lint run ./...
Отчёт о покрытии кода
Покрытие тестами — важный метрика качества. GitHub Actions может генерировать отчёты и даже блокировать PR при низком покрытии:
- name: Генерация отчёта о покрытии
run: go test -coverprofile=coverage.out -covermode=atomic ./...
- name: Проверка минимального покрытия
run: |
go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//' > coverage.txt
if [ $(cat coverage.txt) -lt 70 ]; then
echo "Покрытие кода меньше 70%"
exit 1
fi
Теперь workflow будет падать, если покрытие тестами падает ниже 70%. Это отличная практика для поддержания качества Go-проекта.
3. Сборка и публикация Docker-образа
Go-приложения часто деплоятся в виде Docker-контейнеров. GitHub Actions позволяет автоматически собирать образы и публиковать их в Docker Hub или GitHub Container Registry.
Сборка Docker-образа в CI
Сначала создайте 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 myapp ./cmd/main.go
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/myapp .
EXPOSE 8080
CMD ["./myapp"]
Теперь добавим шаг сборки и публикации в workflow. Для аутентификации используем секреты GitHub:
- name: Логин в Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Сборка и пуш Docker-образа
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ secrets.DOCKER_USERNAME }}/myapp:latest
${{ secrets.DOCKER_USERNAME }}/myapp:${{ github.sha }}
Также можно использовать GitHub Container Registry (ghcr.io). Для этого измените логин на docker.pkg.github.com и используйте токен GitHub.
4. Деплой на сервер через SSH
Финальный этап — развёртывание приложения на production-сервере. GitHub Actions поддерживает деплой через SSH, что удобно для небольших Go-проектов.
Настройка SSH-ключа
Добавьте приватный ключ в секреты репозитория (Settings → Secrets → Actions → New secret → SSH_PRIVATE_KEY). Публичный ключ должен быть добавлен на сервер в ~/.ssh/authorized_keys.
Шаг деплоя
- name: Деплой на сервер
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /opt/myapp
docker pull ${{ secrets.DOCKER_USERNAME }}/myapp:latest
docker stop myapp || true
docker rm myapp || true
docker run -d --name myapp -p 8080:8080 \
-e "DB_URL=${{ secrets.DB_URL }}" \