Skip to content

Omarchy 4.0.3

Omarchy 4.0.3 #265

name: Omarchy 4.0.3
run-name: Omarchy 4.0.3
on:
push:
branches: [main]
paths: &e2e-paths
- ".github/workflows/midscene-omarchy-4.0.3.yml"
- ".github/workflows/deploy-midscene-report.yml"
- "scripts/build-pages-report.mjs"
- "scripts/report-cases.mjs"
- "scripts/render-ci-report-summary.mjs"
- "scripts/write-ci-shard-status.mjs"
- "scripts/verify-pages-report.mjs"
- "scripts/verify-omarchy-evidence.mjs"
- "scripts/omarchy-shell-evidence.mjs"
- "tests/contracts/test_pages_report_history.mjs"
- "tests/e2e/package.json"
- "tests/e2e/package-lock.json"
- "tests/e2e/gtk_fixture.py"
- "tests/e2e/gtk_onboarding_fixture.py"
- "tests/e2e/gtk_runtime_fixture.py"
- "tests/e2e/capture-report-preview.mjs"
- "tests/e2e/cases/**"
- "tests/e2e/midscene.config.ts"
- "tests/e2e/run-omarchy-midscene.sh"
- "tests/e2e/restore-omarchy-vm.sh"
- "tests/e2e/omarchy-vm.env"
- "src/**"
- "manifest.json"
- "install.sh"
- "setup-omarchy.sh"
- "start.sh"
- "omarchy/**"
pull_request:
branches: [main]
paths: *e2e-paths
workflow_dispatch:
inputs:
project:
description: Run one Midscene project for focused verification
type: choice
default: all
options:
- all
- omarchy-shard-1
- omarchy-shard-2
- omarchy-shard-3
- omarchy-shard-4
- omarchy-shell
- omarchy-providers
permissions:
contents: read
packages: read
concurrency:
group: midscene-model-e2e-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
omarchy-e2e:
name: Midscene visual (${{ matrix.project }})
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
# Each shard restores an independent disposable VM. Sharing one Hyprland
# session would make fixture resets, focus and screenshots race.
fail-fast: false
max-parallel: 5
matrix:
project: >-
${{ fromJSON((inputs.project != '' && inputs.project != 'all') &&
format('["{0}"]', inputs.project) ||
'["omarchy-shard-1","omarchy-shard-2","omarchy-shard-3","omarchy-shard-4","omarchy-shell"]') }}
env:
MIDSCENE_MODEL_API_KEY: ${{ secrets.MIDSCENE_MODEL_API_KEY }}
MIDSCENE_MODEL_NAME: ${{ secrets.MIDSCENE_MODEL_NAME }}
MIDSCENE_MODEL_BASE_URL: ${{ secrets.MIDSCENE_MODEL_BASE_URL }}
MIDSCENE_MODEL_FAMILY: ${{ secrets.MIDSCENE_MODEL_FAMILY }}
MIDSCENE_MODEL_REASONING_ENABLED: ${{ secrets.MIDSCENE_MODEL_REASONING_ENABLED }}
MIDSCENE_COMPUTER_HEADLESS_LINUX: "true"
MIDSCENE_REPLANNING_CYCLE_LIMIT: "40"
# The configured model endpoint is reachable over IPv4; disabling Node's
# family race avoids intermittent runner-side IPv6 connection timeouts.
NODE_OPTIONS: "--dns-result-order=ipv4first --no-network-family-autoselection"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Require Midscene model configuration
run: |
test -n "$MIDSCENE_MODEL_API_KEY"
test -n "$MIDSCENE_MODEL_NAME"
test -n "$MIDSCENE_MODEL_BASE_URL"
test -n "$MIDSCENE_MODEL_FAMILY"
- name: Check Midscene model before the expensive VM install
run: |
payload=$(jq -nc --arg model "$MIDSCENE_MODEL_NAME" '{
model: $model,
messages: [{role: "user", content: "Reply OK."}],
max_tokens: 1
}')
curl --fail --silent --show-error \
--connect-timeout 15 --max-time 90 \
--retry 4 --retry-all-errors --retry-delay 5 --retry-max-time 90 \
-H "Authorization: Bearer $MIDSCENE_MODEL_API_KEY" \
-H "Content-Type: application/json" \
--data "$payload" \
"${MIDSCENE_MODEL_BASE_URL%/}/chat/completions" \
>/dev/null
- name: Install ORAS client
uses: oras-project/setup-oras@1d808f7d7f6995cc68b7bf507bfe5c5446e1dc9d # v2.0.1
- name: Sign in to GitHub Container Registry
run: echo "$GHCR_TOKEN" | oras login ghcr.io --username "$GITHUB_ACTOR" --password-stdin
env:
GHCR_TOKEN: ${{ github.token }}
- name: Restore prebuilt Omarchy VM
run: tests/e2e/restore-omarchy-vm.sh
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: "22"
cache: npm
cache-dependency-path: tests/e2e/package-lock.json
- name: Install Midscene and VNC bridge
id: test-dependencies
run: |
sudo apt-get install -y --no-install-recommends \
fluxbox tigervnc-viewer x11-xserver-utils xvfb
for attempt in 1 2 3; do
if npm --prefix tests/e2e ci --include=optional --ignore-scripts; then
exit 0
fi
echo "npm install attempt $attempt failed; retrying." >&2
sleep 10
done
exit 1
- name: Run real Omarchy Midscene project
id: midscene-test
env:
PROJECT: ${{ matrix.project }}
run: tests/e2e/run-omarchy-midscene.sh "$PROJECT"
- name: Capture report evidence
id: capture-report
if: always() && !cancelled() && steps.test-dependencies.outcome == 'success'
env:
PROJECT: ${{ matrix.project }}
run: |
node tests/e2e/capture-report-preview.mjs \
--report-dir tests/e2e/midscene_run \
--projects "$PROJECT"
- name: Record shard result for report aggregation
if: always() && !cancelled()
env:
PROJECT: ${{ matrix.project }}
TEST_OUTCOME: ${{ steps.midscene-test.outcome }}
CAPTURE_OUTCOME: ${{ steps.capture-report.outcome }}
run: |
node scripts/write-ci-shard-status.mjs \
--output "tests/e2e/midscene_run/ci-shard-status-$PROJECT.json" \
--project "$PROJECT" \
--test-outcome "${TEST_OUTCOME:-skipped}" \
--capture-outcome "${CAPTURE_OUTCOME:-skipped}"
- name: Upload installer evidence
if: always() && !cancelled()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: omarchy-vm-installer-evidence-${{ matrix.project }}
path: .midscene-omarchy/omarchy-iso/test-runs/**/runs/**
if-no-files-found: warn
retention-days: 3
overwrite: true
- name: Upload Omarchy Midscene shard report
if: always() && !cancelled()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: omarchy-midscene-${{ matrix.project }}
path: tests/e2e/midscene_run/
if-no-files-found: error
retention-days: 7
overwrite: true
- name: Verify Omarchy shell visual evidence
if: success() && matrix.project == 'omarchy-shell'
run: node scripts/verify-omarchy-evidence.mjs tests/e2e/midscene_run
report-bundle:
name: Assemble Midscene report bundle
needs: omarchy-e2e
if: >-
always() && !cancelled() &&
(inputs.project == '' || inputs.project == 'all')
runs-on: ubuntu-latest
outputs:
report-artifact-id: ${{ steps.report.outputs.artifact-id }}
steps:
- name: Create bundle even when every shard failed early
run: |
mkdir -p "$RUNNER_TEMP/midscene-report-shards"
printf '%s\n' '{"bundle":"omarchy-4.0.3"}' > "$RUNNER_TEMP/midscene-report-shards/ci-bundle-status.json"
# Keep shard directories separate. Native report filenames can share a
# timestamp, while the Pages builder locates reports by project identity.
- name: Download every shard report
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: omarchy-midscene-*
path: ${{ runner.temp }}/midscene-report-shards
merge-multiple: false
- name: Upload combined report bundle
id: report
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: omarchy-midscene-e2e-report
path: ${{ runner.temp }}/midscene-report-shards/
if-no-files-found: error
retention-days: 7
overwrite: true
pages-report:
name: GitHub Pages report
needs: [omarchy-e2e, report-bundle]
if: >-
always() &&
!cancelled() &&
needs.report-bundle.outputs.report-artifact-id != '' &&
(github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name == github.repository)
permissions:
actions: read
contents: read
pages: write
id-token: write
uses: ./.github/workflows/deploy-midscene-report.yml
with:
artifact-name: omarchy-midscene-e2e-report
report-label: Omarchy 4.0.3
summary-title: Omarchy
report-groups: >-
[{"role":"primary","label":"Doubao Say","projects":["omarchy-shard-1","omarchy-shard-2","omarchy-shard-3","omarchy-shard-4"]},{"role":"auxiliary","label":"Omarchy visual checks","projects":["omarchy-shell"]}]
run-result: ${{ needs.omarchy-e2e.result }}