Files
amethyst/.github/workflows/smoke-test-desktop.yml
Claude 8b72c6f740 ci: install a pinned JetBrains Runtime instead of setup-java's lookup
setup-java's `jetbrains` distribution lists JetBrains' releases to find
the newest 21, and that lookup fails intermittently on the runners,
leaving only JBR 11 builds ("No matching version found for SemVer
'21'"). It failed the Linux desktop jobs on x64 and arm64 alike.

The new .github/actions/setup-jbr downloads one pinned JBR 21 SDK
(21.0.11 b1163.116, the build CI resolved today), checks it against a
SHA-512 pinned in the repo, and installs it with setup-java's jdkfile
distribution. build.yml, smoke-test-desktop.yml and create-release.yml
use it on Linux; macOS and Windows stay on Temurin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HisVbewiVYcAvnCCkBXCZK
2026-10-22 17:38:44 +00:00

220 lines
9.0 KiB
YAML

name: Desktop Smoke Test
on:
workflow_dispatch:
pull_request:
paths:
- 'desktopApp/**'
- '.github/workflows/smoke-test-desktop.yml'
# The keyring self-test exercises these, and the libraries they pin.
- 'commons/src/jvmMain/kotlin/com/vitorpamplona/amethyst/commons/keystorage/**'
- 'scripts/keyring-self-test.sh'
- 'gradle/libs.versions.toml'
permissions:
contents: read
concurrency:
group: smoke-desktop-${{ github.ref }}
cancel-in-progress: true
jobs:
# -------------------------------------------------------------------------
# 1) Compose UI test — verifies the composable tree renders (login screen)
# under the dev classpath. Catches missing string resources, broken
# composables, and basic dependency-graph issues.
# -------------------------------------------------------------------------
compose-ui-test:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Set up JDK 21
uses: actions/setup-java@v6.0.1
with:
distribution: 'temurin'
java-version: 21
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6
with:
cache-read-only: true
- name: Install xvfb
run: sudo apt-get update && sudo apt-get install -y xvfb
- name: Run desktop tests (including UI smoke test)
run: xvfb-run --auto-servernum ./gradlew :desktopApp:test
# -------------------------------------------------------------------------
# 2) Release .deb build + launch — builds the ProGuard'd, jlink'd .deb
# package, installs it, and verifies the process stays alive for 10s.
# Catches ProGuard stripping (JNI, reflection), missing jlink modules
# (java.management, java.prefs), and native lib bundling issues.
#
# Runs on both x64 and arm64 hosted runners so release-time arm64 breakage
# (e.g. ProGuard rules missing an arch-specific reflection root) is caught
# at PR time instead of on the tag build.
# -------------------------------------------------------------------------
release-deb-launch:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm]
runs-on: ${{ matrix.os }}
timeout-minutes: 45
steps:
- name: Checkout code
uses: actions/checkout@v7
# As in create-release.yml: Linux packages bundle the JetBrains Runtime (native Wayland).
- name: Set up JDK 21 (JetBrains Runtime)
uses: ./.github/actions/setup-jbr
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6
with:
cache-read-only: true
- name: Install xvfb + packaging deps
# gnome-keyring + dbus: the keyring self-test below needs a Secret Service session.
# sway: the Wayland-only launch below.
run: sudo apt-get update && sudo apt-get install -y xvfb fakeroot gnome-keyring dbus sway
- name: Build release .deb
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0
with:
max_attempts: 2
timeout_minutes: 20
command: ./gradlew --no-daemon :desktopApp:packageReleaseDeb
- name: Relax build-host-pinned deps
run: |
set -euo pipefail
chmod +x scripts/relax-deb-libicu.sh
scripts/relax-deb-libicu.sh desktopApp/build/compose/binaries/main-release/deb/*.deb
# Mirrors the same step in create-release.yml so this job exercises the
# exact .deb release ships. libskiko-linux-arm64.so has libEGL.so.1 in
# DT_NEEDED and jpackage does not scan lib/app/ for Depends, so without
# this the arm64 app dies at startup with
# UnsatisfiedLinkError: libEGL.so.1: cannot open shared object file
# See scripts/add-deb-libegl-dep.sh for the full rationale.
- name: Add libegl1 dep to arm64 .deb
run: |
set -euo pipefail
chmod +x scripts/add-deb-libegl-dep.sh
scripts/add-deb-libegl-dep.sh desktopApp/build/compose/binaries/main-release/deb/*.deb
# Also mirrors create-release.yml, so the install below resolves the same Depends.
- name: Add GStreamer deps to .deb
run: |
set -euo pipefail
chmod +x scripts/add-deb-gstreamer-deps.sh
scripts/add-deb-gstreamer-deps.sh desktopApp/build/compose/binaries/main-release/deb/*.deb
# Also mirrors create-release.yml: the bundled JBR opens libxkbcommon with dlopen.
- name: Add Wayland deps to .deb
run: |
set -euo pipefail
chmod +x scripts/add-deb-wayland-deps.sh
scripts/add-deb-wayland-deps.sh desktopApp/build/compose/binaries/main-release/deb/*.deb
# Also mirrors create-release.yml. Without it, jpackage's postinst runs
# xdg-desktop-menu, which fails here as on any system without menu
# directories ("No writable system menu directory found").
- name: Fix desktop entry in .deb
run: |
set -euo pipefail
chmod +x scripts/fix-deb-desktop-entry.sh
scripts/fix-deb-desktop-entry.sh desktopApp/build/compose/binaries/main-release/deb/*.deb
- name: Install .deb
run: |
set -euo pipefail
# Installed via apt (not `dpkg -i`) so the .deb's declared Depends are
# actually resolved — that is what pulls in libegl1 on the arm64
# runner, which does not ship it preinstalled. A failed install,
# maintainer scripts included, fails the job.
sudo apt-get install -y ./desktopApp/build/compose/binaries/main-release/deb/*.deb
dpkg-query -W -f='${Status}\n' amethyst | grep -qx 'install ok installed'
test -f /usr/share/applications/amethyst-Amethyst.desktop
echo "Installed files:"
dpkg -L amethyst | sed -n '1,30p'
# Fail if the binary wasn't actually extracted
test -d /opt/amethyst || test -d /opt/Amethyst || {
echo "FAIL: /opt/amethyst not found after dpkg -i"
exit 1
}
- name: Smoke test — app launches and stays alive
run: |
set -euo pipefail
# Find the launcher binary
LAUNCHER=$(find /opt -name "Amethyst" -type f -executable 2>/dev/null | head -1)
if [[ -z "$LAUNCHER" ]]; then
# Fallback: search dpkg file list
LAUNCHER=$(dpkg -L amethyst | grep -E '/bin/[Aa]methyst$' | head -1)
fi
if [[ -z "$LAUNCHER" ]]; then
echo "FAIL: could not find Amethyst launcher binary"
dpkg -L amethyst
exit 1
fi
echo "Launcher: $LAUNCHER"
# Launch under xvfb with a timeout safety net
xvfb-run --auto-servernum timeout 30 "$LAUNCHER" &
APP_PID=$!
echo "PID: $APP_PID"
# Wait 10s — if the process is still alive, the app launched successfully
sleep 10
if kill -0 "$APP_PID" 2>/dev/null; then
echo "PASS: Application launched and stayed alive for 10s"
kill "$APP_PID" || true
wait "$APP_PID" 2>/dev/null || true
else
wait "$APP_PID" 2>/dev/null
EXIT_CODE=$?
echo "FAIL: Application exited with code $EXIT_CODE within 10s"
exit 1
fi
# Wayland-only session (sway, Xwayland off): the app must open a native Wayland window,
# which needs the bundled JetBrains Runtime and the app picking its Wayland toolkit.
- name: Smoke test - app opens a native Wayland window
run: |
set -euo pipefail
LAUNCHER=$(find /opt -name "Amethyst" -type f -executable 2>/dev/null | head -1)
if [[ -z "$LAUNCHER" ]]; then
LAUNCHER=$(dpkg -L amethyst | grep -E '/bin/[Aa]methyst$' | head -1)
fi
[[ -n "$LAUNCHER" ]] || { echo "FAIL: could not find Amethyst launcher binary"; exit 1; }
bash scripts/wayland-smoke-test.sh "$LAUNCHER"
# The release build must keep keys in the OS keyring: ProGuard once stripped the D-Bus
# transport and broke a signed jar, so every Linux release silently stopped using it.
# See commons/plans/2026-10-12-desktop-key-storage.md.
- name: Keyring self-test - the installed app keeps keys in GNOME Keyring
run: |
set -euo pipefail
LAUNCHER=$(find /opt -name "Amethyst" -type f -executable 2>/dev/null | head -1)
if [[ -z "$LAUNCHER" ]]; then
LAUNCHER=$(dpkg -L amethyst | grep -E '/bin/[Aa]methyst$' | head -1)
fi
[[ -n "$LAUNCHER" ]] || { echo "FAIL: could not find Amethyst launcher binary"; exit 1; }
bash scripts/keyring-self-test.sh "$LAUNCHER"
- name: Upload .deb artifact (for manual testing)
if: always()
uses: actions/upload-artifact@v7
with:
# Artifact names must be unique across a run — disambiguate per arch.
name: Release DEB (smoke-tested, ${{ matrix.os }})
path: desktopApp/build/compose/binaries/main-release/deb/*.deb