Files
TRIPandHKLHaoBin 6f9af89583 release: OpenLess 2.0.0-Beta.4+build.20260930 (#1126)
Integrate ASR/Omni fixes, API Route, Android IME and confirmation-based vocabulary learning. Complete settings transitions and macOS single-item credential storage. Synchronize all application versions to 2.0.0-Beta.4+build.20260930.

Integrated PRs: #1116, #1120, #1121, #1123, #1124, #1067 and #1128. Linux #1117 remains independent and is excluded from automatic release.

Validated: full cross-platform CI, 18 UI motion cases, 112 frontend test files, 1245 Core tests (1 ignored) and 572 macOS native tests.

Co-authored-by: HKLHaoBin <we3q@qq.com>
2026-09-30 20:32:53 +08:00

169 lines
7.1 KiB
YAML

name: Linux egui build and backend checks
# CI and independent manual Linux builds share this deb/rpm verification path.
# No standalone push trigger: a Linux PR must show one combined Linux check.
on:
workflow_call:
inputs:
# 'none' skips a change set that is only prose (see
# scripts/ci-changed-areas.sh): the callers that must always build the
# packages, including accepted tag builds, leave the default in place.
scope:
required: false
type: string
default: full
permissions:
contents: read
concurrency:
group: linux-egui-build-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build-linux-egui:
# PipeWire/libspa in this host needs 24.04. Packages target glibc >= 2.39.
runs-on: ubuntu-24.04
# A cold dependency tree costs ~18 minutes; anything past this is a hang.
timeout-minutes: 90
env:
RELEASE_TAG: ${{ github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/v') && endsWith(github.ref, '-tauri') && github.ref_name || '' }}
# Debug info dominates both compile time and cache size for this host, and
# the gate below never reads it. The Linux job keeps its own cache so a
# red run still starts warm.
CARGO_PROFILE_DEV_DEBUG: 0
CARGO_PROFILE_TEST_DEBUG: 0
steps:
- uses: actions/checkout@v6
with:
submodules: false
- name: Install native build and packaging dependencies
if: inputs.scope != 'none'
run: |
sudo add-apt-repository -y universe || true
sudo apt-get update
sudo apt-get install -y \
appstream build-essential cmake cpio desktop-file-utils \
fcitx5-modules-dev file libasound2-dev libdbus-1-dev \
libfcitx5config-dev libfcitx5core-dev libfcitx5utils-dev \
liblzma-dev libpipewire-0.3-dev libpulse-dev libssl-dev \
libwayland-dev libx11-dev libxkbcommon-dev pkg-config ripgrep rpm
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
if: inputs.scope != 'none'
- uses: actions/setup-node@v4
with:
node-version: '22'
if: inputs.scope != 'none'
- name: Resolve package version and validate release tag
id: version
working-directory: openless-all/app
env:
VERSION_TAG: ${{ env.RELEASE_TAG }}
run: |
set -euo pipefail
VERSION=$(node -p "require('./package.json').version")
if [ -n "$VERSION_TAG" ]; then
TAG_VERSION=${VERSION_TAG#v}
TAG_VERSION=${TAG_VERSION%-tauri}
if [ "${VERSION%%+*}" != "$TAG_VERSION" ]; then
echo "::error::tag $VERSION_TAG does not match package.json version $VERSION"
exit 1
fi
fi
# Linux packages use the same explicitly incremented -N revision as
# earlier Beta.2-78/-79 builds. Keep it separate from the Tauri tag.
REVISION=$(< linux-egui/package-revision)
[[ "$REVISION" =~ ^[1-9][0-9]*$ ]]
echo "version=${VERSION%%+*}-$REVISION" >> "$GITHUB_OUTPUT"
- uses: swatinem/rust-cache@v2
if: inputs.scope != 'none'
with:
workspaces: 'openless-all/app -> target'
# Saving after a failed test step keeps the next push incremental
# instead of repeating a cold build of the whole dependency tree.
cache-on-failure: true
- name: Build and test fcitx5 plugin
if: inputs.scope != 'none'
working-directory: openless-all/scripts/linux-fcitx5-plugin
run: |
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
cmake --build build --parallel
ctest --test-dir build --output-on-failure
test -s build/libopenless.so
test -s build/openless.conf
- name: Test Core, Linux host, and platform boundaries
if: inputs.scope != 'none'
working-directory: openless-all/app
run: |
cargo test --locked -p openless-core
cargo clippy --locked -p openless-core --all-targets -- -D warnings
cargo test --locked -p openless-linux-egui --all-targets
cargo clippy --locked -p openless-linux-egui --all-targets -- -D warnings
cargo check --locked -p openless-linux-egui --all-targets
node scripts/linux-egui-tauri-free-contract.test.mjs
node scripts/linux-egui-release-contract.test.mjs
node scripts/ci-changed-areas.test.mjs
node scripts/tauri-linux-free-contract.test.mjs
pwsh -NoProfile -File ./scripts/check-core-deps.ps1
pwsh -NoProfile -File ./scripts/check-core-deps.ps1 openless-linux-egui
pwsh -NoProfile -File ./scripts/check-core-secret-surface.ps1
pwsh -NoProfile -File ./scripts/check-core-test-isolation.ps1
pwsh -NoProfile -File ./scripts/check-core-runtime-seam.ps1
pwsh -NoProfile -File ./scripts/check-linux-public-surface.ps1
- name: Test remote input TLS identity and Unix key permissions
if: inputs.scope != 'none'
working-directory: openless-all/app
run: cargo test --locked --manifest-path src-tauri/backend-tests/Cargo.toml --test remote_tls
- name: Validate Linux desktop metadata
if: inputs.scope != 'none'
run: |
desktop-file-validate openless-all/app/linux-egui/packaging/openless.desktop
appstreamcli validate --no-net openless-all/app/linux-egui/packaging/top.openless.OpenLess.metainfo.xml
- name: Build Linux egui host
if: inputs.scope != 'none'
working-directory: openless-all/app
run: cargo build --locked --release -p openless-linux-egui
- name: Package deb and rpm without Tauri
if: inputs.scope != 'none'
working-directory: openless-all/app
env:
OPENLESS_LINUX_VERSION: ${{ steps.version.outputs.version }}
OPENLESS_LINUX_ARCH: x86_64
run: |
# CI runners are disposable. Ignore old outputs restored by a cache.
rm -f target/linux-egui-packages/*.deb target/linux-egui-packages/*.rpm \
target/linux-egui-packages/SHA256SUMS
bash scripts/package-linux-egui.sh
- name: Generate checksums and verify distributable packages
if: inputs.scope != 'none'
working-directory: openless-all/app
run: |
set -euo pipefail
OUTPUT=target/linux-egui-packages
( cd "$OUTPUT" && sha256sum ./*.deb ./*.rpm > SHA256SUMS )
bash scripts/verify-linux-egui-packages.sh
- name: Upload verified Linux packages as workflow artifacts
# Push builds keep the release path warm but do not publish artifacts;
# the tag release and pull request runs are the consumers.
if: inputs.scope != 'none' && (github.event_name != 'push' || env.RELEASE_TAG != '')
uses: actions/upload-artifact@v7
with:
name: openless-linux-egui-x86_64
path: openless-all/app/target/linux-egui-packages/*
if-no-files-found: error