Compare commits

..
2 Commits
Author SHA1 Message Date
dasandClaude Opus 5.5 f3793d468c Incremental package builds and releases on v* tags (0.8.0)
build / build (push) Successful in 30m42s
- build-packages.sh rebuilds a package only when its srcpkgs/ directory
  changed, its binary package is missing, or a dry-run install finds a
  shared library Void no longer provides; DASOS_REBUILD=1 rebuilds all.
  An unchanged `make packages` takes 20 s instead of 17 min on the CI host
- ci/release.sh publishes both ISOs and SHA256SUMS as a Gitea release
  when the workflow runs for a v* tag matching VERSION
- README and TODO updated

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 14:55:45 +03:00
dasandClaude Opus 5.5 dbfb104d89 TODO: stage 9 verified in Gitea and across a reboot
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 13:15:25 +03:00
9 changed files with 102 additions and 14 deletions
+12
View File
@@ -1,5 +1,6 @@
# 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.
# A v* tag also publishes the images as a release (ci/release.sh).
name: build
on:
@@ -15,6 +16,8 @@ concurrency:
jobs:
build:
runs-on: dasci
permissions:
contents: write # ci/release.sh creates releases
steps:
- uses: builtin:checkout
@@ -25,3 +28,12 @@ jobs:
- name: Result
run: ls -lh "$DASOS_OUT/iso/"*-"$(cat VERSION)"-x86_64.iso
# A v* tag publishes both images and their checksums as a release
- name: Release
if: startsWith(gitea.ref, 'refs/tags/v')
env:
GITEA_TOKEN: ${{ gitea.token }}
GITEA_SERVER_URL: ${{ gitea.server_url }}
GITEA_REPOSITORY: ${{ gitea.repository }}
run: ci/release.sh "${{ gitea.ref_name }}" "$DASOS_OUT/iso"
+1 -1
View File
@@ -40,5 +40,5 @@ test:
# Build output may be owned by root when a build was interrupted, so remove it from the container
clean:
scripts/builder.sh rm -rf /work/out/hostdir/binpkgs /work/out/iso
scripts/builder.sh rm -rf /work/out/hostdir/binpkgs /work/out/hostdir/stamps /work/out/iso
rm -rf out/qemu
+4 -3
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.7.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.8.0-lightgrey)](#)
🇺🇦 [Українська версія](README_ua.md)
@@ -180,6 +180,7 @@ Void Linux is fast, simple and independent: runit instead of systemd, and its ow
- `srcpkgs/das-server` is the server metapackage with the nftables, fail2ban, sshd and Docker defaults. `srcpkgs/das-helpers` contains `dsv`, `duser`, `dfw`, `dsys`, `dprofile` and the profiles.
- `srcpkgs/calamares`, `srcpkgs/adw-gtk3` and `srcpkgs/font-jetbrains-mono` package upstream releases that Void does not have.
- `make packages` lays the templates over a shallow clone of void-packages and builds them with `xbps-src` into `out/hostdir/binpkgs`. The ISO build installs them from there.
- A package is rebuilt only when its directory in `srcpkgs/` changed, its binary package is missing, or Void no longer provides a shared library it links to (checked with a dry-run install). `DASOS_REBUILD=1 make packages` rebuilds everything.
#### Containerised build<a id='Build' />
**_The whole build runs in a Docker container, so only Docker and QEMU are needed on the host._**
@@ -193,7 +194,7 @@ Void Linux is fast, simple and independent: runit instead of systemd, and its ow
- 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.
- A `v*` tag that matches `VERSION` also publishes both ISOs and `SHA256SUMS` as a release (`ci/release.sh`, with the job's own token): `git tag v0.8.0 && git push origin v0.8.0`. Other builds keep the ISOs on the CI host in `/var/lib/dasos-ci/out/iso`.
### 🚀 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.
@@ -207,6 +208,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.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.
**Note:** Das OS is an early version (0.8.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:=-_
+4 -3
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.7.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.8.0-lightgrey)](#)
🇬🇧 [English version](README.md)
@@ -180,6 +180,7 @@ Void Linux швидкий, простий і незалежний: runit зам
- `srcpkgs/das-server` — серверний метапакет із налаштуваннями nftables, fail2ban, sshd і Docker. `srcpkgs/das-helpers` містить `dsv`, `duser`, `dfw`, `dsys`, `dprofile` і профілі.
- `srcpkgs/calamares`, `srcpkgs/adw-gtk3` і `srcpkgs/font-jetbrains-mono` пакують релізи, яких немає у Void.
- `make packages` накладає шаблони на неглибокий клон void-packages і збирає їх через `xbps-src` в `out/hostdir/binpkgs`. Збирання ISO встановлює їх звідти.
- Пакет перезбирається, лише коли змінився його каталог у `srcpkgs/`, зник бінарний пакет або Void більше не надає бібліотеку, з якою він зібраний (перевіряється пробним встановленням). `DASOS_REBUILD=1 make packages` перезбирає все.
#### Збирання в контейнері<a id='Build' />
**_Усе збирання відбувається в Docker-контейнері, тож на хості потрібні лише Docker і QEMU._**
@@ -193,7 +194,7 @@ Void Linux швидкий, простий і незалежний: runit зам
- 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` і поки не публікуються.
- Тег `v*`, що збігається з `VERSION`, ще й публікує обидва ISO та `SHA256SUMS` як реліз (`ci/release.sh`, з власним токеном завдання): `git tag v0.8.0 && git push origin v0.8.0`. Інші збирання залишають ISO на CI-хості в `/var/lib/dasos-ci/out/iso`.
### 🚀 Збирання застосунку
Вимоги: Linux із Docker (користувач має бути в групі `docker`), QEMU та OVMF для тестування, Go 1.24+ і файли розробки GTK 3 для `make test`. Приблизно 10 ГБ вільного місця.
@@ -207,6 +208,6 @@ make clean # видалити результати збиранн
```
ISO з'являються в `out/iso/dasos-<версія>-x86_64.iso` і `out/iso/dasos-server-<версія>-x86_64.iso`. Записати їх на флешку можна через `dd` або Ventoy.
**Примітка:** Das OS — рання версія (0.7.0). Пакети й ISO збираються в CI; підписаний репозиторій на хостингу заплановано на наступний етап. Поки репозиторій не розміщено на хостингу, встановлена система отримує оновлення лише з Void. Das OS базується на Void Linux, але не пов'язана з ним офіційно.
**Примітка:** Das OS — рання версія (0.8.0). Пакети й ISO збираються в CI; підписаний репозиторій на хостингу заплановано на наступний етап. Поки репозиторій не розміщено на хостингу, встановлена система отримує оновлення лише з Void. Das OS базується на Void Linux, але не пов'язана з ним офіційно.
###### _Made by -=:dAs:=-_
+7 -6
View File
@@ -1,6 +1,6 @@
# Das OS — що зробити далі
Стан на 2026-10-20: версія 0.7.0, етапи 1–8 готові (live ISO, власний репозиторій, оформлення, інсталятор Calamares зі знімками Btrfs, Go-утиліти `das-update` і `das-welcome`, серверний образ з консольним інсталятором, менші ISO, консольні помічники, профіль розробника), етап 9 (CI) налаштовано, чекає першого запуску в Gitea.
Стан на 2026-10-20: версія 0.8.0, етапи 1–8 готові (live ISO, власний репозиторій, оформлення, інсталятор Calamares зі знімками Btrfs, Go-утиліти `das-update` і `das-welcome`, серверний образ з консольним інсталятором, менші ISO, консольні помічники, профіль розробника), CI (етап 9: пакети й обидва ISO збираються на власному runner, ~45 хв).
## Етап 5. Go-утиліти (готово, лишилися перевірки)
- [x] `das-update`: вікно, значок у треї (лише коли є оновлення), консольний режим `--cli`, знімок snapper pre/post, встановлення через pkexec, підказка про відкат.
@@ -60,13 +60,14 @@ Live ISO без графіки з консольним інсталятором:
- [x] Перевірено: сервер (QEMU) — `go run`, Node.js, uv, `docker run`, rootless `podman run` без попередження після перезавантаження; десктоп — встановлення з `das-welcome`, Code - OSS і VS Code з Flathub у меню після входу, `dprofile app rm` звільняє рантайми.
- [x] Повідомлення наприкінці `das-server-install` згадує `dprofile install dev`.
## Етап 9. CI
## Етап 9. CI (готово)
- [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).
- [x] Runner зареєстровано, перший запуск у Gitea (run 1) успішний за 46 хв.
- [x] Після перезавантаження Windows runner піднімається сам, без входу в систему (завдання S4U).
- [x] Тег `v*` публікує обидва ISO і `SHA256SUMS` як реліз Gitea (`ci/release.sh`). Ліміт вкладення релізу — 2 ГБ на файл (`[repository.release] FILE_MAX_SIZE`).
- [ ] Перевірити першу публікацію на справжньому тегу.
## Репозиторій пакетів
- [ ] Підпис через `xbps-rindex --sign`, ключ поза репозиторієм.
@@ -89,7 +90,7 @@ Live ISO без графіки з консольним інсталятором:
- [ ] Прибрати значки томів live-носія («Том 6,6 ГБ») з робочого столу live-сесії.
- [ ] Тема GRUB у встановленій системі (зараз стандартний чорний екран).
- [ ] Перевірити меню Whisker вручну.
- [ ] Прискорити `make packages`: не перезбирати Calamares, якщо його версія не змінилася.
- [x] Прискорити `make packages`: пакет перезбирається лише після змін у `srcpkgs/<назва>`, без бінарного пакета або коли у Void зникла потрібна йому бібліотека (`xbps-install -n`). `DASOS_REBUILD=1` перезбирає все.
## Відкладено
- [ ] ARM-образ для Raspberry Pi.
+1 -1
View File
@@ -1 +1 @@
0.7.0
0.8.0
Executable
+41
View File
@@ -0,0 +1,41 @@
#!/bin/sh
# Publishes the ISO images of the current version as a Gitea release:
# release.sh <tag> <iso dir>
# Needs GITEA_TOKEN, GITEA_SERVER_URL and GITEA_REPOSITORY (owner/name); in CI
# the job provides them. Running it again for the same tag replaces the files.
set -eu
tag=$1
dir=$2
version=$(cat VERSION)
[ "$tag" = "v$version" ] || { echo "release: tag $tag does not match VERSION $version" >&2; exit 1; }
api=$GITEA_SERVER_URL/api/v1/repos/$GITEA_REPOSITORY
auth="Authorization: token $GITEA_TOKEN"
json() { python3 -c "import json,sys; d=json.load(sys.stdin); $1"; }
isos="dasos-$version-x86_64.iso dasos-server-$version-x86_64.iso"
cd "$dir"
sha256sum $isos >SHA256SUMS
if ! id=$(curl -fsS -H "$auth" "$api/releases/tags/$tag" 2>/dev/null | json 'print(d["id"])' 2>/dev/null); then
id=$(curl -fsS -H "$auth" -H 'Content-Type: application/json' \
-d "{\"tag_name\":\"$tag\",\"name\":\"Das OS $version\",\"body\":\"Desktop and server live ISO images. Check them with sha256sum -c SHA256SUMS.\"}" \
"$api/releases" | json 'print(d["id"])')
echo "release: created $tag (id $id)"
fi
# Files left from an earlier run for this tag are replaced
curl -fsS -H "$auth" "$api/releases/$id/assets" |
json '[print(a["id"], a["name"]) for a in d]' |
while read -r asset name; do
case " $isos SHA256SUMS " in
*" $name "*) curl -fsS -X DELETE -H "$auth" "$api/releases/$id/assets/$asset" ;;
esac
done
for f in $isos SHA256SUMS; do
echo "release: uploading $f"
curl -fsS -o /dev/null -H "$auth" -F "attachment=@$f" "$api/releases/$id/assets?name=$f"
done
echo "release: $GITEA_SERVER_URL/$GITEA_REPOSITORY/releases/tag/$tag"
+1
View File
@@ -18,4 +18,5 @@ exec docker run --rm --privileged \
--volume "$out/cache/xbps:/var/cache/xbps" \
--env HOST_UID="$(id -u)" \
--env HOST_GID="$(id -g)" \
--env DASOS_REBUILD \
"$image" "$@"
+31
View File
@@ -34,6 +34,30 @@ XBPS_CHROOT_CMD=uchroot
XBPS_MAKEJOBS=$(nproc)
CONF
# A package is rebuilt only when its directory in srcpkgs/ changed since the last
# build, its binary package is gone, or Void no longer provides a shared library
# it links to (a soname bump there needs a rebuild here). DASOS_REBUILD=1 rebuilds all.
stamps=$hostdir/stamps
mkdir -p "$stamps"
srchash() {
(cd "$vp/srcpkgs/$1" && find . -type f -print0 | sort -z | xargs -0 sha256sum) | sha256sum | cut -d' ' -f1
}
# An empty root to dry-run installs into: xbps refuses unresolved shared libraries
checkroot=$(mktemp -d)
mkdir -p "$checkroot/var/db/xbps/keys"
cp -a /var/db/xbps/keys/. "$checkroot/var/db/xbps/keys/"
voidrepo=$(sed -n 's/^repository=//p' /usr/share/xbps.d/*-repository-main.conf | head -1)
xbps-install -S -r "$checkroot" -R "$voidrepo" >/dev/null
up_to_date() {
local info version revision
[[ ${DASOS_REBUILD:-} != 1 && -f $stamps/$1 && $(< "$stamps/$1") == "$(srchash "$1")" ]] || return 1
info=$(as_builder ./xbps-src show "$1")
version=$(sed -n 's/^version:[[:space:]]*//p' <<<"$info")
revision=$(sed -n 's/^revision:[[:space:]]*//p' <<<"$info")
compgen -G "$hostdir/binpkgs/$1-${version}_$revision.*.xbps" >/dev/null || return 1
xbps-install -n -y -r "$checkroot" -R "$hostdir/binpkgs" -R "$voidrepo" "$1" >/dev/null 2>&1
}
names=()
for dir in /work/srcpkgs/*/; do
name=$(basename "$dir")
@@ -59,9 +83,16 @@ fi
# (also as a dependency of another one) would package the stale files
rm -rf masterdir-x86_64/destdir/*
for name in "${names[@]}"; do
if up_to_date "$name"; then
echo "==> $name is up to date"
continue
fi
echo "==> Building $name"
as_builder ./xbps-src -H "$hostdir" -f pkg "$name"
srchash "$name" >"$stamps/$name"
done
rm -rf "$checkroot"
chown -R "$HOST_UID:$HOST_GID" "$stamps"
echo "==> Repository: $hostdir/binpkgs"
ls -1 "$hostdir"/binpkgs/*.xbps