# Build the session on the three distributions HyprCosmic targets. # # Much lighter than the compositor's matrix: this crate is pure Rust with no # system libraries to find, so what is actually being tested per distribution is # the toolchain and `just`, not a list of -dev packages. # # Rust comes from rustup for the same reason it does in cosmic-comp: Cargo.toml # asks for edition 2024 and rust-version 1.93, and Debian bookworm ships 1.63. # # Named hyprcosmic.yml rather than ci.yml to match the compositor fork, where # that name is already upstream's and taken. Upstream cosmic-session ships no # workflows at all, so nothing here is being displaced. name: HyprCosmic on: push: branches: [master] pull_request: workflow_dispatch: 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: fail-fast: false matrix: include: - distro: fedora image: fedora:latest - distro: debian image: debian:bookworm - distro: arch image: archlinux:latest # Every `run` step works from the crate, which the checkout below deliberately # places one level down inside the parent repository rather than at the root. defaults: run: working-directory: hyprcosmic/cosmic-session steps: # Before checkout: actions/checkout needs git and these images are bare. # # The three of them override working-directory back to the workspace root, # because the default above names a directory the checkout has not created # yet and a run step whose working-directory does not exist fails before it # runs anything. - name: Install build dependencies (fedora) if: matrix.distro == 'fedora' working-directory: . run: dnf -y install --setopt=install_weak_deps=False git curl gcc just # bookworm has no `just` package -- it arrived in trixie -- so it is built # from crates.io there. That is why this step installs it separately rather # than listing it above: the fallback is Debian-specific and saying so here # is better than a comment explaining an absence somewhere else. - name: Install build dependencies (debian) if: matrix.distro == 'debian' working-directory: . run: | apt-get update DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ git curl ca-certificates build-essential - name: Install build dependencies (arch) if: matrix.distro == 'arch' working-directory: . run: pacman -Syu --noconfirm --needed git curl base-devel just # Two checkouts, laid out the way the working tree is laid out. # # Two tests here read `../config/autostart` through include_str!, so the # crate does not compile its own test profile unless the parent repository # is its parent directory. That coupling is deliberate -- the point of # those tests is that the template this session actually ships still # parses to the commands it documents, and a copy vendored in here to make # the build self-contained would be a copy that silently goes stale. # # The parent lands first and this repository is checked out over the top of # where its submodule would be, so the crate under test is the commit that # triggered the run and not whatever the parent has pinned. - name: Check out the parent repository uses: actions/checkout@v4 with: repository: ${{ github.repository_owner }}/hyprcosmic path: hyprcosmic - name: Check out this repository inside it uses: actions/checkout@v4 with: path: hyprcosmic/cosmic-session - name: Install Rust run: | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ | sh -s -- -y --default-toolchain stable --profile minimal echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" # Both paths are workspace-relative, and `defaults.run.working-directory` # does not apply to actions -- only to `run` steps. - uses: Swatinem/rust-cache@v2 with: workspaces: hyprcosmic/cosmic-session key: ${{ matrix.distro }} - name: Install just (debian only) if: matrix.distro == 'debian' run: cargo install just --locked - name: Show toolchain run: | cargo --version just --version - name: Build run: just build-release --locked - name: Test run: cargo test --release --locked - name: Install into a staging root run: just rootdir="$PWD/stage" install # Eight files: upstream's six, at upstream's paths, plus this fork's two. # HyprCosmic replaces COSMIC rather than installing beside it, so nothing # else on the machine provides the systemd target, the mimeapps list or # the dconf profile -- a session that omits them starts, and then has no # user target for the portals to attach to, which surfaces much later and # much less clearly than a missing file would. # # Both session entries are asserted. Dropping cosmic.desktop would leave a # machine whose only way in is the HyDE shell, and the last two lines are # what stop the private libexec layout from creeping back. - name: Assert it installs as the session, at upstream's paths run: | set -eux test -x stage/usr/bin/cosmic-session test -x stage/usr/bin/start-hyprcosmic test -x stage/usr/bin/start-cosmic test -f stage/usr/share/wayland-sessions/hyprcosmic.desktop test -f stage/usr/share/wayland-sessions/cosmic.desktop test -f stage/usr/lib/systemd/user/cosmic-session.target test -f stage/usr/share/applications/cosmic-mimeapps.list test -f stage/usr/share/dconf/profile/cosmic test ! -e stage/usr/libexec/hyprcosmic/cosmic-session find stage -type f -printf '%M %10s %P\n' # Upstream rewrites DCONF_PROFILE to an absolute path in its own start # script; this fork's searches for the profile at runtime instead. Both # behaviours are deliberate, and the pair is easy to get backwards in a # recipe that now installs both scripts. - name: Assert the dconf rewrite hit start-cosmic and only start-cosmic run: | set -eux grep -q 'DCONF_PROFILE=/usr/share/dconf/profile/cosmic' stage/usr/bin/start-cosmic grep -q 'DCONF_PROFILE=cosmic$' stage/usr/bin/start-hyprcosmic - uses: actions/upload-artifact@v4 with: name: cosmic-session-${{ matrix.distro }} path: hyprcosmic/cosmic-session/stage/ retention-days: 14 # Off the matrix on purpose. Shell scripts do not vary by distribution, and # running this on the bare runner avoids naming the shellcheck package three # times in three package managers to check the same two files three times. scripts: name: session scripts runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # These only ever run at login, where a syntax error is a black screen # with nowhere to print the reason. Parsing them is the cheapest possible # guard against that, and it is worth doing to start-cosmic as well even # though this fork no longer installs it. - name: Syntax-check the session scripts run: | set -eux bash -n data/start-hyprcosmic bash -n data/start-cosmic # start-hyprcosmic only. start-cosmic is upstream's, it is not installed # by this fork, and it has pre-existing findings that are not this fork's # to rewrite -- linting it would mean either carrying a diff against # upstream for style or starting with a failing job. - name: Shellcheck run: | set -eux command -v shellcheck >/dev/null || { sudo apt-get update sudo apt-get install -y --no-install-recommends shellcheck } shellcheck data/start-hyprcosmic