Gitea & Act Runner: First touch

Хотелось бы восполнить скромную пустоту в литературе по 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.0'

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, просто прописав путь к репозиторию@ветка.

Попытка номер провалилась на этапе установки 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 на этот образ никак нельзя.

Тем не менее, не все так плохо. Есть несколько вариантов.

  1. Можно поменять дефолтный лейбл для раннера в панели Site administration → Actions → Runners → Edit и перезаписать существующий лейбл на новый. Синтаксис у лейблов такой: {тип хостовой ВМ, на которой будет запускаться джоба}:{имя Docker образа, в котором будет работать пайплайн}. Тип хостовой ВМ может быть ubuntu-latest, windows- latest или macOS-latest. Лейблы разделяются запятыми.

  2. Можно просто обавить строчку 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 (в мб):

Использование памяти Gitea Act Runner

График использования памяти пайплайном

310 мегабайт ОЗУ на пике. Сойдет!

Итоги

Gitea Actions оказался довольно простым в настройке и довольно легковесным решением для реализации CI/CD у себя дома.

© Habrahabr.ru