Files

12 KiB

title, description, sections
title description sections
Contribute Help make Federated CoreDesktop better: suggest software, send a pull request, and learn how changes reach existing machines through migrations.
type compact eyebrow title subhead visual ctas
hero true MIT licensed · Pull requests welcome Help make CoreDesktop better. Want to help? Awesome! We welcome any and all help. Suggest missing titles or services, or contribute a PR and we're off to a better CoreDesktop. false
label url style
Open the repository https://gitea.federated.computer/Federated_Computer/coredesktop primary
label url style
Report an issue https://gitea.federated.computer/Federated_Computer/coredesktop/issues ghost
type kicker headline items
steps Ways to help Pick one.
title body
Suggest software Missing a title or service you use every day? [Open an issue](https://gitea.federated.computer/Federated_Computer/coredesktop/issues) and say why. Found a bug? Report it there too.
title body
Send a pull request Packages live in `packages.conf`, Flatpaks in `install-flatpaks.sh`, update steps in `updates.d/` and setup in `configure.d/`. Every push is checked with [shellcheck](https://www.shellcheck.net); run `make check` first, which runs shellcheck and the bats tests. The [developer tools](#coredesktop-dev) make this easier.
title body
Build a sibling Have something that's only for you or your team? Make it a [sibling project](/siblings/) instead.
type id kicker headline body
text coredesktop-dev Developer tools Install coredesktop-dev. [coredesktop-dev](https://gitea.federated.computer/Federated_Computer/Coredesktop-Dev) has the tools for working on CoreDesktop itself. Only contributors need them, so it's a [sibling project](/siblings/) rather than part of CoreDesktop. Install it with: ``` sibling add https://gitea.federated.computer/Federated_Computer/Coredesktop-Dev.git ``` It asks where your working copy of CoreDesktop is (default `~/Projects/coredesktop`) and offers to clone it there. It installs shellcheck, bats, tea (Gitea's CLI), QEMU and xorriso, and `update` keeps it current from then on. To change the working copy, run `sibling add` again. **Why it exists: your machine has two copies of CoreDesktop.** The *deployed* copy in `~/.local/share/coredesktop` is what the machine runs and what `update` pulls (fast-forward only). The *working* copy, e.g. `~/Projects/coredesktop`, is where you make changes. Never edit the deployed copy: one changed tracked file stops `update` from pulling. coredesktop-dev lets you test the working copy without touching the deployed one.
type id kicker headline lede headers rows
table coredesktop-dev-commands coredesktop-dev The commands. Each takes `--help`. In a Flatpak, such as an editor's built-in terminal, coredesktop-dev runs itself on the host with `flatpak-spawn --host`.
Command
What it does
`coredesktop-dev doctor`
Checks the tools, the working copy, and that the deployed copy can still update
`coredesktop-dev check [--fast]`
Runs `make lint` and `make test` in the working copy, plus shellcheck on scripts you haven't committed yet (`make lint` only sees tracked files). `--fast` runs shellcheck only
`coredesktop-dev try [--keep] [cmd...]`
Runs the working copy's code as if it were installed, in a throwaway home with its own D-Bus session and no display, e.g. `coredesktop-dev try configure --list`. sudo, yay, pacman and systemctl still change this machine
`coredesktop-dev deployed [status|restore]`
Shows the deployed copy's state, or undoes local changes to it (after asking)
`coredesktop-dev hooks [status|install|remove]`
A pre-push hook in the working copy that runs `check` first. `git push --no-verify` skips it
`coredesktop-dev smoketest ...`
Tests install and update on throwaway virtual machines ([below](#smoketests))
type id kicker headline lede headers rows
table testing Testing Four kinds of tests. CI only runs shellcheck (`make lint` in `.gitea/workflows/shellcheck.yml`), so run the bats tests and smoketests yourself before sending a PR.
Test
What it checks
How to run it
Documented in
Lint
Every tracked bash script, with [shellcheck](https://www.shellcheck.net) at warning level. Settings in `.shellcheckrc`
`make lint`, or `coredesktop-dev check --fast` to include untracked scripts
[README.md](https://gitea.federated.computer/Federated_Computer/coredesktop/src/branch/main/README.md#contributing)
Unit tests
The logic of the scripts, with [bats](https://github.com/bats-core/bats-core) tests in `tests/*.bats`. Each test gets its own `HOME` and a fake `bin` folder at the front of `PATH`, where the `stub` helper fakes commands like pacman, yay and sudo
`make check` (lint, then `make test`), or `coredesktop-dev check`
[tests/test_helper.bash](https://gitea.federated.computer/Federated_Computer/coredesktop/src/branch/main/tests/test_helper.bash)
Smoketests
`install.sh` and `update` end to end, on a real Arch + GNOME virtual machine: what fakes can't check
`coredesktop-dev smoketest run`
[smoketest/README.md](https://gitea.federated.computer/Federated_Computer/coredesktop/src/branch/main/smoketest/README.md)
Sibling projects
A sibling's install and update, in a throwaway home with `sibling add` pointed at a local clone
By hand, as the guide shows
[skills/sibling-project-format.md](https://gitea.federated.computer/Federated_Computer/coredesktop/src/branch/main/skills/sibling-project-format.md#testing)
type text
callout **Tests must not start session services.** A throwaway `HOME` doesn't isolate you from the live GNOME session: `/run/user/<uid>` is shared. A test that replaced the keyring daemon once left the real keyring locked and hung Bitwarden. Anything that starts session daemons needs its own `XDG_RUNTIME_DIR`, no display and `dbus-run-session`, which is what `coredesktop-dev try` sets up. And remember that sudo, yay, pacman and systemctl ignore `HOME`: test those with stubs, or on a VM. More in [skills/coredesktop-dev-sibling.md](https://gitea.federated.computer/Federated_Computer/coredesktop/src/branch/main/skills/coredesktop-dev-sibling.md).
type id kicker headline body
text smoketests Smoketests Install and update, on real virtual machines. The bats tests check the logic with fake commands. Smoketests check what fakes can't: pacman, yay, Flatpak, systemd, ufw, Snapper on btrfs, GNOME settings and a reboot. The scenarios live in CoreDesktop's `smoketest/scenarios/` (shared helpers in `smoketest/lib/scenario.sh`); coredesktop-dev provides the QEMU virtual machines that run them. They test your working copy's `HEAD`, so commit first. ``` coredesktop-dev smoketest list # the scenarios and their tier coredesktop-dev smoketest run # the quick ones (tier pr) coredesktop-dev smoketest run --tier all # everything, including a fresh install; hours coredesktop-dev smoketest run 40 43 # just these coredesktop-dev smoketest run --keep 40 # on failure, leave the VM up to look around coredesktop-dev smoketest shell installed # SSH into a throwaway VM ``` Scenarios cover a fresh install, `refresh`, a no-op update, upgrading from an older release, `update` replacing itself, new and failing migrations, a failing hook, an unreachable upstream, local edits, low disk space, a month-old machine, skipped packages and siblings. **How it works.** Each scenario runs on a throwaway copy of one of two images. *base* is Arch's cloud image with GNOME added as archinstall's desktop profile does it, and a user `tester` (password `tester`) who logs in automatically. *installed* is base after `install.sh` at the commit your branch started from; scenarios on it first `update` to the commit under test. Inside the VM, a bare repo at `/srv/smoketest/coredesktop.git` stands in for Gitea, so `install.sh` and `update` run unchanged. After a scenario, `fingerprint` describes the machine as text (packages, Flatpaks, services, firewall, files in `/etc`, `~/.bashrc`, GNOME settings). The baseline scenario installs an older commit, runs `update`, and checks the result matches a fresh install. If not, an `install.sh` change is probably missing its migration. The older commits are listed in `smoketest/baselines`. Their installers can no longer finish in a VM as they did then (a package that no longer builds, a dialog no one clicks), so the scenario installs each with small fixes on top, then sets the clone back to the commit itself. An install that fails is tried once more. **What you need.** KVM (virtualization turned on in the firmware), about 8 GB of RAM and 4 CPUs per VM (`SMOKETEST_MEMORY`, `SMOKETEST_CPUS`), and about 45 GB in `~/.cache/coredesktop-dev/smoketest`. The images are kept between runs (the installed one is the biggest, around 35 GB), along with the shared package cache and each run's logs. A scenario's own disk only holds its changes to the image, and is deleted when the scenario ends. To free space, `coredesktop-dev smoketest clean` deletes old runs' logs, and `clean --all` deletes everything, so the next run rebuilds the images. The first run builds both images before any scenario runs: *base* in a few minutes, *installed* in an hour or more. Later runs reuse them; rebuild *installed* now and then with `coredesktop-dev smoketest images installed`. Arch packages are cached and shared between VMs; Flatpaks aren't. To watch a VM's screen, set `SMOKETEST_VNC=1` and connect a VNC viewer to `127.0.0.1:5901`. **Following a run.** While a VM boots, or a command such as `install.sh` runs in it, the terminal says once a minute what it's still waiting for, or which command is still running and its latest line of output. The logs are in `~/.cache/coredesktop-dev/smoketest`: `build.log` and the VM's console, `serial.log`, in `build-base/` and `build-installed/` while an image builds, and each scenario's logs in `runs/<date>-<time>/<scenario>/`. Each command's log is written as it runs, so you can follow it with `tail -f`. Not covered: NVIDIA drivers, firmware updates, and anything that needs a real Core, a Tailscale login or a Claude login. Check those by hand.
type kicker headline body
text Migrations Getting a change to existing machines. Changes to `install.sh` only reach new installs. If existing machines need the change too, also add a migration: a script named after the current time, ``` migrations/$(date +%s).sh ``` that `update` runs once on each machine. It may also run on fresh installs, so make it safe to repeat.
type id kicker headline body
text license License MIT, the whole project. Copyright 2026 Federated Computer, Inc. Permission is granted, free of charge, to anyone who gets a copy of this software to use, copy, modify, merge, publish, distribute, sublicense and sell it, as long as the copyright and permission notice are included. The software is provided as is, without warranty of any kind. Read the full text in [LICENSE.md](https://gitea.federated.computer/Federated_Computer/coredesktop/src/branch/main/LICENSE.md).
type kicker headline body
text Thanks Standing on good shoulders. Most of the heavy lifting is done by [Arch Linux](https://archlinux.org), and to that distribution we send much gratitude. Arch lets us get on with building, instead of waiting for upstream changes and fixes. These scripts are based on the initial work of [Typecraft](https://www.youtube.com/@typecraft_dev).
type headline ctas
final-cta Ready when you are.
label url style
Install CoreDesktop /install/ primary
label url style
View the source https://gitea.federated.computer/Federated_Computer/coredesktop ghost