# CI/CD бэкенда через Gitea Actions (встроенный в Gitea, раннер на сервере). # # push/PR: go vet → накат миграций в сервисную postgres → go test -race → # go build; параллельно golangci-lint; затем сборка прод-образа api # (локальные теги latest и короткий SHA, реестр не используется). # Деплой — ТОЛЬКО ручной запуск workflow (кнопка Run workflow): compose-файлы # берутся из дерева этого же коммита (actions/checkout), секреты не нужны. # web перезапускает свой workflow в репо веба — репозитории независимы. # # Требования к раннеру (см. README, раздел «CI/CD (Gitea Actions)»): # runner.labels: [docker] — совпадает с runs-on ниже; # container.valid_volumes: /var/run/docker.sock, /opt/building-mgmt — # сокет docker для сборки/деплоя и каталог стека с .env. name: backend on: push: branches: [main] pull_request: workflow_dispatch: jobs: test: runs-on: docker container: golang:1.27 # Сервисная база для интеграционных тестов: схему накатывает шаг # test (cmd/migrate), тесты выполняют сценарии в транзакции и # откатывают их — данные в базе не остаются. services: postgres: image: postgres:16-alpine env: POSTGRES_USER: building POSTGRES_PASSWORD: building POSTGRES_DB: building_mgmt_test env: DATABASE_URL: postgres://building:building@postgres:5432/building_mgmt_test?sslmode=disable steps: - uses: actions/checkout@v4 - name: go vet run: go vet ./... - name: Накат миграций (ждём сервисную postgres) # Postgres поднимается параллельно с контейнером джобы: # повторяем накат, пока база не готова (30 попыток по 2 секунды). run: | ok=0; for i in $(seq 1 30); do if go run ./cmd/migrate; then ok=1; break; fi; sleep 2; done; test "$ok" = 1 - name: Тесты # -race требует CGO — полный golang-образ, не alpine. run: go test -race -count=1 ./... - name: Сборка run: go build ./... lint: runs-on: docker container: ghcr.io/golangci/golangci-lint:v2.14.0 steps: - uses: actions/checkout@v4 - name: golangci-lint run: golangci-lint run ./... build-api: runs-on: docker container: docker:27-cli steps: - uses: actions/checkout@v4 - name: Сборка прод-образа api # Образ и два тега: latest (его поднимает compose.prod.yaml) и # короткий SHA (для отката: перетегнуть latest вручную). run: | short="$(echo "$GITHUB_SHA" | cut -c1-7)" docker build -t building-mgmt-api:latest -t "building-mgmt-api:${short}" . deploy: if: github.event_name == 'workflow_dispatch' needs: build-api runs-on: docker container: docker:27-cli steps: - uses: actions/checkout@v4 - name: Подъём db/minio/api стека # compose-CLI ставим в джоб-контейнер; docker — через смонтированный # сокет хоста (valid_volumes у раннера). -p закрепляет имя проекта: # оно задаёт имя сети, и web из своего workflow находит api. # web не трогаем — его перезапускает workflow репо веба. run: | apk add --no-cache docker-cli-compose docker compose -p building-mgmt \ --env-file /opt/building-mgmt/.env \ -f compose.prod.yaml \ up -d --wait db minio api