harmonize with coredesktop

This commit is contained in:
David Young
2026-10-28 14:35:07 -06:00
parent 866720c3c1
commit 9b9f1d5fdd
35 changed files with 1445 additions and 8 deletions
+149
View File
@@ -0,0 +1,149 @@
# Skill: Supporting the updates.d Update Architecture in a Sibling Project
## Overview
There are two ways for a sibling project to plug into MiniServer:
1. **The `sibling` command (preferred).** The user runs `sibling` and gives it
the project's git URL. The repo is cloned into
`~/.local/share/siblings/<name>` and its `install.sh` (if any) is run once.
On every `update`, `updates.d/71-siblings.sh` pulls each sibling and runs its
`update.sh` (if any). The sibling only needs those two optional scripts.
2. **A custom hook.** MiniServer's `update` script sources every `*.sh` file
found in `~/.local/share/MiniServer/updates.d/` in filename order. A sibling
project can install its own numbered shell script into that directory during
its own install step, for full control over how and when it updates.
## Using the `sibling` Command
See `sibling-project-format.md` for the full rules, templates and testing.
In short, give the repo these optional files at its top level:
| File | When it runs |
|--------------|---------------------------------------------------|
| `install.sh` | Once, from the repo folder, when the user runs `sibling add` (and again if they re-run it) |
| `update.sh` | On every `update`, from the repo folder, after the repo has been pulled |
Both run with `bash`, and a non-zero exit is reported as a failure.
`update.sh` should be idempotent. If you have no `update.sh`, `update` just pulls the repo.
Commands:
```bash
sibling # asks for the git URL
sibling add <url> # same, without the prompt
sibling list # installed siblings, their URL and current commit
sibling remove <name> # deletes ~/.local/share/siblings/<name>
```
The rest of this document covers the custom-hook approach.
## How It Works
When a user runs `update`:
1. The MiniServer repo at `~/.local/share/MiniServer` is pulled.
2. All `*.sh` files in `updates.d/` are **sourced**, each in its own subshell,
in lexicographic order.
3. Each script can see `$MINISERVER`, but nothing defined by earlier hooks —
source `utils.sh` yourself if you need its helpers. A `cd`, `set -e` or `exit`
in one hook can't affect the others.
4. A hook that exits non-zero is listed in the summary at the end of `update`.
Because the scripts are sourced from within the cloned repo directory, any file
placed there by a sibling project's installer will **survive `git pull`** — git
does not delete untracked files on pull.
## Naming Convention
Existing MiniServer hooks use a numeric prefix to control execution order:
| File | Purpose |
|-----------------------|---------------------------------------------|
| `10-pacman.sh` | Arch system update |
| `12-migrations.sh` | One-time migrations from `migrations/` |
| `20-aur.sh` | AUR packages |
| `30-pm2.sh` | pm2 |
| `40-cockpit.sh` | Cockpit |
| `70-claude.sh` | Claude Code setup |
| `71-siblings.sh` | Projects installed with `sibling` |
| `72-sandbox.sh` | Sandbox runtime and Hermes Agent |
| `80-firewall.sh` | Ports from every `firewall.conf` |
| `95-cleanup.sh` | pacman cache cleanup |
| `99-reboot-check.sh` | Reboot-needed notice |
Sibling projects should use an unused number from **73–79** so they run after
the core updates but before MiniServer's end-of-run hooks (80+).
## What to Add to a Sibling Project
### 1. Create the hook script
Add a file like `updates.d/73-myproject.sh` to the sibling repo:
```bash
#!/bin/bash
echo "Updating MyProject..."
git -C "$HOME/.local/share/myproject" pull
# Optional: use MiniServer helpers if needed
# source "$MINISERVER/utils.sh"
# install_packages "${MY_PACKAGES[@]}"
```
### 2. Install the hook during the sibling's install step
In the sibling's `install.sh`, copy the hook into MiniServer's `updates.d/`:
```bash
echo "Registering MyProject update hook..."
cp updates.d/73-myproject.sh ~/.local/share/MiniServer/updates.d/
```
This is a one-time step that wires the sibling into every future `update`
run on the machine.
### Optional: only update when installed
Instead of running code at the top level, a hook can define `run_update` and,
optionally, `is_installed`. `update` calls `run_update` only when `is_installed`
is missing or returns true, so the hook is skipped on machines where the project
isn't installed. Return non-zero from `run_update` to report a failure:
```bash
#!/bin/bash
is_installed() {
[ -d "$HOME/.local/share/myproject" ]
}
run_update() {
echo "Updating MyProject..."
git -C "$HOME/.local/share/myproject" pull --ff-only
}
```
## Available Helpers
Hooks don't inherit functions from earlier hooks, so source `utils.sh` for its
helpers. Do this before defining your own `is_installed`, because `utils.sh` has
a pacman-specific function with the same name:
```bash
source "$MINISERVER/utils.sh"
# Install pacman packages (skips already-installed ones)
install_packages "${MY_PACMAN_PACKAGES[@]}"
# Remove packages
remove_packages "${MY_REMOVE_PACKAGES[@]}"
```
## Checklist for Sibling Project Authors
- [ ] Create `updates.d/7X-<project>.sh` in the sibling repo
- [ ] Hook script echoes its name so progress is visible during `update`
- [ ] Install step copies the hook to `~/.local/share/MiniServer/updates.d/`
- [ ] Numeric prefix is an unused number in 73–79
- [ ] Script is idempotent — safe to run multiple times without side effects