feat: release and install rkd-activity (#1143) #7

Merged
dozken merged 4 commits from feat/1143-plugins-release-and-install-rkd-activity-pa into main 2026-09-25 15:26:54 +02:00
Owner

Summary

rkd-activity merged in #6 but users could only get it with a Rust toolchain: the release pipeline and install.sh only knew rkd-terminal. This makes a release build and attach rkd-activity for Linux, lets the same install.sh install it (… | sh -s -- rkd-activity), and puts every crate on one workspace version so the next tag (v0.6.0) releases rkd-activity with the rest. No tag is pushed here; cutting v0.6.0 is the owner's call.

Refs nanoya-biz/rkd#1143

Type of change

  • New feature
  • Build, CI, or tooling
  • Docs

Screenshots / recording

Tooling change, so the pair is the installer's output. Same command, same fake v0.6.0 release (built with this branch's package-release.sh from real host builds of both plugins, served as file:// through RKD_*_BASE_URL + RKD_*_INSECURE_TEST=1), uname faked to Linux x86_64, *_NO_SERVICE=1. BEFORE runs git show origin/main:install.sh; AFTER runs this branch's.

BEFORE — origin/main: install.sh | sh -s -- rkd-activity ignores the argument and installs rkd-terminal

rkd-terminal: warning: downloading from file://<tmp>/srv (RKD_TERMINAL_BASE_URL), not https://git.rkd.nanoya.biz
rkd-terminal: downloading rkd-terminal-v0.6.0-x86_64-unknown-linux-musl
rkd-terminal: installed v0.6.0 to <tmp>/home-before/.local/bin/rkd-terminal
rkd-terminal: not installing the service (RKD_TERMINAL_NO_SERVICE=1), so nothing is running yet.
-- ~/.local/bin: rkd-terminal

AFTER — this PR: the same command installs rkd-activity, with its own settings

rkd-activity: warning: downloading from file://<tmp>/srv (RKD_ACTIVITY_BASE_URL), not https://git.rkd.nanoya.biz
rkd-activity: downloading rkd-activity-v0.6.0-x86_64-unknown-linux-musl
rkd-activity: installed v0.6.0 to <tmp>/home-after/.local/bin/rkd-activity
rkd-activity: not installing the service (RKD_ACTIVITY_NO_SERVICE=1), so nothing is running yet.
rkd-activity: next: start it, with `rkd-activity serve` (in the foreground) or `rkd-activity install` (as a service), then run `rkd-activity pair` and enter the code in RKD → Settings → Plugins on this device.
-- ~/.local/bin: rkd-activity

The installed binary is byte-identical (cmp) to the cargo build --release output it was packaged from. The release workflow itself only runs on a tag, so there is no before/after of a real release run.

What changed

  • Versioning (decided): one version for every crate. [workspace.package] version = "0.5.0", each crate version.workspace = true; rkd-activity goes 0.1.0 → 0.5.0 (Cargo.lock updated). A tag vX.Y.Z releases all plugins at X.Y.Z, so v0.6.0 bumps rkd-activity too. release-guard.sh now checks the tag against the workspace version and refuses any local/* crate that sets its own. Written down in local/README.md's new Releases section and the root README's "Adding a plugin" step 4.
  • Release: build-linux builds -p rkd-terminal -p rkd-activity in one zigbuild per target and packages + static-checks both; package-release.sh takes the plugin from the binary's file name (only rkd-terminal/rkd-activity accepted). Assets: rkd-activity-<tag>-{x86_64,aarch64}-unknown-linux-musl.tar.gz + .sha256.
  • macOS: not shipped (decided). rkd-activity detects nothing on macOS and rkd-activity install bails there (LINUX_ONLY), so a macOS build would only report null and could not run as a service. build-macos stays rkd-terminal only; install.sh refuses rkd-activity on Darwin with that reason.
  • Installer: shared, not copied. install.sh takes the plugin as its first argument (default rkd-terminal, so the existing one-liner is unchanged; terminal/activity shorthands accepted, anything else refused). All guarantees are the same code path: https only, sha256 verified (fail closed without a tool), no sudo, refuses root, refuses a bin dir others can write, atomic rename, runs <plugin> install. Settings are per plugin: RKD_ACTIVITY_VERSION / _BIN / _NO_SERVICE / _BASE_URL / _INSECURE_TEST; the RKD_TERMINAL_* ones do not leak into rkd-activity. The prefix comes from a fixed case list, so the eval that reads ${VAR}_NAME only ever sees literals. Asking for a release older than rkd-activity says so instead of a bare download error.
  • CI: the existing install-script job runs scripts/test-install.sh, which now covers rkd-activity too (no workflow step change needed, comment updated). test-release.sh gains workspace-version guard cases and package-release.sh cases for both plugins.
  • Docs: local/README.md's "build from source" note becomes the one-line install (source build kept as the fallback); root README gets the rkd-activity install line and a refreshed status table.

Test plan

Automated:

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets --locked -- -D warnings (host, aarch64-apple-darwin)
  • cargo clippy --target x86_64-pc-windows-msvc --workspace --all-targets --locked -- -D warnings
  • cargo test --workspace --locked passes locally
  • REQUIRE_SHELLCHECK=1 dash scripts/test-install.sh and under sh — all checks pass (31 new checks for rkd-activity and plugin selection: install, activity shorthand, aarch64, pinned version, other plugin's version ignored, no-service, custom bin with a space, macOS refused, riscv refused with cargo hint, root refused, http refused, other plugin's insecure switch ignored, bad checksum, release without an activity build, archive holding the wrong binary, unknown plugin)
  • REQUIRE_SHELLCHECK=1 sh scripts/test-release.sh — all checks pass; shellcheck -s sh install.sh scripts/*.sh clean
  • Added or updated tests covering the change; hand-applied mutations went red: rkd-activity reading RKD_TERMINAL_* (24 failures), allowing rkd-activity on Darwin, dropping the guard's per-crate check, packaging under a fixed rkd-terminal name
  • release-guard.sh v0.5.0 HEAD HEAD passes on this tree, v0.6.0 is refused (version mismatch)

Manual:

  • End to end: real release builds → package-release.sh → local fake release dir → install.sh rkd-activity → binary installed, identical to the build

Review checklist

  • No console.log / dbg! / commented-out code left behind
  • No secrets, tokens, or personal URLs added
  • CLAUDE.md / README updated if behaviour or commands changed

Migrations and breaking changes

  • Bumps a version: rkd-activity 0.1.0 → 0.5.0 via the shared workspace version (rkd-terminal and rkd-local-link stay 0.5.0). No wire change; test-vectors.json's activity hello example still says "version":"0.1.0", which is sample data, not asserted against the crate.

Notes for the reviewer

Not done on purpose: no tag or release (v0.6.0 is yours: bump [workspace.package] version to 0.6.0, merge, tag the merge on main); systemd hardening stays deferred per the issue. Unverified until the first tag: the release workflow's real run (zigbuild of rkd-activity for aarch64 musl in particular; rkd-activity has the same dependency set as rkd-terminal minus portable-pty, so it should link the same way). The release-guard refuses any future local/* crate that sets its own version, which is the point but also means a new plugin must use version.workspace = true.

https://claude.ai/code/session_01S6WwLMTpMtw1RuCgBY8JGt

## Summary rkd-activity merged in #6 but users could only get it with a Rust toolchain: the release pipeline and install.sh only knew rkd-terminal. This makes a release build and attach rkd-activity for Linux, lets the same install.sh install it (`… | sh -s -- rkd-activity`), and puts every crate on one workspace version so the next tag (v0.6.0) releases rkd-activity with the rest. No tag is pushed here; cutting v0.6.0 is the owner's call. Refs nanoya-biz/rkd#1143 ## Type of change - [x] New feature - [x] Build, CI, or tooling - [x] Docs ## Screenshots / recording Tooling change, so the pair is the installer's output. Same command, same fake v0.6.0 release (built with this branch's `package-release.sh` from real host builds of both plugins, served as `file://` through `RKD_*_BASE_URL` + `RKD_*_INSECURE_TEST=1`), `uname` faked to Linux x86_64, `*_NO_SERVICE=1`. BEFORE runs `git show origin/main:install.sh`; AFTER runs this branch's. **BEFORE — origin/main: `install.sh | sh -s -- rkd-activity` ignores the argument and installs rkd-terminal** ``` rkd-terminal: warning: downloading from file://<tmp>/srv (RKD_TERMINAL_BASE_URL), not https://git.rkd.nanoya.biz rkd-terminal: downloading rkd-terminal-v0.6.0-x86_64-unknown-linux-musl rkd-terminal: installed v0.6.0 to <tmp>/home-before/.local/bin/rkd-terminal rkd-terminal: not installing the service (RKD_TERMINAL_NO_SERVICE=1), so nothing is running yet. -- ~/.local/bin: rkd-terminal ``` **AFTER — this PR: the same command installs rkd-activity, with its own settings** ``` rkd-activity: warning: downloading from file://<tmp>/srv (RKD_ACTIVITY_BASE_URL), not https://git.rkd.nanoya.biz rkd-activity: downloading rkd-activity-v0.6.0-x86_64-unknown-linux-musl rkd-activity: installed v0.6.0 to <tmp>/home-after/.local/bin/rkd-activity rkd-activity: not installing the service (RKD_ACTIVITY_NO_SERVICE=1), so nothing is running yet. rkd-activity: next: start it, with `rkd-activity serve` (in the foreground) or `rkd-activity install` (as a service), then run `rkd-activity pair` and enter the code in RKD → Settings → Plugins on this device. -- ~/.local/bin: rkd-activity ``` The installed binary is byte-identical (`cmp`) to the `cargo build --release` output it was packaged from. The release workflow itself only runs on a tag, so there is no before/after of a real release run. ## What changed - **Versioning (decided): one version for every crate.** `[workspace.package] version = "0.5.0"`, each crate `version.workspace = true`; rkd-activity goes 0.1.0 → 0.5.0 (Cargo.lock updated). A tag `vX.Y.Z` releases all plugins at X.Y.Z, so v0.6.0 bumps rkd-activity too. `release-guard.sh` now checks the tag against the workspace version and refuses any `local/*` crate that sets its own. Written down in local/README.md's new *Releases* section and the root README's "Adding a plugin" step 4. - **Release:** `build-linux` builds `-p rkd-terminal -p rkd-activity` in one zigbuild per target and packages + static-checks both; `package-release.sh` takes the plugin from the binary's file name (only `rkd-terminal`/`rkd-activity` accepted). Assets: `rkd-activity-<tag>-{x86_64,aarch64}-unknown-linux-musl.tar.gz` + `.sha256`. - **macOS: not shipped (decided).** rkd-activity detects nothing on macOS and `rkd-activity install` bails there (`LINUX_ONLY`), so a macOS build would only report null and could not run as a service. `build-macos` stays rkd-terminal only; install.sh refuses rkd-activity on Darwin with that reason. - **Installer: shared, not copied.** install.sh takes the plugin as its first argument (default rkd-terminal, so the existing one-liner is unchanged; `terminal`/`activity` shorthands accepted, anything else refused). All guarantees are the same code path: https only, sha256 verified (fail closed without a tool), no sudo, refuses root, refuses a bin dir others can write, atomic rename, runs `<plugin> install`. Settings are per plugin: `RKD_ACTIVITY_VERSION` / `_BIN` / `_NO_SERVICE` / `_BASE_URL` / `_INSECURE_TEST`; the `RKD_TERMINAL_*` ones do not leak into rkd-activity. The prefix comes from a fixed case list, so the `eval` that reads `${VAR}_NAME` only ever sees literals. Asking for a release older than rkd-activity says so instead of a bare download error. - **CI:** the existing `install-script` job runs `scripts/test-install.sh`, which now covers rkd-activity too (no workflow step change needed, comment updated). `test-release.sh` gains workspace-version guard cases and `package-release.sh` cases for both plugins. - **Docs:** local/README.md's "build from source" note becomes the one-line install (source build kept as the fallback); root README gets the rkd-activity install line and a refreshed status table. ## Test plan Automated: - [x] `cargo fmt --all --check` - [x] `cargo clippy --workspace --all-targets --locked -- -D warnings` (host, aarch64-apple-darwin) - [x] `cargo clippy --target x86_64-pc-windows-msvc --workspace --all-targets --locked -- -D warnings` - [x] `cargo test --workspace --locked` passes locally - [x] `REQUIRE_SHELLCHECK=1 dash scripts/test-install.sh` and under `sh` — all checks pass (31 new checks for rkd-activity and plugin selection: install, `activity` shorthand, aarch64, pinned version, other plugin's version ignored, no-service, custom bin with a space, macOS refused, riscv refused with cargo hint, root refused, http refused, other plugin's insecure switch ignored, bad checksum, release without an activity build, archive holding the wrong binary, unknown plugin) - [x] `REQUIRE_SHELLCHECK=1 sh scripts/test-release.sh` — all checks pass; `shellcheck -s sh install.sh scripts/*.sh` clean - [x] Added or updated tests covering the change; hand-applied mutations went red: rkd-activity reading `RKD_TERMINAL_*` (24 failures), allowing rkd-activity on Darwin, dropping the guard's per-crate check, packaging under a fixed `rkd-terminal` name - [x] `release-guard.sh v0.5.0 HEAD HEAD` passes on this tree, `v0.6.0` is refused (version mismatch) Manual: - [x] End to end: real release builds → `package-release.sh` → local fake release dir → `install.sh rkd-activity` → binary installed, identical to the build ## Review checklist - [x] No `console.log` / `dbg!` / commented-out code left behind - [x] No secrets, tokens, or personal URLs added - [x] CLAUDE.md / README updated if behaviour or commands changed ## Migrations and breaking changes - [x] Bumps a version: rkd-activity 0.1.0 → 0.5.0 via the shared workspace version (rkd-terminal and rkd-local-link stay 0.5.0). No wire change; `test-vectors.json`'s activity `hello` example still says `"version":"0.1.0"`, which is sample data, not asserted against the crate. ## Notes for the reviewer Not done on purpose: no tag or release (v0.6.0 is yours: bump `[workspace.package] version` to 0.6.0, merge, tag the merge on main); systemd hardening stays deferred per the issue. Unverified until the first tag: the release workflow's real run (zigbuild of rkd-activity for aarch64 musl in particular; rkd-activity has the same dependency set as rkd-terminal minus portable-pty, so it should link the same way). The `release-guard` refuses any future `local/*` crate that sets its own version, which is the point but also means a new plugin must use `version.workspace = true`. https://claude.ai/code/session_01S6WwLMTpMtw1RuCgBY8JGt
Every crate takes [workspace.package] version, and the release guard
checks the tag against that and refuses a crate with a version of its
own. One tag then names one build of every plugin, so install.sh only
has to find one release. rkd-activity moves from 0.1.0 to 0.5.0 with
the others; v0.6.0 will be its first release.

Refs nanoya-biz/rkd#1143

Claude-Session: https://claude.ai/code/session_01S6WwLMTpMtw1RuCgBY8JGt
The Linux jobs build rkd-activity next to rkd-terminal and attach its
archives and .sha256. package-release.sh takes the plugin from the
binary's name. No macOS build: rkd-activity detects nothing there and
cannot install its service (ADR-0005).

Refs nanoya-biz/rkd#1143

Claude-Session: https://claude.ai/code/session_01S6WwLMTpMtw1RuCgBY8JGt
feat(install): install.sh installs rkd-activity (#1143)
All checks were successful
CI / install-script (pull_request) Successful in 14s
CI / windows-check (pull_request) Successful in 23s
CI / rust (pull_request) Successful in 36s
5951d30d94
`install.sh | sh -s -- rkd-activity` installs rkd-activity with the
same guarantees as rkd-terminal (https only, sha256 checked, no sudo,
refuses root, runs `install`), one script rather than a copy. Settings
are per plugin (RKD_ACTIVITY_*), picked from a fixed list so nothing
the caller passes reaches a URL or the eval. macOS is refused for
rkd-activity. The READMEs drop the build-from-source note and write
down the versioning.

Refs nanoya-biz/rkd#1143

Claude-Session: https://claude.ai/code/session_01S6WwLMTpMtw1RuCgBY8JGt
docs(install): name the per-plugin insecure-test switch (#1143)
All checks were successful
CI / rust (pull_request) Successful in 34s
CI / install-script (pull_request) Successful in 13s
CI / windows-check (pull_request) Successful in 23s
970c4cd0ca
The HTTPS-only comment still named RKD_TERMINAL_INSECURE_TEST alone,
though the switch is now per plugin and the terminal's does not unlock
rkd-activity. Also reflow the CI harness comment left half-wrapped.

Claude-Session: https://claude.ai/code/session_01S6WwLMTpMtw1RuCgBY8JGt
dozken merged commit a659c877ba into main 2026-09-25 15:26:54 +02:00
dozken deleted branch feat/1143-plugins-release-and-install-rkd-activity-pa 2026-09-25 15:26:54 +02:00
dozken referenced this pull request from a commit 2026-09-25 15:29:47 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rkd/plugins!7
No description provided.