ci: build on Fedora, Debian and Arch, and assert the install stays beside COSMIC

Additive to upstream ci.yml, which is left exactly as it is. That workflow asks
whether the code is formatted, lints clean and still compiles under each feature
flag, on one Ubuntu runner. None of that stopped being worth asking when the
repository was forked, and replacing it would put a conflict in the path of
every rebase against pop-os/cosmic-comp for no gain.

What it does not ask is whether a distribution has a package called libseat-dev.
That question cannot be put to a single Ubuntu runner, so this builds in three
containers with three package managers and three sets of names -- a job failing
here means a real user of that distribution could not have built it either.

Rust comes from rustup because Debian bookworm ships rustc 1.63 and this crate
needs 1.93 and edition 2024; the packaged toolchain simply cannot build it on
one of the three targets. --default-toolchain none lets rust-toolchain.toml pick
the version, so CI cannot drift onto a compiler the project does not use.

The last step is the point of the whole thing. `make install` is staged into a
DESTDIR and then asserted over: the binary must be at libexec/hyprcosmic, and
/usr/bin/cosmic-comp must NOT exist. That is the rule that keeps installing this
fork from being a one-way door -- if it will not start, the stock session is
still on the greeter's menu to log in and fix it from. Until now that rule lived
only in a Makefile comment.
This commit is contained in:
2026-08-10 16:54:20 +07:00
parent ce3083fad2
commit 139a1de4e8
+152
View File
@@ -0,0 +1,152 @@
# Build the compositor on the three distributions HyprCosmic targets.
#
# WHY THIS IS A SECOND FILE
# -------------------------
# ci.yml beside it is upstream's, and it stays untouched. It asks a different
# question -- rustfmt, clippy, and whether the feature flags still compile -- on
# a single Ubuntu runner, and none of that stops being worth asking because the
# repository was forked. Replacing it would also mean carrying a conflict into
# every rebase against pop-os/cosmic-comp, for no gain. This file is additive,
# which is the same rule the rest of the fork follows.
#
# WHY CONTAINERS RATHER THAN ONE RUNNER
# -------------------------------------
# The interesting failure is never "does Rust compile this" -- it is "does this
# distribution have a package called libseat-dev". That question cannot be asked
# from a single Ubuntu runner, so each distribution builds in its own image with
# its own package manager and its own names. A job failing here means a real
# user of that distribution could not have built it either.
#
# WHY RUSTUP AND NOT THE DISTRIBUTION'S RUST
# ------------------------------------------
# Cargo.toml asks for edition 2024 and rust-version 1.93, and rust-toolchain.toml
# pins channel 1.93 with rust-src. Debian bookworm ships rustc 1.63, so on one of
# the three targets the packaged toolchain cannot build this at all. rustup is
# what makes the three jobs comparable -- and because it reads
# rust-toolchain.toml, all three get the pinned compiler rather than whatever
# each distribution happened to freeze.
name: HyprCosmic
on:
push:
branches: [master]
pull_request:
workflow_dispatch:
# A full matrix here is tens of minutes per distribution. Superseding a run that
# is already obsolete costs nothing and keeps a queue from forming behind it.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
build:
name: ${{ matrix.distro }}
runs-on: ubuntu-latest
container: ${{ matrix.image }}
strategy:
# One distribution failing on a package name is worth seeing on its own.
# Cancelling its siblings would hide whether the break is universal or
# local to that distribution's naming, which is the whole point of the
# matrix.
fail-fast: false
matrix:
include:
- distro: fedora
image: fedora:latest
- distro: debian
image: debian:bookworm
- distro: arch
image: archlinux:latest
steps:
# Before checkout, deliberately: actions/checkout needs git in the image,
# and these containers are bare.
#
# The library list is upstream's own, from debian/control, translated per
# distribution rather than trimmed. Four of them -- wayland, EGL,
# fontconfig and xcb -- proved unnecessary to build on a Fedora workstation
# with none of them installed, but that is a fact about one machine's
# feature flags, not a licence to drop what upstream says it needs.
- name: Install build dependencies (fedora)
if: matrix.distro == 'fedora'
run: |
dnf -y install --setopt=install_weak_deps=False \
git curl gcc gcc-c++ cmake pkgconf-pkg-config \
wayland-devel libxkbcommon-devel libinput-devel libseat-devel \
systemd-devel mesa-libgbm-devel mesa-libEGL-devel pixman-devel \
libdisplay-info-devel fontconfig-devel libxcb-devel
- name: Install build dependencies (debian)
if: matrix.distro == 'debian'
run: |
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
git curl ca-certificates build-essential cmake pkg-config \
libwayland-dev libxkbcommon-dev libinput-dev libseat-dev \
libsystemd-dev libudev-dev libgbm-dev libegl1-mesa-dev \
libpixman-1-dev libdisplay-info-dev libfontconfig-dev libxcb1-dev
# Arch keeps headers in the main packages rather than split -devel ones,
# so this list is shorter by construction, not by omission.
- name: Install build dependencies (arch)
if: matrix.distro == 'arch'
run: |
pacman -Syu --noconfirm --needed \
git curl base-devel cmake pkgconf \
wayland libxkbcommon libinput seatd systemd-libs mesa pixman \
libdisplay-info fontconfig libxcb
- uses: actions/checkout@v4
# --default-toolchain none, then let rust-toolchain.toml choose. Naming a
# version here would create a second place to update and a silent way for
# CI to test a compiler the project does not use.
- name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --default-toolchain none --profile minimal
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Show toolchain
run: |
rustup show
cargo --version
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.distro }}
- name: Build
run: cargo build --release --locked
- name: Test
run: cargo test --release --locked
# Staged into DESTDIR so the assertions below can inspect the result
# without needing root or a live system.
- name: Install into a staging root
run: make install DESTDIR="$PWD/stage" prefix=/usr
# These two assertions are Patch D as an executable statement. HyprCosmic
# installs beside COSMIC rather than over it, which is what keeps the stock
# session available to log into when this compositor will not start. If a
# future edit sends the binary back to $(bindir)/cosmic-comp, that stops
# being true silently -- unless something fails here.
- name: Assert it installs beside COSMIC, not over it
run: |
set -eux
test -x stage/usr/libexec/hyprcosmic/cosmic-comp
test ! -e stage/usr/bin/cosmic-comp
test ! -e stage/usr/share/cosmic/com.system76.CosmicSettings.Shortcuts/v1/defaults
find stage -type f -printf '%M %10s %P\n'
- uses: actions/upload-artifact@v4
with:
name: cosmic-comp-${{ matrix.distro }}
path: stage/
retention-days: 14