Skip to content

Prove the release-package pattern on macarchy-touchbar #16

Description

@phmatray

Part of #14 — Releases publish no installable package, only GitHub's source zip.
Blocked by: none — can start immediately

Problem

macarchy-touchbar v0.4.0's release carries no installable artifact. It is the proof case for the whole job: real code, a python package, a udev rule, a modules-load drop-in and a user unit — every shape the other repos have between them.

Proposed solution

A PKGBUILD in the repo and a workflow that, on release publication, builds it in an archlinux:base-devel container and attaches the result to that release.

Already built by hand on the target machine, so the layout below is observed and not designed:

usr/bin/macarchy-touchbar
usr/lib/modules-load.d/macarchy-touchbar.conf
usr/lib/systemd/user/macarchy-touchbar.service
usr/lib/udev/rules.d/70-macarchy-touchbar.rules
usr/lib/python3.14/site-packages/macarchy_touchbar/…

Area

ci

📋 Spec

Goal

macarchy-touchbar's next release carries one *.pkg.tar.* asset that installs with pacman -U.

Design

PKGBUILD at the repo root, arch=('any'), source=() carrying two entries: the release tarball, and the Material Symbols font that install.sh:27 currently curls unpinned from master. In a PKGBUILD it gets a real sha256sum — strictly better than the status quo, and it is what makes the package self-contained.

package() mirrors install.sh file for file. site-packages is derived, never hardcoded: it carries the interpreter version.

The workflow triggers on release: [published] only, builds as a non-root user (makepkg refuses root), runs makepkg --nodeps (the depends are a runtime contract, and the container has no reason to resolve them), and uploads with a globPKGEXT differs between machines (.xz here, .zst in a stock container).

Acceptance criteria

  1. gh release view <tag> --json assets lists exactly one *.pkg.tar.*.
  2. tar -tf on that asset contains usr/bin/macarchy-touchbar and the udev, modules-load and systemd paths.
  3. The font is inside the package — the installed machine needs no network.
  4. The workflow does not run on push or pull_request.
  5. Re-running it on the same release replaces the asset rather than failing.

Testing decisions

Seams under test: the built package's file list (tar -tf) and the release's asset list (gh release view --json assets).
Prior art: macarchy-install/tests/clean-machine.sh — prove an install by observing the result, not the script.
A good test here: a repo test asserting the PKGBUILD's package() covers every path install.sh installs, so the two channels cannot drift.

Out of scope

  • AUR publication; package signing; any change to install.sh.

🛠️ Implementation plan

For agentic workers: execute this plan task-by-task with implement-issue (subagent-per-task for broad plans, inline for small ones). Steps use checkbox (- [ ]) syntax for tracking.

Goal: one installable package on macarchy-touchbar's next release.
Architecture: PKGBUILD at the repo root; a workflow beside release-please.yml; pytest suites under tests/.
Tech stack: bash, makepkg 7, GitHub Actions, archlinux:base-devel.

Seams under test: the built package's file list (tar -tf) and the release's asset list (gh release view --json assets).

Global constraints

  • arch=('any') — no compilation in this repo.
  • Never hardcode PKGEXT or the site-packages path.
  • The package must not fetch anything at install time.
  • Conventional Commit PR title decides the release bump; commits below use feat.
  • Commit trailer: Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>.

Task 1: let the daemon find its data outside the checkout

Files: modify macarchy_touchbar/daemon.py, macarchy_touchbar/draw.py; test tests/test_data_root.py.

Interfaces: a single data_root() resolving, in order: $MACARCHY_TOUCHBAR_DATA, /usr/share/macarchy-touchbar, then the checkout root one level above the package. modules/, config/layouts.toml and fonts/*.codepoints all go through it.

  • Step 1: Write the failing test in tests/test_data_root.py (seam: data_root()'s return value) — assert the env var wins, then the packaged path when it exists, then the checkout root.
  • Step 2: Run python3 -m pytest tests/test_data_root.py -q → FAIL (no such function).
  • Step 3: Implement data_root() once and route daemon.py:43, :71, :158 and draw.py:25 through it. The checkout fallback keeps ./install.sh working unchanged.
  • Step 4: Run the whole suite → PASS; the daemon still starts from a checkout.
  • Step 5: Commit: feat: resolve the data directory instead of assuming the checkout.

Task 2: the PKGBUILD, with a test that pins it to install.sh

Files: create PKGBUILD; test tests/test_pkgbuild.py.

Interfaces: pkgname=macarchy-touchbar, arch=('any'), source=(<release tarball> <Material Symbols font>), package() mirroring install.sh.

  • Step 1: Write the failing test in tests/test_pkgbuild.py (seam: the PKGBUILD text vs install.sh's installed paths) — assert every destination install.sh writes has a counterpart in package().
  • Step 2: Run python3 -m pytest tests/test_pkgbuild.py -q → FAIL (no PKGBUILD).
  • Step 3: Write the PKGBUILD, modelled on omarchy-aikit/PKGBUILD's package() but versioned from the tag rather than git describe. Pin the font with a real sha256sum.
  • Step 4: Build it for real: makepkg -f --nodeps, then tar -tf the result and check the five paths.
  • Step 5: Re-run the suite → PASS.
  • Step 6: Commit: feat(pkg): a PKGBUILD that mirrors install.sh.

Task 3: publish it on every release

Files: create .github/workflows/package.yml.

Interfaces: on: release: [published]; job builds in archlinux:base-devel and runs gh release upload "$TAG" *.pkg.tar.* --clobber.

  • Step 1: Write the workflow: non-root build user, makepkg --nodeps, glob upload with --clobber.
  • Step 2: Assert the trigger is release-only — grep -c 'pull_request\|push:' .github/workflows/package.yml must be 0.
  • Step 3: Commit: feat(ci): attach the package to every release.
  • Step 4: Merge, cut a release, and read the asset back with gh release view --json assets → exactly one *.pkg.tar.*.
  • Step 5: Download it and tar -tf it; confirm the five paths and the font.
  • Step 6: Re-run the workflow on the same release; confirm it replaces rather than fails.
  • Step 7: Record the result on Releases publish no installable package, only GitHub's source zip #14's ## Decisions so far.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: cithe workflows and the hermetic test suitesbugSomething isn't workingeffort: mediumA handful of tasks inside one layerpriority: mediumThe default tier — worth doing, not urgent

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions