test: follow the autostart template off its author's home directory, and let CI compile

The template it parses stopped naming /home/dingo, so the two assertions that
named it had to move with it: the bar is now an `sh -c` invocation rather than a
bare waybar, and the wallpaper path is $HOME. The wallpaper assertion keeps the
surrounding double quotes in the expected string deliberately -- dropping them
is what would split the path at a space in someone's home directory, which is
the failure the test exists to catch.

Adds a ratchet: no line in the shipped autostart may contain "/home/". Both
lines carried an author's home directory right up until the repository was about
to be published, which is a bad moment to find out.

CI is fixed at the same time, because it could never have run these two tests.
They read ../config/autostart through include_str!, so the crate does not
compile its own test profile unless the parent repository is its parent
directory -- and a workflow checkout puts this repository at the workspace root,
alone. Confirmed by building a standalone export of HEAD:

    error: couldn't read `.../standalone/../config/autostart`: No such file
    error: could not compile `cosmic-session` (bin "cosmic-session" test)

So the job now checks the parent out first and this repository over the top of
where its submodule sits, which is the layout the working tree already has. The
coupling is worth keeping: 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 goes
stale without anyone noticing.

The three dependency-install steps override working-directory back to the
workspace root, since they run before the checkout that creates the directory
the job otherwise defaults to, and a run step whose working-directory does not
exist fails before it runs anything.
This commit is contained in:
2026-08-10 17:13:34 +07:00
parent 03cd10c0d9
commit 8ff1e72d3e
2 changed files with 69 additions and 4 deletions
+40 -2
View File
@@ -42,10 +42,22 @@ jobs:
- 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
@@ -54,6 +66,7 @@ jobs:
# 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 \
@@ -61,9 +74,31 @@ jobs:
- name: Install build dependencies (arch)
if: matrix.distro == 'arch'
working-directory: .
run: pacman -Syu --noconfirm --needed git curl base-devel just
- uses: actions/checkout@v4
# 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: |
@@ -71,8 +106,11 @@ jobs:
| 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)
@@ -114,7 +152,7 @@ jobs:
- uses: actions/upload-artifact@v4
with:
name: cosmic-session-${{ matrix.distro }}
path: stage/
path: hyprcosmic/cosmic-session/stage/
retention-days: 14
# Off the matrix on purpose. Shell scripts do not vary by distribution, and
+29 -2
View File
@@ -293,7 +293,9 @@ mod tests {
assert_eq!(got.len(), 5, "{got:?}");
// First, so its startup compile lands before the compositor settles.
assert_eq!(got[0], vec!["cosmic-conf", "watch"]);
assert_eq!(got[1][0], "waybar");
// The bar is a shell invocation, because its stylesheet lives under a
// home directory that this file cannot expand on its own.
assert_eq!(got[1][0], "sh");
assert_eq!(got[2], vec!["awww-daemon"]);
// Last, so the fallback terminal is the topmost window.
assert_eq!(got[4], vec!["cosmic-term"]);
@@ -321,8 +323,13 @@ mod tests {
assert_eq!(argv.len(), 3, "{argv:?}");
// The symlink, not one of the copies beside it. Naming a copy would
// strand this line on a path the next theme import deletes.
//
// `$HOME` rather than a real home directory: sh expands it, and the
// shipped template has to work for whoever installed it, not only for
// whoever wrote it. The double quotes are asserted with it, because
// dropping them is what would split the path at a space in $HOME.
assert!(
argv[2].contains(r#""/home/dingo/.local/share/wallpapers/hyprcosmic/current""#),
argv[2].contains(r#""$HOME/.local/share/wallpapers/hyprcosmic/current""#),
"{}",
argv[2]
);
@@ -330,4 +337,24 @@ mod tests {
// must not be set until it answers.
assert!(argv[2].starts_with("until awww query"), "{}", argv[2]);
}
/// The template is installed verbatim into every user's config directory,
/// so a literal `/home/someone` in it is a file that works for exactly one
/// person -- and it fails quietly for everyone else, because a waybar with
/// an unreadable stylesheet still starts and a wallpaper that was never set
/// looks the same as one that failed to load.
///
/// Both lines carried an author's home directory until the repository was
/// about to be published. This is here so that neither can carry one again.
#[test]
fn the_shipped_autostart_names_nobodys_home_directory() {
let text = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/../config/autostart"));
for (n, line) in text.lines().enumerate() {
assert!(
!line.contains("/home/"),
"config/autostart:{}: absolute home directory: {line}",
n + 1
);
}
}
}