Хотелось бы восполнить скромную пустоту в литературе по Gitea. С версии 1.19 в Gitea появился свой CI/CD и раннер Act Runner, являющийся ничем иным как форком всем знакомого nextos/act-runner.
Собственно говоря, с Gitea я был знаком достаточно давно, и использовал его в своих любительских целях более года, а вот к Gitea CI/CD руки мои дошли только сейчас, и сразу же меня спохватил зуд перенести свой самописный пайплайн по развертке сайта на базе MkDocs на него.
Кроме того, интересно будет пронаблюдать: упрется ли в потолок наконец-то мой VPS с 2 гигабайтами ОЗУ, или же нет? Насколько вообще Gitea вместе с одним инстансом раннера будет прожороливым?
Постановка
Задача для нашего CI/CD до отвращения проста и банальна:
есть сайт, написанный на MkDocs, и есть python скрипт(ы), генерирующие часть Markdown кода, которые нужно сначала запустить;
сайт собирается при помощи команды
mkdocs build
в статику, аккуратно сложенную в субдиректорииsite
;статику нужно залить на сервер в определенную папку по SSH, используя SCP или rsync.
И Все! Вместо MkDocs здесь мог бы быть любой известный JS фреймворк вроде React или Angular.
Gitea и Docker Compose
Gitea был с самого начала развернут при помощи Docker Compose вместе с SSHing Shim (см. гайд). Компоуз до боли стандартный:
version: '3.9'
services:
app:
container_name: gitea-app
restart: always
image: gitea/gitea:1.20 # ≥ 1.19
volumes:
- ./data/gitea:/data
- /home/git/.ssh/:/data/git/.ssh
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "127.0.0.1:2222:22"
- "127.0.0.1:3000:3000"
environment:
- GITEA__repository__ENABLE_PUSH_CREATE_USER=true
- GITEA__repository__ENABLE_PUSH_CREATE_ORG=true
- GITEA__server__SSH_PORT=22
- GITEA__server__SSH_LISTEN_PORT=22
- VIRTUAL_HOST=https://git.mydomain.tld
- ROOT_URL=https://git.mydomain.tld
- USER_UID=1003
- USER_GID=1003
networks:
- gitea
...
Прикрутить к нему раннер оказалось довольно просто:
В конфиге Gitea нужно добавить строчку
[actions]
ENABLED = true
И в наш компоуз добавить шаблон из официального гайда:
...
act-runner:
container_name: gitea-runner
restart: always
depends_on:
- app
image: gitea/act_runner:latest # или nightly
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./runner-data:/data
environment:
- GITEA_RUNNER_REGISTRATION_TOKEN=<<Токен>>
- GITEA_INSTANCE_URL=https://git.mydomain.tld
# можно и http://192.x.x.x:3000, но не имя сервиса
- GITEA_RUNNER_NAME=runner
networks:
- gitea
...
Токен берем в зависимости от того, где мы хотими, чтобы runner был доступен:
— На глобальном уровне: Settings -> Site administration -> Actions -> Runners -> Create new Runner и копируем REGISTRATION TOKEN
;
— На уровне организации: вкладка организации -> Settings -> Actions -> Runners -> Create new Runner и копируем REGISTRATION TOKEN
;
— На уровне репозитория: вкладка репозитория -> Settings -> Actions -> Runners -> Create new Runner и копируем REGISTRATION TOKEN
.
Токен подставляем в переменную GITEA_RUNNER_REGISTRATION_TOKEN
нашего сервиса act-runner
.
Когда в разделе раннеров появится строка с новым инстансом Act Runner, мы можем писать наш первый Gitea Actions скрипт.
Используем Actions
Недолго думая пришел, то есть пытаясь долго подобрать минимально работающий скрипт, я пришел к первому варианту:
# .gitea/workflows/publish.yml
name: Publish site
run-name: ${{ gitea.actor }} greets Habr!
on: [push]
jobs:
build and deploy:
runs-on: ubuntu-latest
name: Build and deploy
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
architecture: 'x64'
- name: Mkdocs build
run: |
pip install -r requirements.txt
python generate.py
mkdocs build
- name: Deploy to Server
uses: https://gitea.com/aquelle1/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY }}
ARGS: "-rlgoDzvc -i --delete" # рекурсивно, копируя сим. ссылки, сохраняя группы и оунеров; файлы устройств, а также сжимая файлы при передаче и сохраняя список файлов и удаляя файлы из искомой директории
SOURCE: "site/"
REMOTE_HOST: ${{ secrets.SSH_HOST }}
REMOTE_USER: ${{ secrets.SSH_USER }}
TARGET: ${{ secrets.SSH_DIR }}
Да, Gitea использует тот же самый формат, что и GitHub Actions. Собственно говоря, это он и есть. Секретные переменные secrets
задаются в Репозиторий -> Settings -> Actions -> Secrets. По умолчанию Gitea берет все actions из своего собственного сайта gitea.com, но можно конечно вставить на свой страх и риск actions из Github, просто прописав путь к репозиторию@ветка
.
Попытка № 1 провалилась на этапе установки Python3.9 с таким сообщением:
::group::Installed versions
Version 3.9 was not found in the local cache
::error::The version '3.9' with architecture 'x64' was not found for this operating system.%0AThe list of all available versions can be found here: https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json
М-да, и вроде бы проверил версию ubuntu, использующуюся раннером, но всякие попытки поменять версию не увенчались успехом.
Меняем дефолтный Docker образ раннера
Оказалось, что по умолчанию, если не указать в компоузе раннера переменную GITEA_RUNNER_LABELS
, то он будет по умолчанию использовать лейбл ubuntu-latest:docker://node:16-bullseye
(образ, в котором нет Docker), и поставить Python на этот образ никак нельзя.
Тем не менее, не все так плохо. Есть несколько вариантов.
Можно поменять дефолтный лейбл для раннера в панели Site administration -> Actions -> Runners -> Edit и перезаписать существующий лейбл на новый. Синтаксис у лейблов такой:
{тип хостовой ВМ, на которой будет запускаться джоба}:{имя Docker образа, в котором будет работать пайплайн}
. Тип хостовой ВМ может бытьubuntu-latest
,windows- latest
илиmacOS-latest
. Лейблы разделяются запятыми.Можно просто добавить строчку
container
в конфиг нашего пайплайна. Например:
container:
image: catthehacker/ubuntu:act-22.04
Альтернативой дефолтного образа был catthehacker/ubuntu:runner-22.04 с установленной Ubuntu 22.04. Весит он 510 мегабайт, что для меня было терпимо.
На этом образе Python успешно установился; сайт собрался и успешно улетел на сервер. Ура!
Enhancement & Benchmarks
До полного счастья осталось пару шагов.
Добавим в стадию установки Python кэширование самих бинарников и pip пакетов:
- name: Install Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
architecture: 'x64'
cache: 'pip' # кэширование пакетов
env:
AGENT_TOOLSDIRECTORY: /opt/hostedtoolcache # кэширование бинарников Python
С этими изменениями пайплайн выполнился за 10 минут и 31 секунду. Вот статистика по Memory Usage (в мб):
310 мегабайт ОЗУ на пике. Сойдет!
Итоги
Gitea Actions оказался довольно простым в настройке и довольно легковесным решением для реализации CI/CD у себя дома.
Комментарии (7)
ak47cccp
28.10.2023 08:01Люблю Gitea. Интерфейс работает гораздо быстрее гитлаба, несмотря на недостаток фичей по сравнению с гитлабом. Но хоть и gitea actions делают совместимыми с GitHub actions, совместимость не выполнена полностью. Например, не работает on.workflow_push и on.workflow_call.
slonopotamus
28.10.2023 08:01-1Интерфейс работает гораздо быстрее гитлаба, несмотря на недостаток фичей по сравнению с гитлабом.
Это не так работает. Больше фич -> больше тормозов. Поэтому интерфейс гораздо быстрее из-за меньшего количества фич.
JustOxlamon
А вы пробовали drone? (https://docs.drone.io/server/provider/gitea/) у дрона вроде побогаче все. Как вам в сравнении если пробовали?
kodor Автор
Дрон пробовал, и он ИМХО конечно лучше. Gitea Actions пока что сыроват. В моем случае были жесткие ограничения по доступной памяти, и отдельный инстанс дрона + его раннера мне показался слишком дорогим удовольствием.
Конечно нужно отдельно провести сравнение производительности Gitea Actions и дрона, чтобы делать выводы.
ShefEr
Тогда лучше уж брать Woodpecker CI https://woodpecker-ci.org/, форк дрона после того как проект сменил лицензию на менее свободную.
JustOxlamon
Оу, спасибо, проверим. А то у нас все на дроне издревле настроено. Но начинает не хватать.