Skip to content

Dev - #37

Merged
stslex merged 28 commits into
masterfrom
dev
Jun 26, 2026
Merged

Dev#37
stslex merged 28 commits into
masterfrom
dev

Conversation

@stslex

@stslex stslex commented Jun 25, 2026

Copy link
Copy Markdown
Owner

No description provided.

stslex and others added 18 commits June 24, 2026 22:47
…d app_id

Prepares the systemd unit and the egui GUI for the deb/rpm/pacman packages.

- splitway.service: ExecStart now passes
  `--config /var/lib/splitway/config.json` and the unit declares
  StateDirectory=splitway (0700), mirroring nix/module.nix. The daemon
  creates its config under the persistent, daemon-owned state dir on first
  run instead of falling back to /root/.config (and logging a warning).
- Add the same --config to the commented socket-group opt-in ExecStart
  override. The bare `ExecStart=` reset fully replaces the command, so
  without this an opt-in user would silently drop --config and reintroduce
  the /root/.config fallback this commit removes. (Minor deviation from the
  "keep the block untouched" plan, for correctness/consistency with the
  main ExecStart and nix/module.nix.)
- splitway-gui: set the ViewportBuilder app_id to
  io.github.stslex.splitway so Wayland compositors map the window to the
  packaged .desktop entry + hicolor icon (shipped under that basename by
  the GUI package).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
Adds the MIT LICENSE (the repo had none) and declares `license = "MIT"` on
every workspace crate, then defines the deb + rpm metadata for the core
`splitway` package on splitway-daemon.

The package ships both binaries — `splitway-daemon` and the `splitway` CLI
(from splitway-cli) — plus the systemd unit and README/LICENSE. It is built
musl-static (*-unknown-linux-musl) so it has no shared-library dependencies
and installs on any glibc/musl baseline; the desktop GUI is a separate
package (next commit) that Depends on this one.

- [package.metadata.deb]: name=splitway, binaries to /usr/bin, copyright from
  the MIT text, Recommends network-manager + systemd-resolved (not Depends),
  empty Depends (static). An (empty) maintainer-scripts dir enables cargo-deb's
  systemd-units integration to generate the postinst/postrm: enable+start on
  install, restart on upgrade, stop on remove, daemon-reload.
- [package.metadata.generate-rpm]: same layout, auto-req disabled (static),
  weak-dep Recommends, raw /bin/sh systemd scriptlets (cargo-generate-rpm does
  not expand %systemd_* macros).

Asset-path note (verified by building both packages with cargo-deb 3.7.0 and
cargo-generate-rpm 0.21.0): cargo-deb resolves non-`target/` asset paths
relative to THIS crate's manifest dir (so workspace-root files use `../`),
while cargo-generate-rpm resolves relative to the invocation dir (workspace
root, bare paths) — hence the intentional path skew between the two blocks.

Version is stamped at the packaging layer (cargo deb --deb-version /
cargo generate-rpm --set-metadata) so dev builds get <ver>~dev.<utc>.<sha>
without a non-semver string in Cargo.toml. CI builds per-triple with --target
(remaps target/release -> target/<triple>/release and stamps the arch).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
…opt-in

A separate `splitway-gui` package for the egui desktop GUI (glibc, dynamic),
which Depends on the musl-static core `splitway` (>=, the IPC compat contract).

- .desktop (io.github.stslex.splitway.desktop, Exec=splitway-gui) +
  hicolor icons rasterized from assets/icon/splitway-icon.svg (8 PNG sizes +
  scalable SVG, basename = app_id) via packaging/icons/generate-hicolor.sh.
  The icon tree is committed so every packaging path ships it without a
  rasterizer; the .desktop passes desktop-file-validate.
- Dependencies (both formats, verified by building real packages): the
  eframe/glow windowing libs are DLOPEN'd by winit/glow at runtime, so they
  are absent from the ELF DT_NEEDED and neither cargo-deb's $auto nor
  cargo-generate-rpm's auto-req can detect them — they MUST be hardcoded.
  deb: libgl1, libx11-6, libxcursor1, libxi6, libxrandr2, libwayland-client0,
  libxkbcommon0, libc6 (>= 2.31 floor). rpm: mesa-libGL, libX11, libXcursor,
  libXi, libXrandr, libwayland-client, libxkbcommon (auto-req still pins the
  glibc floor from libc/libgcc sonames). Recommends an XDG desktop portal +
  backend for rfd's file dialog.
- Socket-group opt-in (security-sensitive): the maintainer scripts create an
  EMPTY `splitway` group and install a service drop-in switching the daemon
  to group-socket mode (0660 root:splitway, dir 0750). EMPTY-GROUP INVARIANT:
  with no members the posture is identical to the default 0600 root-only; the
  scripts NEVER add a user — the only grant is a human running
  `usermod -aG splitway <user>` + re-login. postinst installs the drop-in +
  reloads + restarts; postrm removes it, groupdel only if empty, reverting to
  root-only. A loud first-install message prints the exact opt-in one-liner.

Validated by building both packages with cargo-deb 3.7.0 /
cargo-generate-rpm 0.21.0 and inspecting deps, files, and scriptlets.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
…tests

New packaging.yml (no secrets — gates the PR). The publish/sign job is added
in the next commit.

- meta: compute the channel version once (compute-version.sh). Release (push
  to master) = clean <X.Y.Z>; dev/PR/dispatch = <X.Y.Z>~dev.<utc>.<sha>, which
  sorts below the release in dpkg and rpm.
- build-core (amd64 + arm64): `cross` builds splitway-daemon + splitway CLI
  musl-static, asserts `file` reports "statically linked", then cargo-deb /
  cargo-generate-rpm with --target (remaps target/release + sets arch) and the
  stamped version. Emits deb + rpm + tarball.
- build-gui (amd64 + arm64): builds the egui binary INSIDE debian:bullseye
  (glibc 2.31 floor, so the libc6 (>= 2.31) / rpm GLIBC requires are true),
  arm64 on a native arm64 runner (no QEMU). Rewrites the core-dependency floor
  to the built version for dev channels, then packages on the host.
- test-install (debian:bookworm, ubuntu:22.04, fedora:latest): installs the
  built artifacts directly; asserts the binaries run, the unit validates
  (systemd-analyze verify), the GUI pulls splitway + the GL deps, the empty
  `splitway` group exists with no members, and the .desktop validates.
- test-signed-repo: generates a THROWAWAY gpg key, builds + signs local apt
  (build-apt-repo.sh) and dnf (build-dnf-repo.sh) repos from the artifacts,
  serves them over localhost, and installs with signature verification ON —
  proving metadata + signing + verify end-to-end with no production secret.
  (Those two repo scripts are reused by the real publish job next commit.)
- test-arm64-smoke: best-effort arm64 deb install under QEMU.

Validated locally: actionlint clean (incl. shellcheck of run blocks); all
helper scripts shellcheck-clean; the deb/rpm builds + --target/--deb-version/
--set-metadata flags exercised against cargo-deb 3.7.0 / cargo-generate-rpm
0.21.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
Adds the publish-pages job (secrets) and the signing plumbing reused by the
PR-time ephemeral-key test.

- publish-pages: runs on push to master (release) / dev (dev) and dispatch,
  NEVER on pull_request, gated behind the build + test jobs. Serialized by a
  single `pages-deploy` concurrency group (cancel-in-progress: false) so two
  deploys queue rather than clobber. Imports the RSA signing key, checks out
  (or bootstraps) the persistent gh-pages branch, drops the artifacts into the
  correct channel pool, regenerates + signs ONLY that channel's apt + dnf
  metadata, publishes the armored pubkey to splitway.gpg, renders index.html,
  and commits + pushes — MERGE, never wipe, so old versions and the other
  channel survive. Release additionally attaches the tarballs to the v<ver>
  GitHub Release. A post-deploy smoke waits for Pages to go live, then installs
  from the real repo with signature verification ON (apt + dnf).
- build-apt-repo.sh / build-dnf-repo.sh: optional SPLITWAY_GPG_PASSFILE feeds
  the real key's passphrase via loopback (never on a command line); unset for
  the passphrase-less ephemeral key.
- render-index.sh: the Pages landing page with per-distro, per-channel
  add-repo snippets + the key fingerprint.
- RSA fix: the throwaway test key (and, by requirement, GPG_PRIVATE_KEY) is RSA
  — rpm --addsign only produces a verifiable signature with RSA; an EdDSA key
  silently yields no RPMTAG_RSAHEADER (found + fixed via local signing tests).

Validated locally: apt InRelease + Release.gpg verify Good; per-arch Packages
filtering correct; dnf repomd.xml.asc verifies; RSA-signed rpm passes rpm -K
("digests signatures OK"). actionlint + shellcheck clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
Closes Arch via a self-hosted, GPG-signed pacman repo (reusing the apt/dnf key
+ Pages), since AUR registration is disabled. x86_64 for the hosted repo;
aarch64 users use the in-repo splitway-bin PKGBUILD.

PKGBUILDs in packaging/aur/ (also usable now via `makepkg -si`):
- splitway: source build of daemon + CLI from the release tag; makedepends
  cargo; ships both binaries + unit; splitway.install prints the enable hint
  (Arch policy: no auto-enable); optdepends networkmanager / systemd-resolvconf.
- splitway-bin: prebuilt from the release tarball (x86_64 + aarch64);
  provides/conflicts splitway.
- splitway-gui: source egui GUI; depends splitway + libglvnd/libxkbcommon/
  wayland/libx11/libxcursor/libxi/libxrandr; optdepends xdg-desktop-portal;
  splitway-gui.install mirrors the deb/rpm empty-group + drop-in invariant.

CI (packaging.yml):
- build-arch: archlinux container, non-root makepkg of the two source
  PKGBUILDs from THIS checkout (clean version — pacman has no ~dev channel
  because vercmp does not treat ~ as a pre-release marker), validates
  .SRCINFO + namcap (advisory). x86_64 .pkg.tar.zst artifacts.
- test-arch: pacman -U local install (asserts binaries + unit + empty group),
  then a throwaway-RSA-key signed repo — repo-add --sign, pacman-key
  --add/--lsign, SigLevel = Required DatabaseOptional, pacman -Sy with
  verification ON.
- publish-pages (release only): copies the .pkg.tar.zst into the persistent
  arch/release/x86_64 subtree, detach-signs each with the real key, repo-add
  (in a container) incrementally (old packages preserved), replaces Pages-
  hostile db/files symlinks with real signed copies, reuses splitway.gpg.
  Post-deploy: live `pacman -Sy splitway` with verification ON.
- render-index.sh: Arch section (signed repo primary, makepkg alternative,
  AUR pending).

DEFERRED (not here): the automated AUR ssh push — blocked on AUR registration
reopening. The in-repo PKGBUILDs are the bridge.

Validated locally: all PKGBUILD/.install bash-syntax-clean; actionlint clean;
index renders with $arch left literal for pacman.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
Docs only — no code.

- README: Install sections for apt / dnf (both channels) and Arch (signed
  pacman repo primary, in-repo PKGBUILD makepkg alternative; AUR pending), with
  the key-verification note. NixOS section left as-is.
- packaging/README.md: a Distribution packages (deb / rpm / pacman) section —
  the two-package split, dev vs release channels + ~dev versioning, the glibc
  2.31 floor, the dlopen'd GL deps, the GUI socket-group drop-in + empty-group
  invariant, and the pacman specifics (x86_64-only, no ~dev channel, detached
  signing, repo-add incrementality).
- docs/design/linux-distro-packaging.md: the durable record — decisions 1-7,
  the channel/version topology, dep lists, signing + merge mechanics across all
  three formats (incl. the RSA-not-EdDSA and cargo-deb-vs-generate-rpm
  path-resolution gotchas), the two-layer test design, the pacman-now/AUR-later
  Arch strategy, and the signing key.
- ROADMAP.md: Phase 6 marked done (Linux), noting the two-package design
  supersedes the original one-package sketch; macOS Homebrew + the automated
  AUR push remain deferred.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
No behavior change for the current (validated) inputs — robustness only,
flagged by an adversarial self-review of the diff:

- build-apt-repo.sh: `break` after the first Architecture line in the per-arch
  Packages filter (the canonical value; a valid stanza has exactly one).
- packaging.yml: `g` flag on the GUI core-dep-floor seds (defensive if more
  `splitway (>=` references are ever added).
- packaging.yml: comment that test-arm64-smoke is intentionally not a publish
  gate (best-effort under QEMU, continue-on-error).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018GKGiqawfPb5fzMGHisrrF
Resolves the Codex + self-review findings on the Phase 6 packaging PR.

Build-blocking CI fixes:
- static-linkage gate: assert no dynamic interpreter instead of requiring the
  literal "statically linked" (musl x86_64 is "static-pie linked") — unblocks
  build-core (amd64) and the whole deb/rpm pipeline
- test-arch: read the GPG fingerprint from fpr field 10, not 5 (5 is empty)
- AUR splitway-bin: rename splitway.install -> splitway-bin.install so
  install="$pkgname.install" resolves (makepkg no longer aborts)
- build-gui: CARGO_NET_RETRY + a retrying `cargo fetch --locked` before the
  offline build, hardening the transient arm64 crates.io failure

Supply-chain / correctness:
- apt: dearmor the published (armored) key into the binary keyring at every
  consumption site (works on every apt version; the published file stays armored
  for rpm --import / pacman-key)
- publish: fail-closed signature verification (apt InRelease+Release.gpg, dnf
  repomd + per-rpm RSA header, pacman db+pkg sigs) BEFORE the gh-pages push
- apt Release: Valid-Until (APT_VALID_DAYS, default 90d; LC_ALL=C) for
  freeze/replay protection
- dev-floor sed: anchor to the dependency lines (leave the comment), and assert
  the floor was actually stamped
- signed-repo tests (apt/dnf/pacman) now install splitway-gui too, exercising the
  GUI package under signature enforcement

Arch / consistency / docs:
- splitway-gui PKGBUILD: splitway>=$pkgver floor + hicolor-icon-theme,
  desktop-file-utils
- new check-pkgver-sync.sh (meta job): daemon version == every PKGBUILD pkgver
- render-index/README: dearmor --yes for apt, pacman-key --init, dev-channel
  keyring install
- splitway-bin SKIP digest documented + tracked for the deferred AUR-push phase

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…oling

Follow-up to the second Codex pass on PR #36.

- splitway-bin: `provides=("splitway=$pkgver")` (was unversioned). pacman only
  satisfies a versioned dependency from a versioned provision, so splitway-gui's
  new `splitway>=$pkgver` floor could not install against the prebuilt core.
- test-signed-repo: install `rpm` in the tooling step. build-dnf-repo.sh needs
  `rpm --addsign`; it passes today only because ubuntu-latest pre-installs rpm —
  make it explicit (matches the publish job) so the dnf signing path is robust.
- packaging/README.md: document the one-time config relocation for users who ran
  the daemon by hand as root before packaging (old XDG fallback
  /root/.config/splitway -> /var/lib/splitway). No maintainer-script migration:
  no published package used the old path, it is config-not-read (not data loss),
  and the deb core postinst is cargo-deb-generated (#DEBHELPER#) from an empty
  dir, so a hand-written migration would risk breaking systemd enablement that
  the docker install-test (no systemd) could not catch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The `meta` gate (check-pkgver-sync.sh) requires every packaging/aur/*/PKGBUILD
`pkgver=` to equal the daemon version, but release.yml's bump-version job only
bumped splitway-daemon/Cargo.toml. So the first post-release auto-bump would
leave the three PKGBUILDs behind and fail every later packaging run in `meta`
until a human hand-edited all three.

- Add packaging/ci/sync-pkgver.sh: the write side of the lockstep invariant
  (symmetric with check-pkgver-sync.sh, same daemon-version read). It stamps the
  daemon version into each PKGBUILD `pkgver=` and resets `pkgrel=1` (Arch
  convention on a version change). The `$pkgver`-derived fields (source URLs,
  provides, depends floor) follow automatically.
- release.yml bump-version: run sync-pkgver.sh after the Cargo.toml bump and
  `git add` the PKGBUILDs into the same commit.

Verified locally: no-op when already in sync (no diff), correct bump on a
simulated 0.0.5 -> 0.0.6, and check-pkgver-sync.sh passes against the result.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…review)

Two findings from Codex's re-review of b326036:

- P2 (splitway-gui/Cargo.toml): the deb declared libgl1 but not libegl1,
  and the rpm required mesa-libGL but not mesa-libEGL. glow/glutin creates
  its GL context via EGL on Wayland (glutin_egl_sys is in Cargo.lock; GLX on
  X11), and libgl1 does NOT pull libegl1 — so a minimal Wayland-only install
  would succeed and then fail at GL-context creation. Add libegl1 (deb) and
  mesa-libEGL (rpm); both pull the libglvnd EGL loader, mirroring how
  libgl1/mesa-libGL pull GLX. Arch is unaffected (libglvnd already provides
  libGL + libEGL). Doc + comments updated.

- P1 (packaging.yml test-arch): the local `pacman -U` smoke preinstalled the
  GL/X11/wayland libs but not hicolor-icon-theme/desktop-file-utils, which
  the splitway-gui PKGBUILD declares as hard deps. `pacman -U` on local files
  only auto-resolves deps from a synced repo DB, so the smoke must not lean
  on that — preinstall the full declared set explicitly, matching the PKGBUILD.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…iew round 3)

Codex re-review (1) + self-review (4) of 6de36d7:

- P2 (Codex, splitway-gui): add the X11 xkb runtime lib. winit's default `x11`
  feature has xkbcommon-dl dlopen libxkbcommon-x11.so (confirmed in Cargo.lock),
  a SEPARATE package from libxkbcommon on Debian (libxkbcommon-x11-0), Fedora
  (libxkbcommon-x11) AND Arch (libxkbcommon-x11 — verified via the Arch package
  API: it provides libxkbcommon-x11.so and is NOT bundled in the base
  libxkbcommon). Without it an X11 session can fail to load the lib before the
  window opens. Added to the deb Depends, rpm Requires, the Arch GUI PKGBUILD
  depends, and both Arch CI preinstall lists.

- P2 (postinst): the groupadd under `set -e` was the only unguarded mutating
  step. Keep the abort (the drop-in is meaningless without the group) but make
  it deliberate + diagnosable with an explicit error message + exit.

- P2 latent (version reads): `grep '^version' … | head -1` SIGPIPEs grep under
  `set -o pipefail` if a second match ever appears. Replaced with a SIGPIPE-free
  `awk -F'"' '/^version/{print $2; exit}'` in compute-version.sh,
  check-pkgver-sync.sh (+ the pkgver read), sync-pkgver.sh and release.yml (x3).

- P2 (splitway-bin): surface the same networkmanager / systemd-resolvconf
  optdepends as the source splitway PKGBUILD (identical daemon, same prereqs).

- P2 (README niri): the interim egui GUI now sets `.with_app_id(...)` and the
  packaged splitway-gui ships the matching .desktop + icons, so the app-id
  window rule is no longer Tauri-only; clarified the packaged GUI is the egui build.

Also quoted "$GITHUB_OUTPUT" in the release.yml blocks touched above
(pre-existing SC2086). actionlint + shellcheck clean; awk reads verified to
yield 0.0.5 and check-pkgver-sync passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…emon (Codex P2)

The post-release auto-bump stamped the AUR PKGBUILDs with the *next*
(unreleased) daemon version, so `makepkg -si` from master pointed at a
`v$pkgver` tag / release assets that do not exist yet.

- release.yml: run sync-pkgver.sh BEFORE the daemon bump so the PKGBUILDs
  pin the just-released version; bump the daemon afterwards for the next cycle.
- check-pkgver-sync.sh: validate the pinned pkgver names a release tag that
  EXISTS (all three PKGBUILDs agreeing), with a no-tags bootstrap fallback —
  instead of requiring equality with the in-tree daemon version.
- packaging.yml: fetch-depth: 0 on the meta checkout so the gate sees tags.
- docs/design: record the invariant and why the gate checks existence, not
  "latest" (avoids spurious dev/PR and release-window failures).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKokH93URrCizdQdVpNCNM
… daemon (Codex P2)

Follow-up to pinning the AUR pkgver to the released tag: the daemon version
now intentionally runs ahead of the committed pkgver. build-arch pre-placed
the checkout tarball as <pkg>-$VERSION.tar.gz (daemon version), but the
PKGBUILD's source= expects <pkg>-$pkgver.tar.gz. When the two diverge makepkg
can't find the local archive and silently downloads the old v$pkgver tag,
building stale code while the smoke test still passes.

Read pkgver from each PKGBUILD and key both the archive filename and the
git-archive --prefix on it, so the pre-placed checkout is always the source
makepkg uses. Drop the now-unused VERSION env.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKokH93URrCizdQdVpNCNM
…inned tag (Codex P1)

The committed PKGBUILD pkgver intentionally lags to the last released tag (so a
user's `makepkg -si` resolves an existing tag), but the hosted pacman repo must
ship the version being released. The prior approach keyed the build on the
committed pkgver, so a release push would publish Arch packages under the
PREVIOUS version and Arch users would never receive the new one.

build-arch now stamps the daemon/meta version into the EPHEMERAL PKGBUILD (never
committed) and pre-places the matching <pkgname>-<VERSION>.tar.gz so makepkg
builds THIS checkout as VERSION — no tag download, correct published version.
The committed PKGBUILDs and the check-pkgver-sync.sh gate are untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKokH93URrCizdQdVpNCNM
`pacman -Sy <pkg>` refreshes the sync databases without upgrading, leaving the
DB ahead of installed packages and resolving deps from a partial-upgrade state.
Use `-Syu` in the hosted-index and README install snippets. The CI smoke tests
keep `-Sy` (throwaway containers, not user systems).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKokH93URrCizdQdVpNCNM
Phase 6: Linux distribution packaging (apt / dnf / pacman + signed GitHub Pages repos)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b21063162d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packaging/ci/compute-version.sh

@stslex stslex left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — PR #37 (Dev → master: Phase 6 distro packaging)

Reviewed read-only, no changes pushed. Inline thread comments attached. Overall the packaging work is solid and internally consistent (the dlopen'd GL/EGL/X11/xkb/wayland dep lists match across deb/rpm/pacman, the socket-group empty-group invariant and maintainer scripts are correct, the systemd --config override re-includes correctly, and the .desktop/icon/app_id strings all agree). The issues are concentrated in CI.

🔴 CI failures — root causes

1. build-arch fails (gates this PR) — stale Cargo.lock.
release.yml's bump-version job bumps splitway-daemon/Cargo.toml but never regenerates/commits Cargo.lock. Result on master today: Cargo.toml = 0.0.6, Cargo.lock pins splitway-daemon = 0.0.5 (verified). This PR builds on the merge commit, so the Arch prepare() cargo fetch --locked aborts:

error: cannot update the lock file ... because --locked was passed to prevent this

The same --locked/--frozen pattern in build-gui will fail identically on release pushes. Fix: regenerate + commit Cargo.lock (cargo update -p splitway-daemon --precise <ver>) — both to unblock this PR and durably in release.yml. Details on the release.yml line-149 comment.

2. publish-pages fails — self-inflicted on first deploy.
The signed gh-pages push succeeds and verifies, then the post-deploy live-smoke exit 1s after a 10-min poll. On the first root-commit deploy, Pages isn't enabled/propagated yet, so the publish is reported failed despite succeeding. (This job runs on push, not on the PR, so it isn't a hard merge gate — but it's a red X.) Fix: make the live-smoke non-fatal and ensure Pages is enabled for gh-pages. Details on the packaging.yml line-694 comment.

🟡 Minor / nits (inline)

  • build-dnf-repo.sh:35 — passphrase-file path word-split is fragile; use an array like the apt script.
  • compute-version.sh:32 — same-second dev pushes are non-monotonic; consider run-number/committer-time.
  • docs/design/linux-distro-packaging.md:83 — dep lists drifted from the manifests (missing libegl1/mesa-libEGL/libxkbcommon-x11).
  • splitway-gui/Cargo.toml:189 — rpm portal Recommends is GTK-only vs the deb's OR-list.

Code/docs otherwise clean: app_id consistent across app.rs / .desktop / icons; license = "MIT" on all crates + new LICENSE; no redaction or language-rule issues. The two CI blockers are the only things that need action before merge.


Generated by Claude Code

Comment thread .github/workflows/release.yml Outdated
Comment thread packaging/aur/splitway/PKGBUILD
Comment thread .github/workflows/packaging.yml Outdated
Comment thread .github/workflows/packaging.yml
Comment thread packaging/ci/build-dnf-repo.sh Outdated
Comment thread packaging/ci/compute-version.sh Outdated
Comment thread docs/design/linux-distro-packaging.md Outdated
Comment thread splitway-gui/Cargo.toml
stslex and others added 5 commits June 26, 2026 07:53
origin/master carried splitway-daemon Cargo.toml=0.0.6 with a stale
Cargo.lock=0.0.5: release.yml's post-release auto-bump rewrote the toml
but never relocked. The dev->master merge tree inherited that drift, so
`cargo fetch --locked` (build-arch's makepkg prepare) and `cargo build
--frozen` (build-gui) aborted with "cannot update the lock file ...
because --locked was passed" — the red build-arch / build-gui checks on
PR #37.

- Sync this branch's Cargo.lock to daemon 0.0.6 (merged from master), so
  the merge tree is internally consistent and the packaging jobs build.
- release.yml bump-version: add a toolchain, then
  `cargo update -p splitway-daemon --precise "$NEW_VERSION"` and stage
  Cargo.lock in the bump commit, so master never drifts again.
- The bot bump commit gets `[skip ci]`: a GITHUB_TOKEN push already does
  not re-trigger workflows, but the marker makes it explicit (and holds
  if the push ever moves to a PAT), so the next-cycle bump can never
  publish an unreleased X.Y.(Z+1) to the stable channels (Codex P1).
- ci.yml: a `cargo metadata --locked` guard fails loudly on any future
  Cargo.lock drift instead of letting it surface as a packaging abort.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The post-deploy steps poll the live Pages URL for 10 min and `exit 1` on
timeout. On the first (root-commit) gh-pages deploy — Pages not yet
enabled/propagated — the package is never served in the window, so the
whole publish-pages job is reported failed even though the signed deploy
already pushed and verified cleanly.

Downgrade both liveness timeouts (apt/dnf smoke and the pacman smoke) to
`::warning` + `exit 0`, skipping the live install. The pre-push "Verify
all signatures (fail closed)" step still gates integrity before the push,
and the actual install stays fatal once the repo IS live — only the
propagation-timeout path is now non-fatal, so a verified publish is never
reported as failed.

Note: enabling GitHub Pages for the gh-pages branch is a one-time repo
setting (Settings -> Pages -> Branch: gh-pages); nothing in CI can do it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
build-dnf-repo.sh: the single PASS_OPT string relied on word-splitting
(SC2086 disabled) at the gpg call. Split it: pass_opt[] (array) for the
direct gpg detach-sign — space-robust, mirroring build-apt-repo.sh's
gpg_sign — and pass_macro (plain string, byte-identical to the original)
for the rpm __gpg_sign_cmd macro, which rpm tokenizes itself and cannot
take a bash array. The passphrase FILE path is mktemp-derived and never
has spaces, so the macro keeps the proven form (zero regression on the
real-key publish path, which has never run in CI).

compute-version.sh: append GITHUB_RUN_NUMBER to the dev pkgver ->
`<ver>~dev.<utc>.<run>.<sha>`. Two pushes in the same UTC second now order
monotonically (run number is compared numerically) instead of falling
back to the non-monotonic lexical short-sha compare. Defaults to 0
outside Actions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The design doc's GUI dependency lists had drifted from the manifests:
- Debian: add libegl1 + libxkbcommon-x11-0
- Fedora: add mesa-libEGL + libxkbcommon-x11
- Arch: add libxkbcommon-x11
…with a note on why EGL is separate from GL (EGL context on Wayland) and
xkbcommon-x11 separate from xkbcommon (winit x11 dlopen), and that the
list is the windowing-lib subset (the PKGBUILD also carries the icon /
desktop-file install-hook deps).

Also update the now-stale dev version format `<X.Y.Z>~dev.<utc>.<sha>` ->
`<X.Y.Z>~dev.<utc>.<run>.<sha>` in the channel-topology table and in
packaging/README.md to match compute-version.sh.

splitway-gui/Cargo.toml: document the rpm Recommends asymmetry — the deb
offers gtk|wlr|kde but a cargo-generate-rpm `key="*"` table has no
boolean-OR, so it names the GTK portal (a weak dep that works on most
desktops); a passthrough rich-dep is left out until verified to emit
correctly through cargo-generate-rpm.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@stslex

stslex commented Jun 26, 2026

Copy link
Copy Markdown
Owner Author

@codex review

The post-release auto-bump only updates master, so after each release dev
falls one version behind (exactly the drift that left this branch at 0.0.5
while master was at 0.0.6). Add a `sync-dev` job (`needs: bump-version`)
that opens — or refreshes — a PR merging master back into dev so dev
tracks the next dev cycle automatically.

A PR, not a direct push: dev follows the branch→PR workflow and may be
protected. The job no-ops when dev already contains master, reuses an
open sync PR instead of duplicating, and enables auto-merge best-effort
(lands once mergeable where the repo allows it, otherwise waits for a
one-click merge). The PR is opened by GITHUB_TOKEN, which does not trigger
pull_request CI on itself — documented inline, with the PAT escape hatch
for anyone who wants required checks to gate the sync merge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6f7c141a84

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packaging/ci/sync-pkgver.sh
stslex and others added 2 commits June 26, 2026 09:14
The new `Verify Cargo.lock` step resolves against the crates.io index on a
cold runner, so a transient blip (observed: `OpenSSL ... unexpected eof`
fetching the tauri-codegen index entry) could flake it — unlike the rest
of this repo's network steps, which already retry.

Wrap it to match that pattern: CARGO_NET_RETRY=10 plus an outer retry that
rides out a transient registry error, while still failing FAST on a real
drift (the `--locked` refusal, which no retry can fix) with a clear
relock hint.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The source PKGBUILDs fetch the `v$pkgver` tag archive (generated the
instant the tag exists), but splitway-bin fetches the release ASSET
tarballs (splitway-$pkgver-linux-*.tar.gz) that packaging.yml attaches
later and independently of release.yml's bump. So stamping splitway-bin
at tag time could point it at not-yet (or, on a failed upload, never-)
uploaded assets while check-pkgver-sync.sh still passes on tag existence
alone (Codex P2).

- sync-pkgver.sh: skip splitway-bin — only advance the tag-archive source
  PKGBUILDs at release time.
- check-pkgver-sync.sh: exclude splitway-bin from the shared-version / tag
  check; it is allowed to lag, and tag-existence is necessary-but-not-
  sufficient for an asset-based fetch.

splitway-bin's pkgver + real sha256sums are both knowable only after the
assets are published, so they are owned together by the deferred
asset-aware AUR-push automation (already referenced in its PKGBUILD's
TRUST ASSUMPTION note). splitway-bin is not on AUR yet, so there is no
live 404 surface today.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@stslex

stslex commented Jun 26, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d0d89562d4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread splitway-gui/Cargo.toml Outdated
…odex P2)

The GUI dlopens libwayland-egl.so.1 (glutin's Wayland EGL platform binds
the GL surface to the wl_surface via wl_egl_window_*), but the manifest
declared only libwayland-client0 / libwayland-client — and the client lib
does NOT pull the EGL platform lib. So on a minimal Wayland host the
package installs and passes the `command -v` smoke tests, then fails at
GL-context creation. Verified the binary dlopens it:
`strings splitway-gui | grep libwayland-egl` ->
"Library libwayland-egl.so could not be loaded." + libwayland-egl.so.1.

- deb depends: add libwayland-egl1
- rpm requires: add libwayland-egl
- Arch is already covered: the `wayland` package ships libwayland-egl.so.1
  alongside libwayland-client.
- Manifest comments + docs/design dep lists updated with the rationale
  (separate from libwayland-client0, same pattern as libegl1 vs libgl1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@stslex

stslex commented Jun 26, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d363052c85

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread splitway-gui/Cargo.toml
…p (Codex P2)

The GUI maintainer scripts run groupadd/groupdel to create and remove the
opt-in `splitway` socket group, but neither package declared the provider:
groupadd is in `shadow-utils` (Fedora/RHEL) and `passwd` (Debian). On a
minimal image lacking it:
- rpm: %post fails NON-fatally, so the install "succeeds" but leaves the
  socket-group drop-in with no group — the daemon then exits on
  `--socket-group splitway` and users can't opt in (Codex P2).
- deb: the postinst `exit 1`s, so the install fails loudly instead.

Declare the dep on both for parity (present on normal systems, but now
guaranteed on minimal ones):
- rpm `[requires]`: add `shadow-utils`
- deb `depends`: add `passwd`
Manifest comments + the design-doc socket-group note updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@stslex

stslex commented Jun 26, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: f86729ea02

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@stslex
stslex merged commit fa18210 into master Jun 26, 2026
40 checks passed
stslex added a commit that referenced this pull request Jun 26, 2026
origin/master carried splitway-daemon Cargo.toml=0.0.6 with a stale
Cargo.lock=0.0.5: release.yml's post-release auto-bump rewrote the toml
but never relocked. The dev->master merge tree inherited that drift, so
`cargo fetch --locked` (build-arch's makepkg prepare) and `cargo build
--frozen` (build-gui) aborted with "cannot update the lock file ...
because --locked was passed" — the red build-arch / build-gui checks on
PR #37.

- Sync this branch's Cargo.lock to daemon 0.0.6 (merged from master), so
  the merge tree is internally consistent and the packaging jobs build.
- release.yml bump-version: add a toolchain, then
  `cargo update -p splitway-daemon --precise "$NEW_VERSION"` and stage
  Cargo.lock in the bump commit, so master never drifts again.
- The bot bump commit gets `[skip ci]`: a GITHUB_TOKEN push already does
  not re-trigger workflows, but the marker makes it explicit (and holds
  if the push ever moves to a PAT), so the next-cycle bump can never
  publish an unreleased X.Y.(Z+1) to the stable channels (Codex P1).
- ci.yml: a `cargo metadata --locked` guard fails loudly on any future
  Cargo.lock drift instead of letting it surface as a packaging abort.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant