Compare commits

..
15 Commits
Author SHA1 Message Date
theupriser 870a3a4ede ci: the VM tests only run on release branches (main only gets tested release branches) 2026-09-30 11:15:34 +02:00
theupriser 813544123b ci: download the ISO with 16 connections (a single stream from the mirror is slow) 2026-09-30 10:59:26 +02:00
theupriser 1a2d81c0a0 ci: stream the VM tests' progress into the job log 2026-09-30 10:50:48 +02:00
theupriser d12be7eaa2 ci: the VM tests only run on main and release branches (and by hand), not on pull requests 2026-09-30 10:28:24 +02:00
theupriser 0bbe97214e ci: wait for udev to apply the KVM rule, print what the runner has 2026-09-30 10:07:50 +02:00
theupriser c4631d6a23 ci: no strategy context in the composite action (vmpkg cache key per run) 2026-09-30 09:35:09 +02:00
theupriser ec993eca33 ci: VM tests: one job per boot loader and per suite, all parallel on their own GitHub runners; the ISO is fetched once and cached 2026-09-30 09:34:53 +02:00
theupriser 5c0cd7aa92 ci: the VM tests run on GitHub's runners (better resources), one matrix job per boot loader, not on the Gitea mirror
vmtest.yml: newest Steamify ISO release from the mirror (secret GIT_UPRISER_URL), KVM on the hosted runner, boot loaders limine/systemd-boot/grub two at a time, then the suites on a plain VM from the same ISO.
2026-09-30 09:34:03 +02:00
theupriser 2a213946ec ci: two fixed boot loader lanes (the runner ignores max-parallel) 2026-09-30 09:02:30 +02:00
theupriser 5585d92cf8 feat(ci): VM tests on the Gitea mirror: boot loaders and all suites on this commit, from the newest Steamify ISO release
vmtest.yml (Gitea only) runs steamify-cachyos-dev's vmbootloadertest.sh per loader (limine, systemd-boot, grub), then the vmtest.sh suites on a plain VM from the same ISO, on pushes to main and release/**, pull requests and by hand.
2026-09-30 08:47:30 +02:00
theupriser d44f29956a Merge pull request #63 from theupriser/release/2.9.4
Single-file build / bundle (push) Successful in 13s
Release 2.9.4
2026-09-29 23:08:59 +02:00
theupriser 2858d13429 docs: changelog hash for 2.9.4 2026-09-29 23:08:20 +02:00
theupriser 48cf3c7c7c Merge pull request #62 from theupriser/feature/docs-ci-and-cec-cache
docs: the CEC driver cache and the CI/ISO release flow
2026-09-29 23:08:12 +02:00
theupriser 619ef1f714 docs: AGENTS.md and TECHNICAL.md: the CEC driver cache, one workflow for GitHub and a Gitea mirror, a release starts the Steamify ISO's release 2026-09-29 23:07:28 +02:00
theupriser b6240539e6 chore: Version 2.9.4 2026-09-29 23:07:08 +02:00
6 changed files with 216 additions and 2 deletions

No files matched your search

+37
View File
@@ -0,0 +1,37 @@
name: VM runner
description: KVM, qemu, the big disk for the VMs, the package cache and the cached Steamify ISO (at /mnt/work/iso/steamify.iso)
inputs:
iso-tag:
description: The Steamify ISO release the iso job cached
required: true
runs:
using: composite
steps:
- name: KVM, qemu, disk
shell: bash
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules && sudo udevadm trigger --name-match=kvm && sudo udevadm settle || true
for _ in $(seq 10); do [ -w /dev/kvm ] && break; sleep 1; done
ls -l /dev/kvm 2>&1 || true
grep -cE 'vmx|svm' /proc/cpuinfo || true
[ -w /dev/kvm ] || { echo "::error::no usable /dev/kvm on this runner (some GitHub runners have none: re-run the job)"; exit 1; }
sudo apt-get update -qq
sudo apt-get install -y -qq qemu-system-x86 qemu-utils ovmf libarchive-tools openssh-client
# The VMs and the ISO on /mnt (the big disk); ~/vms points there.
sudo mkdir -p /mnt/work && sudo chown "$USER" /mnt/work
mkdir -p /mnt/work/vms/pkg-cache /mnt/work/iso "$HOME/.ssh" && ln -s /mnt/work/vms "$HOME/vms"
ssh-keygen -q -t ed25519 -N "" -C steamify-vm -f "$HOME/.ssh/steamify-vm_ed25519"
nproc; free -g | sed -n 2p; df -h /mnt | tail -n 1
- name: Cache - the VMs' packages
uses: actions/cache@v4
with:
path: /mnt/work/vms/pkg-cache
key: vmpkg-${{ github.run_id }}
restore-keys: vmpkg-
- name: Cache - the ISO (from the iso job)
uses: actions/cache/restore@v4
with:
path: /mnt/work/iso
key: steamify-iso-${{ inputs.iso-tag }}
fail-on-cache-miss: true
+160
View File
@@ -0,0 +1,160 @@
# Steamify's own VM tests on GitHub's runners (4 vCPUs, 16 GB, KVM; skipped on the Gitea mirror): the same as
# `scripts/vmtest.sh` in steamify-cachyos-dev, on this commit's steamify.sh. The base is the newest Steamify ISO
# release (steamify-cachyos-live-iso, built and kept on the git.upriser.nl mirror: GitHub releases take at
# most 2 GB per file): the boot loader tests (limine, systemd-boot, grub) install it with this commit's
# Steamify, then the suites (cli, menu, hw, installer, toggles) run on a plain VM from the same ISO (its
# Steamify step skipped: the suites start from a system without Steamify).
# The ISO is fetched once (the iso job, cached) and restored by the others.
# Needs the secret GIT_UPRISER_URL (the mirror's address, for the ISO). Every job has its own runner, so everything runs in parallel: one job per boot loader and per suite, each with its own VMs (2 vCPUs, 4-6 GB).
name: Steamify VM tests
# Only on the release branches (and by hand): the runners' time is limited, so not on every pull request, and not on
# main either, which only ever gets a release branch that was tested here.
on:
push:
branches: ['release/**']
workflow_dispatch:
# A new run on the same branch stops the old one.
concurrency:
group: vmtest-${{ github.ref }}
cancel-in-progress: true
jobs:
iso:
name: Newest Steamify ISO
if: github.server_url == 'https://github.com'
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.find.outputs.tag }}
steps:
- name: Find the newest ISO release on the mirror
id: find
env:
MIRROR: ${{ secrets.GIT_UPRISER_URL }}
run: |
[ -n "$MIRROR" ] || { echo "::error::the secret GIT_UPRISER_URL is not set"; exit 1; }
read -r tag url < <(curl -fsS "${MIRROR%/}/api/v1/repos/theupriser/steamify-cachyos-live-iso/releases?limit=20" | python3 -c '
import json, sys
for r in json.load(sys.stdin):
for a in r["assets"]:
if a["name"].endswith(".iso"):
print(r["tag_name"], a["browser_download_url"]); raise SystemExit
')
[ -n "$tag" ] || { echo "::error::no ISO release on the mirror"; exit 1; }
echo "Using $tag"
{ echo "tag=$tag"; echo "url=$url"; } >> "$GITHUB_OUTPUT"
- name: Cache - the ISO
id: cache
uses: actions/cache@v4
with:
path: /mnt/work/iso
key: steamify-iso-${{ steps.find.outputs.tag }}
- name: Download the ISO (once for every job)
if: steps.cache.outputs.cache-hit != 'true'
run: |
sudo mkdir -p /mnt/work/iso && sudo chown -R "$USER" /mnt/work
# 16 connections: one TCP stream from the mirror to the US stays at a few MB/s whatever the uplink is.
sudo apt-get install -y -qq aria2
aria2c -x16 -s16 -k8M --file-allocation=none --summary-interval=30 --console-log-level=warn --max-tries=5 --retry-wait=5 \
-d /mnt/work/iso -o steamify.iso "${{ steps.find.outputs.url }}"
ls -la /mnt/work/iso
boot:
name: Boot loader ${{ matrix.loader }}
needs: iso
runs-on: ubuntu-latest
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
loader: [limine, systemd-boot, grub]
steps:
- uses: actions/checkout@v4
with:
path: steamify-cachyos
- uses: actions/checkout@v4
with:
repository: theupriser/steamify-cachyos-dev
path: steamify-cachyos-dev
- uses: ./steamify-cachyos/.github/actions/vm-runner
with:
iso-tag: ${{ needs.iso.outputs.tag }}
- name: Boot loader test (${{ matrix.loader }})
env:
CI: "1"
VM_TIMEZONE: UTC
VM_CPUS: "4"
VM_INSTALL_MEM: 6G
run: |
cd steamify-cachyos-dev
touch ~/vms/test.log; tail -n +1 -F ~/vms/test.log & tailpid=$! # the test's progress, as it happens
trap 'kill $tailpid 2>/dev/null' EXIT
VM_ISO=/mnt/work/iso/steamify.iso scripts/vmbootloadertest.sh "${{ matrix.loader }}" --install
- name: Logs
if: always()
uses: actions/upload-artifact@v4
with:
name: boot-${{ matrix.loader }}
path: |
/mnt/work/vms/bl-${{ matrix.loader }}.test.log
/mnt/work/vms/bl-${{ matrix.loader }}/vm.log
retention-days: 7
if-no-files-found: ignore
suites:
name: Suite ${{ matrix.suite }}
needs: iso
runs-on: ubuntu-latest
timeout-minutes: 180
strategy:
fail-fast: false
matrix:
suite: [toggles, hw, cli, 'menu installer']
steps:
- uses: actions/checkout@v4
with:
path: steamify-cachyos
- uses: actions/checkout@v4
with:
repository: theupriser/steamify-cachyos-dev
path: steamify-cachyos-dev
# vmtest.sh reads which boot loaders the ISO advertises from this repository.
- uses: actions/checkout@v4
with:
repository: theupriser/steamify-cachyos-live-iso
path: steamify-cachyos-live-iso
- uses: ./steamify-cachyos/.github/actions/vm-runner
with:
iso-tag: ${{ needs.iso.outputs.tag }}
# A plain VM for the suites: the ISO's installer with its Steamify step skipped (the suites start without Steamify).
- name: Base VM from the ISO
env:
CI: "1"
VM_TIMEZONE: UTC
VM_CPUS: "4"
VM_INSTALL_MEM: 6G
VM_STEAMIFY: skip
run: |
cd steamify-cachyos-dev
VM_DIR="$HOME/vms/steamify-vm" scripts/vminstall.sh --iso /mnt/work/iso/steamify.iso
- name: vmtest.sh ${{ matrix.suite }}
env:
CI: "1"
VM_CPUS: "2"
MAX_PARALLEL: "2"
run: |
cd steamify-cachyos-dev
touch ~/vms/test.log; tail -n +1 -F ~/vms/test.log & tailpid=$! # the suites' progress, as it happens
trap 'kill $tailpid 2>/dev/null' EXIT
scripts/vmtest.sh ${{ matrix.suite }}
- name: Logs
if: always()
uses: actions/upload-artifact@v4
with:
name: suite-${{ strategy.job-index }}
path: |
/mnt/work/vms/last-test.txt
/mnt/work/vms/run-*.log
retention-days: 7
if-no-files-found: ignore
+12
View File
@@ -68,6 +68,13 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine
the entry point's `for lib in ...; do` source loop and wraps everything the entry point's `for lib in ...; do` source loop and wraps everything
after that loop in `main()`. Keep that loop on one line, keep all logic in after that loop in `main()`. Keep that loop on one line, keep all logic in
functions, and don't rely on `SCRIPT_DIR` for anything but sourcing. functions, and don't rely on `SCRIPT_DIR` for anything but sourcing.
The workflow is one file for GitHub and a Gitea mirror (`github.server_url`): build and check run on both
(shellcheck through `ludeeus/action-shellcheck`, which brings its own binary; the artifact with
`upload-artifact@v4` on GitHub and `christopherhx/gitea-upload-artifact@v4` elsewhere: never mention
`upload-artifact@v3`, GitHub fails a workflow for a deprecated version even in a skipped step); the
release is `gh` on GitHub and `akkuman/gitea-release-action` on Gitea. A new release on GitHub also starts the
Steamify ISO's release (`gh workflow run iso-release.yml` in steammachine-cachyos-live-iso, secret
`ISO_DISPATCH_TOKEN`; skipped without it): the ISO repo's GitHub tag names it, the Gitea mirror builds it.
CI (`.github/workflows/bundle.yml`) publishes the bundle as release CI (`.github/workflows/bundle.yml`) publishes the bundle as release
`v$VERSION` on pushes to `main`; an existing version is never overwritten, `v$VERSION` on pushes to `main`; an existing version is never overwritten,
so bump `VERSION` for every release. so bump `VERSION` for every release.
@@ -252,6 +259,11 @@ gamescope and the Plasma desktop. Primary target: the Valve Steam Machine
kernel only pairs that with a named lookup ("Port C") when the CEC driver kernel only pairs that with a named lookup ("Port C") when the CEC driver
registered first, which never happens since amdgpu loads from the registered first, which never happens since amdgpu loads from the
initramfs. Without it `/dev/cec0` exists but stays at `f.f.f.f`. initramfs. Without it `/dev/cec0` exists but stays at `f.f.f.f`.
The source comes from one raw.githubusercontent.com download, which GitHub rate-limits (HTTP 429 after a
day of test installs, per address): it's kept in `/var/cache/steamify/cros-ec-cec-<sha256:12>.c` and reused
while its checksum matches. The name carries the checksum, so a new pin (commit + SHA-256 in `lib/cec.sh`)
downloads its own file once and removes the old one. The repo is an unofficial mirror of Valve's kernel
without releases: if it ever disappears, ship the file with Steamify. The test VMs share the host's cache.
- Power-off fix (`poweroff`, `lib/fremont-poweroff.sh`, a default sub-option - Power-off fix (`poweroff`, `lib/fremont-poweroff.sh`, a default sub-option
of `machine`): recent kernels (7.2 and the 6.x/7.0/7.1 updates with the of `machine`): recent kernels (7.2 and the 6.x/7.0/7.1 updates with the
backport) keep the firmware's S4/S5 wake bit on GPIO backport) keep the firmware's S4/S5 wake bit on GPIO
+5
View File
@@ -5,6 +5,11 @@ All notable changes, per version and per commit. Versions follow
`steamify.sh`. Versions before 0.7.0 were numbered afterwards, `steamify.sh`. Versions before 0.7.0 were numbered afterwards,
one per merged pull request. one per merged pull request.
## 2.9.4 - 2026-09-29
- `619ef1f` **docs: AGENTS.md and TECHNICAL.md: the CEC driver cache, the one workflow for GitHub and a Gitea mirror, and that a new release starts the Steamify ISO's release**
- `b624053` **chore: Version 2.9.4**
## 2.9.3 - 2026-09-29 ## 2.9.3 - 2026-09-29
- `7f5d29c` **feat(ci): a new Steamify release starts the Steamify ISO's release (a test build from the ISO repo's feat/steamify; secret ISO_DISPATCH_TOKEN)** - `7f5d29c` **feat(ci): a new Steamify release starts the Steamify ISO's release (a test build from the ISO repo's feat/steamify; secret ISO_DISPATCH_TOKEN)**
+1 -1
View File
@@ -514,7 +514,7 @@ immediately, which can turn into a loop - see
| `services/` | The systemd units the scripts install (`service_file`, `@KEY@` placeholders); see its README | | `services/` | The systemd units the scripts install (`service_file`, `@KEY@` placeholders); see its README |
| `patches/` | Module sources and patches the scripts build or apply (`patch_file`); see its README | | `patches/` | Module sources and patches the scripts build or apply (`patch_file`); see its README |
| `.github/tools/bundle.sh` | Builds the single-file version (`dist/steamify.sh`), with `patches/` and `services/` embedded | | `.github/tools/bundle.sh` | Builds the single-file version (`dist/steamify.sh`), with `patches/` and `services/` embedded |
| `.github/workflows/bundle.yml` | Builds and checks it on every push; publishes it on `main` | | `.github/workflows/bundle.yml` | Builds and checks it on every push (GitHub and a Gitea mirror); publishes it on `main`, and starts the Steamify ISO's release |
The single-file version is generated: on every push to `main`, GitHub The single-file version is generated: on every push to `main`, GitHub
Actions runs `.github/tools/bundle.sh`, checks the result with `bash -n` and Actions runs `.github/tools/bundle.sh`, checks the result with `bash -n` and
+1 -1
View File
@@ -15,7 +15,7 @@
set -uo pipefail set -uo pipefail
# Release version, see CHANGELOG.md. # Release version, see CHANGELOG.md.
VERSION=2.9.3 VERSION=2.9.4
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"