Skip to content

Set up crates.io + binary releases: publish-on-tag workflow#2

Merged
saucam merged 1 commit into
mainfrom
chore/release-crates
Jun 23, 2026
Merged

Set up crates.io + binary releases: publish-on-tag workflow#2
saucam merged 1 commit into
mainfrom
chore/release-crates

Conversation

@saucam

@saucam saucam commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Second half of release setup (the Rust client). Pairs with codeoid's npm release (saucam/codeoid#20).

What this adds

  • .github/workflows/release.yml — on a vX.Y.Z tag:
    • crates.io: publish codeoid-protocolcodeoid-clientcodeoid-tui in dependency order (cargo waits for each to index).
    • binaries: build codeoid-tui on native runners and upload tarballs for macOS arm64 + x64 and Linux x64 to a GitHub Release.
  • Cargo metadata fixes (required + polish):
    • repository URL corrected (codeoid/codeoid-uisaucam/codeoid-ui).
    • internal path-deps pinned to version = "0.1.0"required for crates.io.
    • homepage + keywords for the crates.io listing.
  • CHANGELOG.md (0.1.0) + RELEASING.md runbook.

To cut the release (after merge)

  1. Add a CARGO_REGISTRY_TOKEN repo secret (crates.io API token; binaries use the built-in GITHUB_TOKEN).
  2. git tag v0.1.0 && git push origin v0.1.0cargo install codeoid-tui + downloadable binaries.

Validated: cargo check + cargo publish --dry-run -p codeoid-protocol pass; Cargo.lock is untouched so the --locked CI build holds.

🤖 Generated with Claude Code

- Cargo.toml: fix repository URL (codeoid -> saucam org), add homepage +
  keywords for crates.io, and pin the internal path-deps to version "0.1.0"
  (required for crates.io publishing). Crates inherit homepage/keywords.
- .github/workflows/release.yml: on a v* tag,
  (1) publish codeoid-protocol -> codeoid-client -> codeoid-tui to crates.io in
      dependency order (cargo waits for each to index), and
  (2) build + upload codeoid-tui binaries for macOS arm64/x64 + Linux x64 to a
      GitHub Release.
- CHANGELOG.md (0.1.0) + RELEASING.md runbook (add CARGO_REGISTRY_TOKEN, tag).

Validated: cargo check + `cargo publish --dry-run -p codeoid-protocol` pass;
downstream crates can only resolve once protocol is on crates.io, which the
workflow ordering handles.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@saucam saucam merged commit ac5ee60 into main Jun 23, 2026
1 check passed
@saucam saucam deleted the chore/release-crates branch June 23, 2026 01:48
@saucam saucam mentioned this pull request Jun 23, 2026
saucam added a commit that referenced this pull request Jul 11, 2026
…r path

Coverage top-up #2 for the input-safety PR (84% → ~91% patch):

- the reconnect backoff unit is injectable (1s in production, ms in
  tests), and event_loop/reconnect_with_backoff are generic over the
  render backend + terminal-event stream — the full 5-attempt budget
  path and the quit-during-backoff path now run in CI against a dead
  port on a TestBackend (a stray key is asserted DISCARDED, q quits).
- the reader task's cancel-pending guard moved to module scope with a
  direct drop test (it also covers panic unwinds, which no exit-point
  call could).
- ClientHandle::detached_for_tests() (doc-hidden) lets the TUI exercise
  request/error paths without a daemon — used to pin "/destroy failed:"
  surfacing when the socket dies mid-request.

Remaining uncovered lines are the live-connection plumbing (run()'s
outer reconnect loop, the reconnect success arm, destroy's post-success
list refresh) — coverable only with a real WS handshake fixture.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
saucam added a commit that referenced this pull request Jul 11, 2026
…troy confirm (#18)

* fix: never wedge or eat input — request timeouts, prompt restore, destroy confirm

Four input-safety fixes for the TUI, all traced from a codebase audit:

- requests are now bounded: `ClientHandle::request` times out after 30s
  (RequestTimeout) and a reader-task Drop guard cancels every pending
  request the moment the socket dies (RequestCancelled) — previously a
  `/fork` or `/provider` awaited inside the event loop could freeze the
  UI forever if the daemon died mid-request, recoverable only by kill -9.
- the reconnect backoff now drains terminal input: `q`/Ctrl+C quit during
  the ~31s backoff window (previously the keyboard was dead the whole
  time) and stray keystrokes are discarded instead of replaying into the
  prompt after reconnect.
- a slash-command typo or a send with no session no longer destroys the
  prompt text — the draft is restored alongside the error.
- `/destroy` now opens the (previously built but unreachable)
  ConfirmDestroy modal: `y` destroys — surfacing daemon rejections
  instead of silently pretending — `n`/Esc cancel, everything else is
  absorbed so a stray key can't confirm.
- the documented `m` cycle-mode key actually works now (was a silent
  no-op): interactive → guarded → autonomous, starting at interactive
  when the mode is unknown.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: cover the request-wrapper and reducer guard branches

Patch-coverage top-up for the input-safety changes: the production
request() delegation (answered-in-time path), the Action::CycleMode
reducer arm, and the /destroy no-session guard.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: cover the reconnect backoff, reader drop guard, and destroy error path

Coverage top-up #2 for the input-safety PR (84% → ~91% patch):

- the reconnect backoff unit is injectable (1s in production, ms in
  tests), and event_loop/reconnect_with_backoff are generic over the
  render backend + terminal-event stream — the full 5-attempt budget
  path and the quit-during-backoff path now run in CI against a dead
  port on a TestBackend (a stray key is asserted DISCARDED, q quits).
- the reader task's cancel-pending guard moved to module scope with a
  direct drop test (it also covers panic unwinds, which no exit-point
  call could).
- ClientHandle::detached_for_tests() (doc-hidden) lets the TUI exercise
  request/error paths without a daemon — used to pin "/destroy failed:"
  surfacing when the socket dies mid-request.

Remaining uncovered lines are the live-connection plumbing (run()'s
outer reconnect loop, the reconnect success arm, destroy's post-success
list refresh) — coverable only with a real WS handshake fixture.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <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