refactor: separate ecosystem release from NixOS config in taffybar skill

Split the skill into two clear concerns: the taffybar org package
release workflow (dependency graph, Hackage publishing, version bounds)
and the personal NixOS flake chain integration. The NixOS section
explains the three-layer flake.lock cascade and why bottom-up updates
matter, without being prescriptive about always doing all layers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-10 20:15:17 -08:00
committed by Kat Huang
parent 4081f9bcca
commit a2dfc31787

View File

@@ -10,8 +10,7 @@ Release and propagate changes across the taffybar Haskell package ecosystem.
## Package Dependency Graph
```
imalison-taffybar (user config — ~/.config/taffybar/)
└── taffybar (main library — ~/.config/taffybar/taffybar/)
taffybar
├── gtk-sni-tray
│ ├── dbus-menu
│ ├── gtk-strut
@@ -24,8 +23,7 @@ imalison-taffybar (user config — ~/.config/taffybar/)
**Leaf packages** (no ecosystem deps): `gtk-strut`, `status-notifier-item`, `dbus-hslogger`, `dbus-menu`
**Mid-level**: `gtk-sni-tray` (depends on dbus-menu, gtk-strut, status-notifier-item)
**Top-level lib**: `taffybar` (depends on all above)
**User config**: `imalison-taffybar` (depends on taffybar + gtk-sni-tray + gtk-strut)
**Top-level**: `taffybar` (depends on all above)
## Repositories & Local Checkouts
@@ -37,108 +35,83 @@ imalison-taffybar (user config — ~/.config/taffybar/)
| status-notifier-item | taffybar/status-notifier-item | `~/Projects/status-notifier-item/` |
| dbus-menu | taffybar/dbus-menu | `~/Projects/dbus-menu/` |
| dbus-hslogger | IvanMalison/dbus-hslogger | `~/Projects/dbus-hslogger/` |
| imalison-taffybar | (dotfiles repo) | `~/.config/taffybar/` |
## Release Order (Bottom-Up)
## Releasing a Package
Always release leaf packages first, then dependents. Changes propagate **upward**.
Always release leaf packages before their dependents. Changes propagate **upward** through the graph.
### 1. Release the Changed Leaf Package
### 1. Release the Changed Package
Use the `hackage-release` skill for the Hackage publish workflow. In the local checkout (`~/Projects/<pkg>/`):
Use the `hackage-release` skill for the full Hackage publish workflow. In the local checkout:
1. Bump version in `.cabal` file (PVP: A.B.C.D)
2. Update ChangeLog.md
3. `cabal build && cabal check`
4. `cabal sdist`
5. Commit, tag `vX.Y.Z.W`, push with tags
6. Publish to Hackage (see hackage-release skill for credentials)
6. Publish to Hackage
7. Publish docs
### 2. Update Dependents' Version Bounds
For each package that depends on the one you just released, update the dependency bound in its `.cabal` file. For example, if you bumped `gtk-strut` to 0.1.5.0:
For each package higher in the graph that depends on what you just released, update the dependency bound in its `.cabal` file. For example, if you bumped `gtk-strut` to 0.1.5.0:
- In `gtk-sni-tray.cabal`: update `gtk-strut >= 0.1.5 && < 0.2`
- In `taffybar.cabal`: update `gtk-strut >= 0.1.5 && < 0.2`
Then release those packages if needed (repeat from step 1).
Then release those packages too if needed (repeat from step 1).
### 3. Update Nix Flake Inputs
### 3. Update Flake Inputs
After pushing changes to GitHub, update flake.lock files that reference the changed packages:
**taffybar's flake** (`~/.config/taffybar/taffybar/`):
```bash
cd ~/.config/taffybar/taffybar
nix flake update gtk-strut # or whichever input changed
```
**imalison-taffybar's flake** (`~/.config/taffybar/`):
```bash
cd ~/.config/taffybar
nix flake update gtk-strut # update the direct input
nix flake update taffybar # if taffybar itself changed
```
### 4. Rebuild and Test
Each package's `flake.nix` references its ecosystem dependencies as inputs (typically `flake = false` pointing at GitHub). After pushing changes, update the flake.lock in any repo that directly references the changed package:
```bash
cd ~/.config/taffybar
nix develop --command cabal build
cd ~/Projects/gtk-sni-tray # if it depends on what changed
nix flake update gtk-strut
```
Or for a full NixOS rebuild:
```bash
cd ~/dotfiles/nixos && just switch
cd ~/.config/taffybar/taffybar # taffybar references all ecosystem pkgs
nix flake update gtk-strut
```
## Flake Input Architecture
### Full Ecosystem Release Order
**taffybar's flake.nix** pulls all ecosystem deps as `flake = false` inputs from GitHub and builds them via `callCabal2nix` through a Nix overlay system.
**imalison-taffybar's flake.nix** re-declares the same inputs as proper flake inputs (where available) and uses `inputs.X.follows` to ensure taffybar uses the same versions:
```
gtk-sni-tray.inputs.gtk-strut.follows = "gtk-strut"
gtk-sni-tray.inputs.status-notifier-item.follows = "status-notifier-item"
gtk-sni-tray.inputs.dbus-menu.follows = "dbus-menu"
taffybar.inputs.gtk-sni-tray.follows = "gtk-sni-tray"
...
```
This means updating a leaf input in the imalison config flake automatically threads it through to taffybar and gtk-sni-tray.
## Common Scenarios
### Changed a leaf package (e.g. status-notifier-item)
1. Make changes in `~/Projects/status-notifier-item/`
2. Release to Hackage if publishing
3. Push to GitHub
4. `cd ~/.config/taffybar && nix flake update status-notifier-item`
5. Rebuild
### Changed taffybar itself
1. Make changes in `~/.config/taffybar/taffybar/`
2. Push to GitHub (or just rebuild — imalison config uses `path:` input)
3. `cd ~/.config/taffybar && nix flake update taffybar`
4. Rebuild
### Changed gtk-sni-tray (mid-level)
1. Make changes in `~/Projects/gtk-sni-tray/`
2. If a leaf dep also changed, update bounds in `gtk-sni-tray.cabal`
3. Push to GitHub
4. `cd ~/.config/taffybar && nix flake update gtk-sni-tray`
5. Rebuild
### Full ecosystem release (all packages)
Release in this exact order:
1. `gtk-strut`, `status-notifier-item`, `dbus-hslogger`, `dbus-menu` (leaves, parallel OK)
1. `gtk-strut`, `status-notifier-item`, `dbus-hslogger`, `dbus-menu` (leaves — parallel OK)
2. `gtk-sni-tray` (update bounds for any leaf changes first)
3. `taffybar` (update bounds for all changes)
4. Update all flake inputs in imalison config
5. Rebuild
## NixOS Configuration Integration
The personal NixOS config consumes these packages through a chain of flakes. When doing a system rebuild (`just switch` in `~/dotfiles/nixos`), be aware that there are multiple flake.lock files that may need updating depending on what changed.
```
nixos/flake.nix (top — `just switch` reads this)
│ ├── taffybar path:.../taffybar/taffybar
│ ├── imalison-taffybar path:../dotfiles/config/taffybar
│ └── gtk-sni-tray, gtk-strut, etc. (GitHub inputs)
dotfiles/config/taffybar/flake.nix (middle — imalison-taffybar)
│ ├── taffybar path:.../taffybar/taffybar
│ └── gtk-sni-tray, gtk-strut, etc. (GitHub inputs)
dotfiles/config/taffybar/taffybar/flake.nix (bottom — taffybar library)
│ └── gtk-sni-tray, gtk-strut, etc. (flake = false GitHub inputs)
```
All three flakes declare their own top-level inputs for the ecosystem packages and use `follows` to keep versions consistent. The key thing to understand: `path:` inputs snapshot the target flake **including its flake.lock** at lock time. So if you update only the top-level nixos flake.lock, the middle and bottom layers will still use whatever was previously locked in *their* flake.lock files.
This means when propagating a change to a system rebuild, you generally need to update flake.lock files **bottom-up** — the bottom layer first so the middle layer picks up fresh locks, then the middle so the top picks up fresh locks:
```bash
# Bottom (if an ecosystem dep changed):
cd ~/.config/taffybar/taffybar && nix flake update <pkg>
# Middle:
cd ~/.config/taffybar && nix flake update <pkg> taffybar
# Top:
cd ~/dotfiles/nixos && nix flake update <pkg> imalison-taffybar taffybar
```
Not every change requires touching all three layers. If you only changed taffybar itself, the bottom layer doesn't need updating since it *is* the bottom. If the nixos flake already uses `follows` to override an input from GitHub directly, updating just that top-level input may be sufficient. Think about which flake.lock files actually contain stale references and update those.