From e165202075a4b5bd6d5f462aa67a93aace766604 Mon Sep 17 00:00:00 2001 From: Rick Peters Date: Wed, 30 Sep 2026 08:20:51 +0200 Subject: [PATCH] feat(ci): Gitea flow is build -> test (boot loader test per loader, parallel) -> release; drop upstream build.yml iso-2-gitea-build.yml now has three jobs. The ISO goes between them as an artifact; the test job runs steamify-cachyos-dev's vmbootloadertest.sh --install for limine, systemd-boot and grub (needs /dev/kvm on the runner, fails at once with a reason without it); the release is only made when every test passed. --- .github/workflows/build.yml | 141 ---------------------- .github/workflows/iso-2-gitea-build.yml | 148 ++++++++++++++++++++++-- AGENTS.md | 8 +- 3 files changed, 143 insertions(+), 154 deletions(-) delete mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 059be29..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,141 +0,0 @@ -name: Desktop ISO -on: - push: - branches: - - master - pull_request: - -concurrency: - group: ${{ github.ref }} - cancel-in-progress: true - -jobs: - build: - # CachyOS's plain ISO and its quicktest matrix: only in CachyOS's own repo, not in this fork - # (the Steamify ISO is iso-2-gitea-build.yml). - if: github.repository == 'CachyOS/CachyOS-Live-ISO' - runs-on: ubuntu-latest - container: - image: archlinux:base-devel - options: --privileged - name: Build - outputs: - builddate: ${{ steps.date.outputs.builddate }} - steps: - - name: Get build date - id: date - run: | - echo "builddate=$(date +'%y%m%d')" >> $GITHUB_OUTPUT - - - name: Clone CachyOS-Live-ISO - id: clone - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Add CachyOS keyring - id: keyring - run: | - pacman-key --init - pacman-key --recv-keys F3B607488DB35A47 --keyserver keyserver.ubuntu.com - pacman-key --lsign-key F3B607488DB35A47 - - sed -i '/^\[core\]$/i[cachyos]\nServer = https://mirror.cachyos.org/repo/$arch/$repo\n' /etc/pacman.conf - - - name: Install dependencies - id: dependencies - run: | - sudo pacman -Syu --noconfirm archiso cachyos-keyring mkinitcpio-archiso squashfs-tools grub - - - name: Create build user - id: user-archiso - run: | - useradd builder -m - echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers - chmod -R a+rw . - - - name: Build ISO (${{ steps.date.outputs.builddate }}) - id: build - run: | - sudo -H -E -u builder ./buildiso.sh - - - name: Upload ISO to artifacts - id: upload - uses: actions/upload-artifact@v4 - with: - name: cachyos-desktop-linux-${{ steps.date.outputs.builddate }} - path: out/desktop/* - quicktest: - name: Testing (${{ matrix.bootloader }} / ${{ matrix.filesystem }}) - runs-on: ubuntu-latest - needs: build - container: - image: archlinux:base-devel - options: --privileged - strategy: - fail-fast: false - max-parallel: 4 - matrix: - bootloader: [grub, systemd-boot, refind, limine] - filesystem: [btrfs, xfs, ext4, f2fs, zfs] - steps: - - name: Clone CachyOS-Live-ISO - id: clone - uses: actions/checkout@v6 - - - name: Install dependencies - id: dependencies - run: | - pacman -Syu --noconfirm git ffmpeg imagemagick tesseract-data-eng qemu-desktop - - - name: Create build user - id: user - run: | - useradd builder -m - echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers - chmod -R a+rw . - - - name: Build quickemu - id: quickemu - run: | - sudo -u builder git clone https://aur.archlinux.org/quickemu.git - cd quickemu - sudo -H -E -u builder makepkg --syncdeps --noconfirm - pacman -U --noconfirm quickemu*.pkg.tar.zst - cd .. - - - name: Clone quicktest - id: clone-quicktest - uses: actions/checkout@v6 - with: - repository: 'quickemu-project/quicktest' - path: 'quicktest' - - - name: Download ISO - id: download - uses: actions/download-artifact@v4 - with: - path: machines/cachyos-dailylive - merge-multiple: true - - - name: Run quicktest - id: quicktest - run: | - ./quicktest/quicktest test_install_calamares cachyos dailylive - env: - QT_NOTIFY: "false" - QT_OPEN_RESULTS: "false" - QT_QUICKGET_SKIP: "true" - QT_TESTCASES_DIR: "./testcases" - QUICKEMU_DISPLAY: "none" - QUICKEMU_VM_DIR: "./machines" - TEST_BOOTLOADER: "${{ matrix.bootloader }}" - TEST_FILESYSTEM: "${{ matrix.filesystem }}" - - - name: Upload results to artifacts - id: upload-results - if: always() - uses: actions/upload-artifact@v4 - with: - name: cachyos-desktop-linux-results-${{needs.build.outputs.builddate}}-${{ matrix.bootloader }}-${{ matrix.filesystem }} - path: results/* diff --git a/.github/workflows/iso-2-gitea-build.yml b/.github/workflows/iso-2-gitea-build.yml index edae835..75bb992 100644 --- a/.github/workflows/iso-2-gitea-build.yml +++ b/.github/workflows/iso-2-gitea-build.yml @@ -4,9 +4,11 @@ # checksums and package list to the mirror's release for that tag. The tag names the Steamify version and # the time: v-- (master) or v-dev.<...> (feat/steamify, a pre-release); # the ISO gets exactly that Steamify release, and its label the same moment. GitHub skips it. -# The runner needs privileged containers (archiso mounts loop devices) and ~20 GB of disk; Gitea's +# Three jobs: build the ISO -> test it (the boot loader test of steamify-cachyos-dev, one job per loader, in +# parallel when the runner's capacity allows) -> release, only when every test passed. +# The runner needs /dev/kvm, privileged containers (archiso mounts loop devices) and ~20 GB of disk; Gitea's # [repository.release] FILE_MAX_SIZE must allow the ISO (default 2 GB). -name: ISO 2/2 · Build and publish (Gitea) +name: ISO 2/2 · Build, test and publish (Gitea) on: push: @@ -18,7 +20,8 @@ concurrency: cancel-in-progress: true jobs: - iso: + build: + name: Build the ISO if: github.server_url != 'https://github.com' runs-on: ubuntu-latest container: @@ -27,6 +30,8 @@ jobs: defaults: run: shell: bash + outputs: + steamify: ${{ steps.tag.outputs.steamify }} steps: - name: Tools run: | @@ -34,6 +39,132 @@ jobs: # nodejs: the actions below run in this container pacman -Syu --noconfirm --needed archiso mkinitcpio-archiso git squashfs-tools grub sudo nodejs curl jq + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Version and time from the tag + id: tag + run: | + tag="${{ github.ref_name }}" + [[ "$tag" =~ ^v([0-9]+\.[0-9]+\.[0-9]+)-(dev\.)?([0-9]{4})\.([0-9]{2})\.([0-9]{2})-([0-9]{4})$ ]] || + { echo "::error::$tag is not a Steamify ISO release tag (v-[dev.]-)"; exit 1; } + m=("${BASH_REMATCH[@]}") + { + echo "STEAMIFY_VERSION=${m[1]}" + # One moment for the ISO's label (profiledef.sh) and the release's name: the tag's (UTC). + echo "STEAMIFY_BUILD_STAMP=${m[3]}${m[4]}${m[5]}_${m[6]}" + echo "ISO_PRERELEASE=$([ -n "${m[2]}" ] && echo true || echo false)" + # The ISO's file name: the tag without its v (profiledef.sh). + echo "STEAMIFY_ISO_VERSION=${tag#v}" + } >> "$GITHUB_ENV" + + echo "steamify=${m[1]}" >> "$GITHUB_OUTPUT" + + - name: Steamify on the ISO (the version the tag names) + run: ./steamify-prepare.sh + + - name: Build + run: | + ./build-live-modules.sh + ./build-calamares-modules.sh + ./buildiso.sh -p desktop -w || ./buildiso.sh -p desktop -c -w + + + - name: Keep the ISO for the tests and the release + uses: christopherhx/gitea-upload-artifact@v4 + with: + name: iso + path: | + out/desktop/*.iso + out/desktop/*.iso.sha256 + out/desktop/*.iso.sha1 + out/desktop/*.pkgs.txt + retention-days: 3 + + test: + name: Test ${{ matrix.loader }} + needs: build + runs-on: ubuntu-latest + timeout-minutes: 90 + container: + image: docker.io/cachyos/cachyos:latest + options: --privileged + strategy: + fail-fast: false + matrix: + loader: [limine, systemd-boot, grub] + defaults: + run: + shell: bash + steps: + - name: Tools and KVM + run: | + pacman-key --init && pacman-key --populate + # nodejs: the actions below run in this container + pacman -Syu --noconfirm --needed qemu-desktop edk2-ovmf openssh libarchive procps-ng util-linux python git nodejs sudo + # Fail at once, with a reason, when the runner cannot run a VM with KVM. + [ -c /dev/kvm ] || { echo "::error::no /dev/kvm in this container: the runner needs KVM (and privileged containers)"; exit 1; } + nproc; free -g | sed -n 2p; df -h . | tail -n 1 + + # The test scripts expect their repos side by side: steamify-cachyos-dev (the scripts), + # steamify-cachyos at the Steamify version the ISO has (shared into the VM, 9p `repo`). + - uses: actions/checkout@v4 + with: + repository: theupriser/steamify-cachyos-dev + path: steamify-cachyos-dev + - uses: actions/checkout@v4 + with: + repository: theupriser/steamify-cachyos + ref: v${{ needs.build.outputs.steamify }} + path: steamify-cachyos + + - uses: christopherhx/gitea-download-artifact@v4 + with: + name: iso + path: iso + + - name: Boot loader test (${{ matrix.loader }}) + env: + CI: "1" + VM_TIMEZONE: UTC + VM_ISO_DIR: ${{ github.workspace }}/iso + run: | + mkdir -p ~/.ssh ~/vms/pkg-cache + ssh-keygen -q -t ed25519 -N "" -C steamify-vm -f ~/.ssh/steamify-vm_ed25519 + iso="$(ls "$VM_ISO_DIR"/*.iso | head -n 1)" + cd steamify-cachyos-dev + VM_ISO="$iso" scripts/vmbootloadertest.sh "${{ matrix.loader }}" --install + + - name: Logs + if: always() + uses: christopherhx/gitea-upload-artifact@v4 + with: + name: test-${{ matrix.loader }} + path: | + /root/vms/bl-${{ matrix.loader }}.test.log + /root/vms/bl-${{ matrix.loader }}/vm.log + retention-days: 7 + if-no-files-found: ignore + + release: + name: Release + needs: [build, test] + runs-on: ubuntu-latest + container: + image: docker.io/cachyos/cachyos:latest + defaults: + run: + shell: bash + steps: + - name: Tools + run: | + pacman-key --init && pacman-key --populate + # nodejs: the actions below run in this container + pacman -Syu --noconfirm --needed git nodejs curl jq + + - uses: actions/checkout@v4 with: fetch-depth: 0 @@ -53,14 +184,11 @@ jobs: echo "STEAMIFY_ISO_VERSION=${tag#v}" } >> "$GITHUB_ENV" - - name: Steamify on the ISO (the version the tag names) - run: ./steamify-prepare.sh - - name: Build - run: | - ./build-live-modules.sh - ./build-calamares-modules.sh - ./buildiso.sh -p desktop -w || ./buildiso.sh -p desktop -c -w + - uses: christopherhx/gitea-download-artifact@v4 + with: + name: iso + path: out/desktop - name: Release name and notes id: rel diff --git a/AGENTS.md b/AGENTS.md index 3724971..4a112fb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -118,8 +118,10 @@ Full write-up, with every trap: `steamify-iso-release` in steamify-cachyos-dev. release, whose `bundle.yml` needs the secret `ISO_DISPATCH_TOKEN`) names the release: the Steamify version plus GitHub's UTC time, `vX.Y.Z-[dev.]YYYY.MM.DD-HHMM`, an **annotated** tag and a release with notes and the direct download link. `feat/steamify` makes a `dev.` pre-release, `master` a real one. -- `.github/workflows/iso-2-gitea-build.yml` (Gitea, `on: push: tags: v*`, skipped on GitHub) builds the ISO for that - tag and attaches it to the mirror's release. The tag decides everything: Steamify version (`steamify-prepare.sh` +- `.github/workflows/iso-2-gitea-build.yml` (Gitea, `on: push: tags: v*`, skipped on GitHub) runs three jobs for that + tag: build the ISO, test it (steamify-cachyos-dev's `scripts/vmbootloadertest.sh --install`, one job per boot loader, + parallel up to the runner's capacity; needs `/dev/kvm` on the runner and checks out steamify-cachyos-dev `main` and + steamify-cachyos at the ISO's version from the mirror), and only when all tests passed attach it to the mirror's release. The tag decides everything: Steamify version (`steamify-prepare.sh` takes `STEAMIFY_VERSION`), file name (`STEAMIFY_ISO_VERSION` -> `iso_version` in `profiledef.sh`), label (`STEAMIFY_BUILD_STAMP`), boot menu and `/etc/steammachine-iso-build`. The build reads no clock; without a tag everything says `local`. @@ -129,4 +131,4 @@ Full write-up, with every trap: `steamify-iso-release` in steamify-cachyos-dev. GitHub doesn't have, and the release with them. GitHub releases can't hold the ISO (2 GB per file). - Gitea needs `[repository.release] FILE_MAX_SIZE` above the ISO (413 otherwise) and the runner `container: privileged: true` (archiso mounts `/proc`); the workflow's `--privileged` option is ignored. -- CachyOS's own `Desktop ISO` workflow (`build.yml`) only runs in `CachyOS/CachyOS-Live-ISO`. +- CachyOS's own `Desktop ISO` workflow (`build.yml`) is removed here; the test job of iso-2-gitea-build.yml replaces it.