Skip to content

Commit 8b47e61

Browse files
committed
ci: reuse prebuilt Omarchy VM from GHCR
1 parent 4bc428a commit 8b47e61

9 files changed

Lines changed: 190 additions & 64 deletions

‎.github/workflows/midscene-experimental.yml‎

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
name: Midscene experimental
22

3-
on:
4-
push:
5-
branches: [ci/midscene-e2e]
6-
paths:
7-
# The VM install is deliberately expensive. Push this marker only when
8-
# the pinned Omarchy ISO or installer harness needs to be revalidated.
9-
- "tests/midscene/.rebuild-omarchy-vm"
10-
workflow_dispatch:
3+
on: workflow_dispatch
114

125
permissions:
136
contents: read
7+
packages: read
148

159
concurrency:
1610
group: midscene-experimental-${{ github.ref }}
@@ -57,8 +51,16 @@ jobs:
5751
"${MIDSCENE_MODEL_BASE_URL%/}/chat/completions" \
5852
>/dev/null
5953
60-
- name: Install Omarchy VM
61-
run: tests/midscene/install-omarchy-vm.sh
54+
- name: Install ORAS client
55+
uses: oras-project/setup-oras@22ce207df3b08e061f537244349aac6ae1d214f6 # v1
56+
57+
- name: Sign in to GitHub Container Registry
58+
run: echo "$GHCR_TOKEN" | oras login ghcr.io --username "$GITHUB_ACTOR" --password-stdin
59+
env:
60+
GHCR_TOKEN: ${{ github.token }}
61+
62+
- name: Restore prebuilt Omarchy VM
63+
run: tests/midscene/restore-omarchy-vm.sh
6264

6365
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
6466
with:
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Build Omarchy VM image
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches: [ci/midscene-e2e]
7+
paths:
8+
- "tests/midscene/.rebuild-omarchy-vm"
9+
- "tests/midscene/install-omarchy-vm.sh"
10+
- "tests/midscene/prepare-omarchy-host.sh"
11+
- "tests/midscene/publish-omarchy-vm.sh"
12+
- "tests/midscene/omarchy-vm.env"
13+
14+
permissions:
15+
contents: read
16+
packages: write
17+
18+
concurrency:
19+
group: omarchy-vm-image-${{ github.ref }}
20+
cancel-in-progress: false
21+
22+
jobs:
23+
build:
24+
name: Install and publish Omarchy base VM
25+
runs-on: ubuntu-latest
26+
timeout-minutes: 70
27+
steps:
28+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
29+
with:
30+
persist-credentials: false
31+
32+
- uses: oras-project/setup-oras@22ce207df3b08e061f537244349aac6ae1d214f6 # v1
33+
34+
- name: Install Omarchy from the verified official ISO
35+
run: tests/midscene/install-omarchy-vm.sh
36+
37+
- name: Sign in to GitHub Container Registry
38+
run: echo "$GHCR_TOKEN" | oras login ghcr.io --username "$GITHUB_ACTOR" --password-stdin
39+
env:
40+
GHCR_TOKEN: ${{ github.token }}
41+
42+
- name: Publish versioned Omarchy base VM
43+
run: tests/midscene/publish-omarchy-vm.sh
44+
45+
- name: Upload installer evidence
46+
if: always()
47+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
48+
with:
49+
name: omarchy-vm-image-installer-evidence
50+
path: .midscene-omarchy/omarchy-iso/test-runs/**/runs/**
51+
if-no-files-found: warn
52+
retention-days: 3

‎tests/midscene/README.md‎

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,22 @@
33
Everything under this directory is developed on `ci/midscene-e2e`; it is not
44
part of the release branch.
55

6-
The first CI stage proves that a GitHub-hosted runner can install the exact
6+
The image-builder CI proves that a GitHub-hosted runner can install the exact
77
official Omarchy ISO in a headless QEMU/KVM VM. It reuses Omarchy's own ISO
8-
acceptance harness and saves installer screenshots and logs as short-lived
9-
artifacts. It does not upload the VM disk or its temporary SSH key.
8+
acceptance harness, saves installer evidence as short-lived artifacts, and
9+
publishes the resulting test-only VM bundle to this repository's private GHCR
10+
namespace.
1011

1112
The full Omarchy install is intentionally not triggered by ordinary pushes.
12-
During development on this branch, deliberately add/update
13-
`tests/midscene/.rebuild-omarchy-vm` only when the pinned ISO or installer
14-
harness changes. Once this workflow exists on the default branch, it can also
15-
be started with `workflow_dispatch`. GitHub-hosted runners are ephemeral, so
16-
every such full rebuild downloads the pinned ISO again; routine Ubuntu
17-
Midscene tests do not need the ISO.
13+
`Build Omarchy VM image` installs the verified official ISO only when its
14+
version, checksum, harness, or rebuild marker changes, then publishes the
15+
installed base disk as a private, versioned OCI artifact in GHCR. The
16+
experimental E2E restores that base and creates a throwaway overlay, so normal
17+
manual runs no longer download or install the 6 GB ISO.
18+
19+
The GHCR artifact also contains the harness-created UEFI state and SSH key.
20+
That key is valid only for the disposable test VM, whose SSH port is bound to
21+
the runner's loopback interface; it is never used for GitHub or production.
1822

1923
Omarchy 4.0.3 was installed successfully on a GitHub-hosted runner in
2024
[Actions run 34866563731](https://github.com/quanru/doubao-say/actions/runs/34866563731).

‎tests/midscene/install-omarchy-vm.sh‎

Lines changed: 7 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,54 +4,18 @@ set -euo pipefail
44
# This is deliberately a real Omarchy installation, not an Arch container
55
# dressed up with a few Omarchy files. The official ISO acceptance harness
66
# drives the installer through QEMU screenshots, OCR and virtual keystrokes.
7-
readonly ISO_VERSION="4.0.3"
8-
readonly ISO_SHA256="03d60bc74306dca51f96e1a84b690871d8d606826b260edd0208962da8507d14"
9-
readonly ISO_HARNESS_SHA="a23f8d464dcb0616a61bfaa8026e23d0533da209"
107
readonly WORK_DIR="$PWD/.midscene-omarchy"
11-
readonly ISO_PATH="$WORK_DIR/omarchy-${ISO_VERSION}.iso"
8+
source "$PWD/tests/midscene/omarchy-vm.env"
9+
readonly ISO_PATH="$WORK_DIR/omarchy-${OMARCHY_ISO_VERSION}.iso"
1210
readonly HARNESS_DIR="$WORK_DIR/omarchy-iso"
1311

14-
if [[ ! -c /dev/kvm ]]; then
15-
echo "::error::This GitHub runner does not expose /dev/kvm; a real Omarchy VM cannot be started."
16-
exit 1
17-
fi
18-
19-
sudo chmod 0666 /dev/kvm
20-
21-
# The ISO is about 6 GB and the installed qcow2 image is sparse but sizeable.
22-
# GitHub's image includes large SDKs that this isolated job does not need.
23-
sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc
24-
sudo apt-get update
25-
sudo apt-get install -y --no-install-recommends \
26-
curl git imagemagick ovmf qemu-system-x86 qemu-utils socat \
27-
tesseract-ocr tesseract-ocr-eng
28-
29-
mkdir -p "$WORK_DIR"
12+
tests/midscene/prepare-omarchy-host.sh
3013
df -h "$WORK_DIR"
3114

3215
curl --fail --location --retry 5 --retry-all-errors \
33-
"https://iso.omarchy.org/omarchy-${ISO_VERSION}.iso" \
16+
"https://iso.omarchy.org/omarchy-${OMARCHY_ISO_VERSION}.iso" \
3417
--output "$ISO_PATH"
35-
printf '%s %s\n' "$ISO_SHA256" "$ISO_PATH" | sha256sum --check --strict
36-
37-
git init --quiet "$HARNESS_DIR"
38-
git -C "$HARNESS_DIR" remote add origin https://github.com/omacom/omarchy-iso.git
39-
git -C "$HARNESS_DIR" fetch --quiet --depth 1 origin "$ISO_HARNESS_SHA"
40-
git -C "$HARNESS_DIR" checkout --quiet --detach FETCH_HEAD
41-
42-
# Omarchy 4.0.3's welcome tagline says "Agentic Linux" while this pinned
43-
# harness revision still waits for the former "Opinionated" tagline. Keep the
44-
# test on the official ISO and change only the OCR readiness marker.
45-
grep -q 'wait_for_screen "Opinionated"' "$HARNESS_DIR/bin/omarchy-iso-test"
46-
sed -i 's/wait_for_screen "Opinionated"/wait_for_screen "Agentic"/g' \
47-
"$HARNESS_DIR/bin/omarchy-iso-test"
48-
49-
# The official harness names Arch paths and its package helper. Adapt only
50-
# those host-side dependencies; the guest still boots and installs the exact
51-
# verified official ISO.
52-
sudo mkdir -p /usr/share/edk2/x64
53-
sudo ln -sf /usr/share/OVMF/OVMF_CODE_4M.fd /usr/share/edk2/x64/OVMF_CODE.4m.fd
54-
sudo ln -sf /usr/share/OVMF/OVMF_VARS_4M.fd /usr/share/edk2/x64/OVMF_VARS.4m.fd
18+
printf '%s %s\n' "$OMARCHY_ISO_SHA256" "$ISO_PATH" | sha256sum --check --strict
5519

5620
readonly SHIM_DIR="$(mktemp -d)"
5721
trap 'rm -rf "$SHIM_DIR"' EXIT
@@ -66,5 +30,5 @@ PATH="$SHIM_DIR:$PATH" "$HARNESS_DIR/bin/omarchy-iso-test" \
6630
--timeout 3000 \
6731
--no-preview
6832

69-
test -s "$HARNESS_DIR/test-runs/omarchy-${ISO_VERSION}/base.qcow2"
70-
echo "PASS: a complete Omarchy ${ISO_VERSION} base VM was installed on the GitHub runner"
33+
test -s "$HARNESS_DIR/test-runs/omarchy-${OMARCHY_ISO_VERSION}/base.qcow2"
34+
echo "PASS: a complete Omarchy ${OMARCHY_ISO_VERSION} base VM was installed on the GitHub runner"

‎tests/midscene/omarchy-vm.env‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
OMARCHY_ISO_VERSION=4.0.3
2+
OMARCHY_ISO_SHA256=03d60bc74306dca51f96e1a84b690871d8d606826b260edd0208962da8507d14
3+
OMARCHY_ISO_HARNESS_SHA=a23f8d464dcb0616a61bfaa8026e23d0533da209
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
readonly ROOT_DIR="$PWD"
5+
readonly WORK_DIR="$ROOT_DIR/.midscene-omarchy"
6+
readonly HARNESS_DIR="$WORK_DIR/omarchy-iso"
7+
8+
# shellcheck source=omarchy-vm.env
9+
source "$ROOT_DIR/tests/midscene/omarchy-vm.env"
10+
11+
if [[ ! -c /dev/kvm ]]; then
12+
echo "::error::This GitHub runner does not expose /dev/kvm; a real Omarchy VM cannot be started."
13+
exit 1
14+
fi
15+
16+
sudo chmod 0666 /dev/kvm
17+
sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/ghc
18+
sudo apt-get update
19+
sudo apt-get install -y --no-install-recommends \
20+
curl git imagemagick ovmf qemu-system-x86 qemu-utils socat \
21+
tesseract-ocr tesseract-ocr-eng zstd
22+
23+
mkdir -p "$WORK_DIR"
24+
git init --quiet "$HARNESS_DIR"
25+
git -C "$HARNESS_DIR" remote add origin https://github.com/omacom/omarchy-iso.git
26+
git -C "$HARNESS_DIR" fetch --quiet --depth 1 origin "$OMARCHY_ISO_HARNESS_SHA"
27+
git -C "$HARNESS_DIR" checkout --quiet --detach FETCH_HEAD
28+
29+
grep -q 'wait_for_screen "Opinionated"' "$HARNESS_DIR/bin/omarchy-iso-test"
30+
sed -i 's/wait_for_screen "Opinionated"/wait_for_screen "Agentic"/g' \
31+
"$HARNESS_DIR/bin/omarchy-iso-test"
32+
33+
sudo mkdir -p /usr/share/edk2/x64
34+
sudo ln -sf /usr/share/OVMF/OVMF_CODE_4M.fd /usr/share/edk2/x64/OVMF_CODE.4m.fd
35+
sudo ln -sf /usr/share/OVMF/OVMF_VARS_4M.fd /usr/share/edk2/x64/OVMF_VARS.4m.fd
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
readonly ROOT_DIR="$PWD"
5+
readonly WORK_DIR="$ROOT_DIR/.midscene-omarchy"
6+
7+
# shellcheck source=omarchy-vm.env
8+
source "$ROOT_DIR/tests/midscene/omarchy-vm.env"
9+
10+
readonly BASE_DIR="$WORK_DIR/omarchy-iso/test-runs/omarchy-${OMARCHY_ISO_VERSION}"
11+
readonly BUNDLE_DIR="$WORK_DIR/registry"
12+
readonly ARCHIVE="$BUNDLE_DIR/omarchy-base.tar.zst"
13+
readonly IMAGE_TAG="${OMARCHY_ISO_VERSION}-${OMARCHY_ISO_SHA256:0:12}-${OMARCHY_ISO_HARNESS_SHA:0:12}"
14+
readonly IMAGE="ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/doubao-say-omarchy-ci-base:${IMAGE_TAG}"
15+
16+
for file in base.qcow2 OVMF_VARS.4m.fd id_ed25519 id_ed25519.pub; do
17+
test -s "$BASE_DIR/$file"
18+
done
19+
20+
mkdir -p "$BUNDLE_DIR"
21+
tar -C "$BASE_DIR" --sparse -I 'zstd -T0 -6' -cf "$ARCHIVE" \
22+
base.qcow2 OVMF_VARS.4m.fd id_ed25519 id_ed25519.pub
23+
sha256sum "$ARCHIVE" | sed 's# .*/# #' >"$BUNDLE_DIR/SHA256SUMS"
24+
du -h "$ARCHIVE"
25+
26+
oras push "$IMAGE" \
27+
--artifact-type application/vnd.lifeos.omarchy-vm.v1 \
28+
--annotation "org.opencontainers.image.source=https://github.com/$GITHUB_REPOSITORY" \
29+
--annotation "org.opencontainers.image.version=$OMARCHY_ISO_VERSION" \
30+
"$ARCHIVE:application/vnd.lifeos.omarchy-vm.layer.v1+zstd" \
31+
"$BUNDLE_DIR/SHA256SUMS:text/plain"
32+
33+
echo "PASS: published $IMAGE"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
readonly ROOT_DIR="$PWD"
5+
readonly WORK_DIR="$ROOT_DIR/.midscene-omarchy"
6+
7+
# shellcheck source=omarchy-vm.env
8+
source "$ROOT_DIR/tests/midscene/omarchy-vm.env"
9+
10+
readonly BASE_DIR="$WORK_DIR/omarchy-iso/test-runs/omarchy-${OMARCHY_ISO_VERSION}"
11+
readonly BUNDLE_DIR="$WORK_DIR/registry"
12+
readonly IMAGE_TAG="${OMARCHY_ISO_VERSION}-${OMARCHY_ISO_SHA256:0:12}-${OMARCHY_ISO_HARNESS_SHA:0:12}"
13+
readonly IMAGE="ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/doubao-say-omarchy-ci-base:${IMAGE_TAG}"
14+
15+
tests/midscene/prepare-omarchy-host.sh
16+
mkdir -p "$BASE_DIR" "$BUNDLE_DIR"
17+
oras pull --output "$BUNDLE_DIR" "$IMAGE"
18+
(cd "$BUNDLE_DIR" && sha256sum --check --strict SHA256SUMS)
19+
tar -C "$BASE_DIR" --use-compress-program=unzstd -xf "$BUNDLE_DIR/omarchy-base.tar.zst"
20+
21+
# In --reuse-base mode the official harness uses the ISO basename only to
22+
# locate BASE_DIR; it does not read ISO contents.
23+
printf 'restored-from=%s\n' "$IMAGE" >"$WORK_DIR/omarchy-${OMARCHY_ISO_VERSION}.iso"
24+
25+
for file in base.qcow2 OVMF_VARS.4m.fd id_ed25519 id_ed25519.pub; do
26+
test -s "$BASE_DIR/$file"
27+
done
28+
chmod 0600 "$BASE_DIR/id_ed25519"
29+
qemu-img check "$BASE_DIR/base.qcow2"
30+
rm -rf "$BUNDLE_DIR"
31+
echo "PASS: restored $IMAGE"

‎tests/midscene/run-omarchy-midscene.sh‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ set -euo pipefail
44
readonly ROOT_DIR="$PWD"
55
readonly WORK_DIR="$ROOT_DIR/.midscene-omarchy"
66
readonly HARNESS_DIR="$WORK_DIR/omarchy-iso"
7-
readonly ISO_PATH="$WORK_DIR/omarchy-4.0.3.iso"
8-
readonly BASE_DIR="$HARNESS_DIR/test-runs/omarchy-4.0.3"
7+
# shellcheck source=omarchy-vm.env
8+
source "$ROOT_DIR/tests/midscene/omarchy-vm.env"
9+
readonly ISO_PATH="$WORK_DIR/omarchy-${OMARCHY_ISO_VERSION}.iso"
10+
readonly BASE_DIR="$HARNESS_DIR/test-runs/omarchy-${OMARCHY_ISO_VERSION}"
911
readonly SSH_KEY="$BASE_DIR/id_ed25519"
1012
readonly SSH_PORT=2222
1113
readonly PLUGIN_DIR="/home/omarchy/.config/omarchy/plugins/md.lifeos.doubao-say"

0 commit comments

Comments
 (0)