Stage 9: CI build on a self-hosted Gitea runner (0.7.0)
build / build (push) Successful in 45m41s

- .gitea/workflows/build.yml builds the packages and both ISOs with
  `make iso iso-server` on pushes to main and dev, v* tags and on demand
- ci/runner: setup of the CI host (WSL2 Ubuntu 24.04 with Docker Engine
  and gitea-runner as a systemd service, autostart task for Windows)
- scripts/builder.sh: DASOS_OUT keeps out/ outside the checkout, so CI
  reuses void-packages, the masterdir and the download cache
- README and TODO updated

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
das
2026-10-20 12:27:00 +03:00
co-authored by Claude Opus 5.5
parent fe043711a0
commit 125f9027c4
10 changed files with 172 additions and 9 deletions
+27
View File
@@ -0,0 +1,27 @@
# Builds the Das OS packages and both ISO images on the CI host (see ci/runner).
# Build output stays on the host in DASOS_OUT, set in the runner's config.
name: build
on:
push:
branches: [main, dev]
tags: ["v*"]
workflow_dispatch:
concurrency:
group: build-${{ gitea.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: dasci
steps:
- uses: builtin:checkout
# One make run builds the packages once for both images.
# Go tests run inside the das-tools and das-theme package builds.
- name: Packages and ISO images
run: make iso iso-server
- name: Result
run: ls -lh "$DASOS_OUT/iso/"*-"$(cat VERSION)"-x86_64.iso
+11 -2
View File
@@ -1,7 +1,7 @@
## Das OS
### _A light, friendly Void Linux–based desktop with Xfce and a Ukrainian touch, plus a console server edition_
[![Void Linux](https://img.shields.io/badge/Void_Linux-x86__64_glibc-green)](https://voidlinux.org) [![Xfce](https://img.shields.io/badge/Xfce-4.20-orange)](https://xfce.org) [![runit](https://img.shields.io/badge/init-runit-blue)](https://docs.voidlinux.org/config/services/) [![Go](https://img.shields.io/badge/Go-1.24+-blue)](https://go.dev) [![Docker](https://img.shields.io/badge/Docker-29-blue)](https://www.docker.com) [![Version](https://img.shields.io/badge/version-0.6.0-lightgrey)](#)
[![Void Linux](https://img.shields.io/badge/Void_Linux-x86__64_glibc-green)](https://voidlinux.org) [![Xfce](https://img.shields.io/badge/Xfce-4.20-orange)](https://xfce.org) [![runit](https://img.shields.io/badge/init-runit-blue)](https://docs.voidlinux.org/config/services/) [![Go](https://img.shields.io/badge/Go-1.24+-blue)](https://go.dev) [![Docker](https://img.shields.io/badge/Docker-29-blue)](https://www.docker.com) [![Version](https://img.shields.io/badge/version-0.7.0-lightgrey)](#)
🇺🇦 [Українська версія](README_ua.md)
@@ -21,6 +21,7 @@ Void Linux is fast, simple and independent: runit instead of systemd, and its ow
- [Desktop defaults](#Defaults) for Xfce that don't overwrite stock files
- [Own package repository](#Repository) built by xbps-src from in-tree templates
- [Containerised build](#Build) that runs on any Linux host with Docker, and QEMU scripts for testing
- [CI build](#CI) of the packages and both ISOs on every push, on a self-hosted Gitea Actions runner
### ⭐ Advantages
- **Void underneath** – a fast runit boot, the xbps package manager and fresh software, with none of the manual setup.
@@ -186,6 +187,14 @@ Void Linux is fast, simple and independent: runit instead of systemd, and its ow
2. `make iso` builds the packages and then the ISO with `void-mklive`, using the profile in `live/` (package list, services, root file system overlay). `make iso-server` does the same for the server profile in `server/`.
3. `make qemu` boots the newest ISO with UEFI. `make qemu-bios` uses legacy BIOS, and `make qemu-disk` also attaches a 20 GB virtual disk to install on. `make qemu-server` boots the server ISO with the disk on a serial console in the terminal (Ctrl-A X quits).
#### CI build<a id='CI' />
**_Every push to `main` or `dev` and every `v*` tag builds the packages and both ISOs on git.das.org.ua._**
- The workflow `.gitea/workflows/build.yml` runs `make iso iso-server` on a self-hosted runner with the `dasci` label.
- The runner is a WSL2 distro on a Windows machine: Ubuntu 24.04 with Docker Engine and `gitea-runner` as a systemd service. A scheduled task starts it when Windows boots, no login needed.
- `ci/runner/setup.sh` installs Docker, the runner and its `config.yaml`; `setup.sh register <token>` registers it, `autostart.ps1` creates the scheduled task.
- `DASOS_OUT` moves `out/` out of the checkout, so void-packages, the bootstrapped masterdir and the download cache survive between builds.
- The ISOs stay on the CI host in `/var/lib/dasos-ci/out/iso` and are not published yet.
### 🚀 Building the application
Requirements: Linux with Docker (the user must be in the `docker` group), QEMU and OVMF for testing, and Go 1.24+ with the GTK 3 development files for `make test`. About 10 GB of free disk space.
```shell
@@ -198,6 +207,6 @@ make clean # remove build output, keep the download cache
```
The ISOs appear in `out/iso/dasos-<version>-x86_64.iso` and `out/iso/dasos-server-<version>-x86_64.iso`. Write them to a USB stick with `dd` or Ventoy.
**Note:** Das OS is an early version (0.6.0). Signed repository hosting and a CI build are planned for upcoming stages. Until the repository is hosted, an installed system gets updates from Void only. Das OS is based on Void Linux but is not affiliated with it.
**Note:** Das OS is an early version (0.7.0). Packages and ISOs are built in CI; signed repository hosting is planned for an upcoming stage. Until the repository is hosted, an installed system gets updates from Void only. Das OS is based on Void Linux but is not affiliated with it.
###### _Made by -=:dAs:=-_
+11 -2
View File
@@ -1,7 +1,7 @@
## Das OS
### _Легкий і дружній десктоп на базі Void Linux з Xfce та українським колоритом, а також консольна серверна версія_
[![Void Linux](https://img.shields.io/badge/Void_Linux-x86__64_glibc-green)](https://voidlinux.org) [![Xfce](https://img.shields.io/badge/Xfce-4.20-orange)](https://xfce.org) [![runit](https://img.shields.io/badge/init-runit-blue)](https://docs.voidlinux.org/config/services/) [![Go](https://img.shields.io/badge/Go-1.24+-blue)](https://go.dev) [![Docker](https://img.shields.io/badge/Docker-29-blue)](https://www.docker.com) [![Version](https://img.shields.io/badge/version-0.6.0-lightgrey)](#)
[![Void Linux](https://img.shields.io/badge/Void_Linux-x86__64_glibc-green)](https://voidlinux.org) [![Xfce](https://img.shields.io/badge/Xfce-4.20-orange)](https://xfce.org) [![runit](https://img.shields.io/badge/init-runit-blue)](https://docs.voidlinux.org/config/services/) [![Go](https://img.shields.io/badge/Go-1.24+-blue)](https://go.dev) [![Docker](https://img.shields.io/badge/Docker-29-blue)](https://www.docker.com) [![Version](https://img.shields.io/badge/version-0.7.0-lightgrey)](#)
🇬🇧 [English version](README.md)
@@ -21,6 +21,7 @@ Void Linux швидкий, простий і незалежний: runit зам
- [Налаштування за замовчуванням](#Defaults) для Xfce, які не перезаписують стандартні файли
- [Власний репозиторій пакетів](#Repository), який xbps-src збирає з шаблонів у дереві проєкту
- [Збирання в контейнері](#Build), яке працює на будь-якому Linux із Docker, і скрипти QEMU для тестування
- [Збирання в CI](#CI) пакетів і обох ISO після кожного push на власному runner Gitea Actions
### ⭐ Переваги
- **Void усередині** – швидке завантаження з runit, менеджер пакетів xbps і свіжі програми без ручного налаштування.
@@ -186,6 +187,14 @@ Void Linux швидкий, простий і незалежний: runit зам
2. `make iso` збирає пакети, а потім ISO через `void-mklive` за профілем у `live/` (список пакетів, сервіси, оверлей кореневої файлової системи). `make iso-server` робить те саме для серверного профілю в `server/`.
3. `make qemu` завантажує найновіший ISO з UEFI. `make qemu-bios` використовує старий BIOS, а `make qemu-disk` ще й підключає віртуальний диск на 20 ГБ для встановлення. `make qemu-server` завантажує серверний ISO з диском на послідовній консолі прямо в терміналі (вихід — Ctrl-A X).
#### Збирання в CI<a id='CI' />
**_Кожен push у `main` чи `dev` і кожен тег `v*` збирає пакети й обидва ISO на git.das.org.ua._**
- Workflow `.gitea/workflows/build.yml` запускає `make iso iso-server` на власному runner з міткою `dasci`.
- Runner — дистрибутив WSL2 на Windows-машині: Ubuntu 24.04 з Docker Engine і `gitea-runner` як службою systemd. Завдання планувальника запускає його під час завантаження Windows, вхід у систему не потрібен.
- `ci/runner/setup.sh` встановлює Docker, runner і його `config.yaml`; `setup.sh register <токен>` реєструє його, `autostart.ps1` створює завдання планувальника.
- `DASOS_OUT` виносить `out/` за межі робочої копії, тож void-packages, підготовлений masterdir і кеш завантажень зберігаються між збираннями.
- ISO лишаються на CI-хості в `/var/lib/dasos-ci/out/iso` і поки не публікуються.
### 🚀 Збирання застосунку
Вимоги: Linux із Docker (користувач має бути в групі `docker`), QEMU та OVMF для тестування, Go 1.24+ і файли розробки GTK 3 для `make test`. Приблизно 10 ГБ вільного місця.
```shell
@@ -198,6 +207,6 @@ make clean # видалити результати збиранн
```
ISO з'являються в `out/iso/dasos-<версія>-x86_64.iso` і `out/iso/dasos-server-<версія>-x86_64.iso`. Записати їх на флешку можна через `dd` або Ventoy.
**Примітка:** Das OS — рання версія (0.6.0). Підписаний репозиторій на хостингу та збирання в CI заплановані на наступні етапи. Поки репозиторій не розміщено на хостингу, встановлена система отримує оновлення лише з Void. Das OS базується на Void Linux, але не пов'язана з ним офіційно.
**Примітка:** Das OS — рання версія (0.7.0). Пакети й ISO збираються в CI; підписаний репозиторій на хостингу заплановано на наступний етап. Поки репозиторій не розміщено на хостингу, встановлена система отримує оновлення лише з Void. Das OS базується на Void Linux, але не пов'язана з ним офіційно.
###### _Made by -=:dAs:=-_
+7 -2
View File
@@ -1,6 +1,6 @@
# Das OS — що зробити далі
Стан на 2026-10-20: версія 0.6.0, етапи 1–8 готові (live ISO, власний репозиторій, оформлення, інсталятор Calamares зі знімками Btrfs, Go-утиліти `das-update` і `das-welcome`, серверний образ з консольним інсталятором, менші ISO, консольні помічники, профіль розробника). Далі: CI (етап 9).
Стан на 2026-10-20: версія 0.7.0, етапи 1–8 готові (live ISO, власний репозиторій, оформлення, інсталятор Calamares зі знімками Btrfs, Go-утиліти `das-update` і `das-welcome`, серверний образ з консольним інсталятором, менші ISO, консольні помічники, профіль розробника), етап 9 (CI) налаштовано, чекає першого запуску в Gitea.
## Етап 5. Go-утиліти (готово, лишилися перевірки)
- [x] `das-update`: вікно, значок у треї (лише коли є оновлення), консольний режим `--cli`, знімок snapper pre/post, встановлення через pkexec, підказка про відкат.
@@ -61,7 +61,12 @@ Live ISO без графіки з консольним інсталятором:
- [x] Повідомлення наприкінці `das-server-install` згадує `dprofile install dev`.
## Етап 9. CI
- [ ] Збирання пакетів і обох ISO (десктоп і сервер) в контейнері Void (Gitea Actions на git.das.org.ua або GitHub Actions).
- [x] Workflow `.gitea/workflows/build.yml`: `make iso iso-server` на власному runner `dasci:host` (push у `main`/`dev`, теги `v*`, ручний запуск).
- [x] CI-хост: Windows-машина (192.168.88.193), WSL2 Ubuntu 24.04 `dasci` у `D:\DasOS\wsl`, Docker Engine, `gitea-runner` 5.1.1 як служба systemd, автозапуск завданням планувальника (`ci/runner`).
- [x] `DASOS_OUT` у `scripts/builder.sh`: кеш `out/` на CI-хості в `/var/lib/dasos-ci/out`.
- [ ] Зареєструвати runner і перевірити перший запуск у Gitea.
- [ ] Перевірити, що після перезавантаження Windows runner піднімається сам (завдання S4U).
- [ ] Вирішити, куди публікувати ISO (Release на тег `v*` чи artifacts).
## Репозиторій пакетів
- [ ] Підпис через `xbps-rindex --sign`, ключ поза репозиторієм.
+1 -1
View File
@@ -1 +1 @@
0.6.0
0.7.0
+12
View File
@@ -0,0 +1,12 @@
# Starts the dasci WSL distro (Docker and gitea-runner inside) when Windows
# boots, without anyone logging in. Run once in an elevated PowerShell.
# The task keeps a process attached so WSL never stops the distro as idle.
$wsl = 'C:\Program Files\WSL\wsl.exe'
$action = New-ScheduledTaskAction -Execute $wsl -Argument '-d dasci --exec /bin/sleep infinity'
$trigger = New-ScheduledTaskTrigger -AtStartup
$principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType S4U -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0 -AllowStartIfOnBatteries `
-DontStopIfGoingOnBatteries -RestartCount 999 -RestartInterval (New-TimeSpan -Minutes 1)
Register-ScheduledTask -TaskName 'DasOS CI (WSL dasci)' -Action $action -Trigger $trigger `
-Principal $principal -Settings $settings -Force | Out-Null
Get-ScheduledTask -TaskName 'DasOS CI (WSL dasci)' | Select-Object TaskName, State
+23
View File
@@ -0,0 +1,23 @@
# gitea-runner configuration for the Das OS CI host (WSL2 distro "dasci").
# Jobs run directly on the host: scripts/builder.sh needs the host's Docker
# and paths it can bind-mount into the privileged Void builder container.
log:
level: info
runner:
file: /var/lib/gitea-runner/.runner
# One build at a time: packages and ISOs share the cache in DASOS_OUT
capacity: 1
# Matches Gitea's default job timeout; the first build bootstraps void-packages
timeout: 3h
envs:
DASOS_OUT: /var/lib/dasos-ci/out
labels:
- "dasci:host"
cache:
# Build caches live in DASOS_OUT, the workflow does not use actions/cache
enabled: false
host:
workdir_parent: /var/lib/gitea-runner/work
+16
View File
@@ -0,0 +1,16 @@
[Unit]
Description=Gitea Actions runner for Das OS
After=docker.service network-online.target
Wants=network-online.target
Requires=docker.service
[Service]
User=runner
Group=runner
WorkingDirectory=/var/lib/gitea-runner
ExecStart=/usr/local/bin/gitea-runner -c /etc/gitea-runner/config.yaml daemon
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
+59
View File
@@ -0,0 +1,59 @@
#!/bin/sh
# Sets up the Das OS CI host: Docker Engine, the runner user and gitea-runner.
# Run as root inside a fresh Ubuntu 24.04 WSL2 distro with systemd enabled:
# sh setup.sh install everything
# sh setup.sh register <token> register the runner with git.das.org.ua
# Safe to run again.
set -eu
RUNNER_VERSION=5.1.1
INSTANCE=https://git.das.org.ua
here=$(cd "$(dirname "$0")" && pwd)
if [ "${1:-}" = register ]; then
[ -n "${2:-}" ] || { echo "usage: setup.sh register <token>" >&2; exit 1; }
sudo -u runner /usr/local/bin/gitea-runner -c /etc/gitea-runner/config.yaml \
register --no-interactive --instance "$INSTANCE" --token "$2" --name dasci
systemctl restart gitea-runner
exit 0
fi
export DEBIAN_FRONTEND=noninteractive
apt-get update -q
apt-get install -yq ca-certificates curl git make xz-utils
# Docker Engine from Docker's repository (Ubuntu's docker.io lags behind)
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
. /etc/os-release
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $VERSION_CODENAME stable" \
>/etc/apt/sources.list.d/docker.list
apt-get update -q
apt-get install -yq docker-ce docker-ce-cli containerd.io docker-buildx-plugin
systemctl enable --now docker
# Jobs run as an unprivileged user: build-packages.sh creates its xbps-src user
# with the caller's UID, which must not be root
id runner >/dev/null 2>&1 || useradd --create-home --shell /bin/bash --groups docker runner
install -d -o runner -g runner /var/lib/gitea-runner /var/lib/dasos-ci /var/lib/dasos-ci/out
url=https://gitea.com/gitea/runner/releases/download/v$RUNNER_VERSION/gitea-runner-$RUNNER_VERSION-linux-amd64.xz
tmp=$(mktemp -d)
curl -fsSL -o "$tmp/gitea-runner.xz" "$url"
curl -fsSL -o "$tmp/gitea-runner.xz.sha256" "$url.sha256"
(cd "$tmp" && echo "$(cut -d' ' -f1 gitea-runner.xz.sha256) gitea-runner.xz" | sha256sum -c --quiet)
xz -d "$tmp/gitea-runner.xz"
install -m 0755 "$tmp/gitea-runner" /usr/local/bin/gitea-runner
rm -rf "$tmp"
install -D -m 0644 "$here/config.yaml" /etc/gitea-runner/config.yaml
install -m 0644 "$here/gitea-runner.service" /etc/systemd/system/gitea-runner.service
systemctl daemon-reload
systemctl enable gitea-runner
# The runner starts once it is registered
if [ -f /var/lib/gitea-runner/.runner ]; then
systemctl restart gitea-runner
else
echo "Now register: sh setup.sh register <token>"
fi
gitea-runner --version
+5 -2
View File
@@ -1,18 +1,21 @@
#!/usr/bin/env bash
# Runs a command inside the Void Linux builder container.
# The project is mounted at /work; downloaded packages are cached in out/cache/xbps.
# DASOS_OUT puts out/ elsewhere (CI keeps it between checkouts).
set -euo pipefail
root=$(cd "$(dirname "$0")/.." && pwd)
out=${DASOS_OUT:-$root/out}
image=dasos-builder
docker build --quiet --tag "$image" "$root/docker/builder" >/dev/null
mkdir -p "$root/out/cache/xbps"
mkdir -p "$out/cache/xbps"
# --privileged: mklive mounts /proc, /sys, /dev and a loop device for the root image
exec docker run --rm --privileged \
--volume "$root:/work" \
--volume "$root/out/cache/xbps:/var/cache/xbps" \
${DASOS_OUT:+--volume "$out:/work/out"} \
--volume "$out/cache/xbps:/var/cache/xbps" \
--env HOST_UID="$(id -u)" \
--env HOST_GID="$(id -g)" \
"$image" "$@"