# Налаштування раннера Forgejo Actions для NetPulse. # # Читається демоном як `forgejo-runner daemon --config`. Підключається # у deploy/docker-compose.ci.yml. # # Головне, заради чого цей файл узагалі існує, — два рядки: # `capacity: 1` і `valid_volumes`. Решта — замовчування з поясненням, # чому їх не змінено. log: level: info runner: # Файл реєстрації. Лежить в іменованому томі, тобто переживає # перестворення контейнера: реєструватись заново після кожного # `docker compose pull` не треба. file: /data/.runner # ОДНА робота за раз. Не «щоб було просто», а тому що на цій машині # 4 ГБ памʼяті й на ній же живе бойовий стек. Дві паралельні роботи — # це `go build` і `vite build` одночасно, тобто ядро вибирає, кого # вбити, і вибір робить не на нашу користь. CI, який кладе продукт, # гірший за відсутній CI. capacity: 1 # Стеля на роботу. Довший прогін означає, що щось зависло (мережа до # реєстру образів, база, яка не піднялась), а не що збірка велика: # найдовші роботи тут — server і dbtest, і кожна вкладається в десяток # хвилин. Свої стелі вони мають ще й у самому workflow # (timeout-minutes: 40) — ця лишається запасною. timeout: 1h # Пауза між опитуваннями Forgejo. Дві секунди — замовчування; частіше # немає сенсу, рідше — довше чекати відповіді на пуш. fetch_timeout: 5s fetch_interval: 2s # Мітки визначають, що можна писати в `runs-on`. Усі роботи в # .forgejo/workflows/ci.yml пишуть `runs-on: docker` і задають свій # образ через `container:`, тож образ у мітці — лише запасний варіант # для робіт без `container`. node:22-alpine узято тому, що це єдиний # із наших образів, у якому є node: якщо колись зʼявиться робота з # JS-дією, вона хоча б стартує. # # УВАГА: мітки з цього файлу застосовуються при РЕЄСТРАЦІЇ. Якщо # раннер уже зареєстровано, зміна цього списку нічого не змінить, # доки не перереєструвати (див. deploy/docker-compose.ci.yml). labels: - "docker:docker://node:22-alpine" cache: # Вбудований кеш-сервер вимкнено НАВМИСНО. # # Він потрібен лише для actions/cache, а її тут немає: кеші Go й npm # їдуть іменованими томами (див. valid_volumes). Різниця не в смаку — # у диску. Кеш-сервер тримає вміст ЩЕ РАЗ, у вигляді tar-архівів # поруч, і пакує/розпаковує їх на кожному прогоні. На машині з ~7 ГБ # вільного це друга копія того самого й зайві хвилини на прогін. enabled: false container: # Порожньо — act створює власну мережу під кожну роботу. Саме завдяки # їй контейнер роботи бачить сервіс `db` за іменем `db`. network: "" # Docker-in-Docker не потрібен: ми нічого не збираємо в образи. privileged: false # Стеля памʼяті й ядер на КОНТЕЙНЕР РОБОТИ. # # Це свідомий вибір, кому вмирати першим. Без стелі найбільший # споживач памʼяті на машині — компілятор Go — і ядро при нестачі # вбиває не його, а те, що поруч, тобто API або базу стенду. Зі # стелею перевищення вбиває саму роботу: CI червоніє, продукт живий. # Червоний CI видно й можна полагодити; перезапущений уночі API — # ні. # # --cpus=2 заразом задає GOMAXPROCS: Go 1.25 читає обмеження cgroup # сам, окремо його виставляти не треба. options: "--memory=1600m --cpus=2" # Батьківський каталог робочих каталогів. workdir_parent: workspace # Томи, які роботам дозволено монтувати. Порожній список означає # «жодних», і тоді .forgejo/workflows/ci.yml не запуститься взагалі: # там кожна робота монтує свій кеш. # # Перелічено поіменно, а не '**': раннер ходить у докер із правами # root, і дозвіл монтувати будь-що перетворює будь-який workflow із # будь-якої гілки на доступ до всього диска машини — включно з # даними бойової бази. valid_volumes: - netpulse-ci-gomod - netpulse-ci-gobuild - netpulse-ci-npm # Порожньо — береться DOCKER_HOST із оточення (сокет, прокинутий у # compose). docker_host: "" # Не тягнути образ, якщо він уже є. Образи тут прибиті до версій # (alpine:3.21, golang:1.25-alpine, node:22-alpine, timescaledb з # тим самим тегом, що в бойовому compose), тож перевіряти реєстр на # кожному прогоні — зайвий трафік і зайва точка відмови. force_pull: false