lenec ru

← все посты

CI/CD на Gitea Actions: рабочая альтернатива GitHub

17K

Gitea Actions появились на стабильном уровне в Gitea 1.21 и за полтора года выросли до варианта, на котором я спокойно держу боевой CI. Расскажу, что это, чем отличается от GitHub Actions и где у меня живёт. Если у тебя есть причина не зависеть от GitHub (импортозамещение, своя инфраструктура, регуляторика) — Gitea это закрывает.

Что такое Gitea Actions

Это встроенная в Gitea система выполнения workflow-файлов в формате, совместимом с GitHub Actions. Те же .github/workflows/*.yml, тот же синтаксис uses, run, steps, matrix. Под капотом — act_runner, форк nektos/act, который умеет запускать GitHub-совместимые workflow в Docker.

Идея простая: ты переносишь репозиторий с GitHub в Gitea, кладёшь рядом .gitea/workflows/ или используешь .github/workflows/ — и CI начинает работать без переписывания.

Что работает

  • Все базовые шаги: checkout, setup-node, run, upload-artifact, download-artifact. Это покрывает 90% всех CI.
  • Matrix, jobs.needs, concurrency — поддерживается.
  • Сервисы (например, Postgres рядом с тестами) через services:.
  • Cache (через actions/cache) — поддерживается, есть встроенный сервер кэша.
  • Custom actions из marketplace, если они написаны на JS или Docker. Через настройку fetch_marketplace можно дотянуться до GitHub-marketplace или поднять свой.

Что не работает или работает иначе

  • Часть actions, которые жёстко привязаны к GitHub API (комментарии в PR, релизы). Большинство аналогов есть в виде Gitea-actions, но переписать пару шагов придётся.
  • Отчёты о тестах в UI — не такие красивые, как в GitHub. Но артефакты загружаются и скачиваются.
  • Reusable workflows и composite actions — поддерживаются, но в новых версиях; на 1.21 ловила баги, на 1.23+ нормально.
  • OIDC (federated authentication) пока ограничен. Если тебе нужен short-lived deploy токен через OIDC — пока нет.

Установка act_runner

Минимальный сетап на одной VPS, где уже стоит Gitea. Создаём отдельного пользователя:

sudo useradd --system --create-home --shell /bin/bash actrunner

Скачиваем бинарь act_runner:

cd /opt
wget https://gitea.com/gitea/act_runner/releases/download/v0.2.10/act_runner-0.2.10-linux-amd64
sudo mv act_runner-0.2.10-linux-amd64 /usr/local/bin/act_runner
sudo chmod +x /usr/local/bin/act_runner

Регистрируем runner. На странице админа Gitea (или owner-а репо) идёшь в Site Administration → Actions → Runners → Create new Runner, копируешь токен.

sudo -u actrunner act_runner register \
  --no-interactive \
  --instance https://git.example.ru \
  --token <runner_token> \
  --name builder-01 \
  --labels ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest

Лейбл ubuntu-latest:docker://... говорит runner-у: «когда workflow требует ubuntu-latest, используй вот этот образ». Я беру catthehacker/ubuntu — он близок к настоящему ubuntu-runner GitHub-а и содержит большинство нужных пакетов.

systemd-сервис runner-а

# /etc/systemd/system/act-runner.service
[Unit]
Description=Gitea Act Runner
After=docker.service
Requires=docker.service

[Service]
Type=simple
User=actrunner
WorkingDirectory=/home/actrunner
ExecStart=/usr/local/bin/act_runner daemon --config /home/actrunner/config.yaml
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Файл config.yaml у меня — слегка отредактированный дефолт:

log:
  level: info
runner:
  capacity: 2
  timeout: 3h
cache:
  enabled: true
  dir: /var/cache/actrunner
container:
  network: host
  privileged: false
  options: '--cpus=2 --memory=4g'

capacity: 2 — runner будет одновременно держать 2 job-а. Подбирай по CPU/RAM сервера. cache.enabled включает встроенный кэш-сервер для actions/cache. Без него кэш не работает или работает в обходной ветке.

Простой workflow

.gitea/workflows/ci.yml:

name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
        with: { version: 9 }
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'
      - run: pnpm install --frozen-lockfile
      - run: pnpm test
      - run: pnpm build

Это работает один в один как на GitHub. Если у тебя workflow уже есть — переезд занимает минуты.

Сервисы для тестов

jobs:
  integration:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: test
          POSTGRES_DB: test
        ports: ['5432:5432']
        options: --health-cmd 'pg_isready -U postgres' --health-interval 10s --health-timeout 5s --health-retries 5
    steps:
      - uses: actions/checkout@v4
      - run: pnpm install --frozen-lockfile
      - env:
          DATABASE_URL: postgres://postgres:test@postgres:5432/test
        run: pnpm test:integration

Здесь обращаю внимание на options: --health-cmd. Без health-check job стартует тесты сразу, до того как Postgres готов. Иногда это работает, иногда — flaky. Health-check экономит часы отладки.

Деплой через workflow

Стандартный паттерн: build → push в registry → ssh-команда на VPS → systemctl restart. На Gitea Actions это собирается так:

jobs:
  deploy:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v4
      - name: Build and push
        run: |
          echo '${{ secrets.REGISTRY_PASSWORD }}' | docker login registry.example.ru -u '${{ secrets.REGISTRY_USER }}' --password-stdin
          docker build -t registry.example.ru/myapp/api:${{ github.sha }} .
          docker push registry.example.ru/myapp/api:${{ github.sha }}
      - name: Deploy
        env:
          SSH_KEY: ${{ secrets.DEPLOY_KEY }}
        run: |
          mkdir -p ~/.ssh
          echo "$SSH_KEY" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          ssh-keyscan srv.example.ru >> ~/.ssh/known_hosts
          ssh deploy@srv.example.ru "cd /opt/myapp \
            && export VERSION=${{ github.sha }} \
            && docker compose pull api \
            && docker compose up -d --no-deps api"

Секреты в Gitea кладутся через UI: Repository Settings → Actions → Secrets. Там же — переменные окружения, которые менее чувствительны.

Сравнение с GitHub Actions

Скорость

На моей VPS act_runner крутится в среднем не быстрее, чем GitHub-runner. Если поставить runner на shared-VPS со слабым CPU, будет ощутимо медленнее. Если выделить отдельную машину с быстрым диском — сравнимо.

Стоимость

На приватных репозиториях GitHub даёт 2000 минут в месяц на free, дальше платно. Gitea Actions полностью бесплатны, ограничены только своим железом. На больших командах с активным CI это разница ощутимая.

Свобода и контроль

Самое главное преимущество. Никакие изменения в политике GitHub не трогают твой CI. Можно ставить runner-ы во внутренней сети, тестировать с доступом к корпоративным сервисам без VPN-туннелей. На частных проектах это бывает решающим фактором.

Экосистема

На GitHub marketplace больше готовых actions, и они часто свежее. На Gitea ты или используешь GitHub-actions через прокси, или пишешь свои. Большинство ходовых (checkout, setup-node, cache, upload-artifact) есть и работают.

Подводные камни

Docker внутри Docker

act_runner запускает workflow в контейнере. Если ты в workflow делаешь docker build, нужен docker-in-docker или docker.sock пробросить. Я делаю так:

# config.yaml act_runner-а
container:
  valid_volumes:
    - /var/run/docker.sock
  options: '-v /var/run/docker.sock:/var/run/docker.sock'

В workflow используешь docker как обычно. На security-критичных проектах это нежелательно: контейнер с доступом к docker.sock — фактически root на хосте. Альтернатива — отдельный buildkit или buildx-сервис.

Слишком тяжёлый образ ubuntu

act_runner по умолчанию подтягивает образ catthehacker/ubuntu в полной комплектации (~10 GB). Первый запуск будет долгим. На своём CI я часто использую act-22.04 или slim-вариант.

Кэш на больших артефактах

Встроенный кэш-сервер хранит файлы локально на диске. Если у тебя огромные node_modules или большие артефакты, диск runner-а может неожиданно кончиться. Поставь периодическую очистку через cron или ограничь размер кэша в config.

Версии Gitea

Gitea Actions активно развивается. Проверяй changelog при апгрейдах: на 1.22 кое-какие синтаксические особенности изменились. Если у тебя сложный workflow, после апгрейда прогоняй тестовый прогон.

Когда я беру Gitea Actions

  • Внутренние корпоративные проекты, которым нельзя на внешний CI.
  • Сервисы с регуляторными требованиями к локализации.
  • Команды с большим объёмом CI-минут, которые упёрлись в платный план GitHub.
  • Проекты, где разработка идёт в Gitea и переход на GitHub — лишний шаг.

Когда оставляю GitHub Actions

  • OSS-проекты с публичной видимостью.
  • Команды, которым важна экосистема готовых action-ов.
  • Стартапы, у которых нет ресурса поддерживать свой CI-инфраструктуру.

Для меня Gitea Actions сейчас — это альтернатива, к которой я прихожу с конкретной причиной, а не дефолт. Но как опция — рабочая, проверенная и бесплатная. На двух своих сервисах её гоняю год без сюрпризов.

Комментарии 0

  • Будьте первым, кто оставит комментарий.

Войдите, чтобы оставить комментарий.