From edafe187a95f7467b4200275d92ce8094aec7ac7 Mon Sep 17 00:00:00 2001 From: Yash Datta Date: Tue, 23 Jun 2026 09:47:24 +0800 Subject: [PATCH] Set up crates.io + binary releases: publish-on-tag workflow - 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) --- .github/workflows/release.yml | 79 ++++++++++++++++++++++++++++++ CHANGELOG.md | 25 ++++++++++ Cargo.toml | 8 +-- RELEASING.md | 47 ++++++++++++++++++ crates/codeoid-client/Cargo.toml | 2 + crates/codeoid-protocol/Cargo.toml | 2 + crates/codeoid-tui/Cargo.toml | 2 + 7 files changed, 162 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 CHANGELOG.md create mode 100644 RELEASING.md diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..9acc285 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,79 @@ +name: Release + +on: + push: + tags: ["v*"] + +permissions: + contents: write # create the GitHub Release + upload assets + +env: + CARGO_TERM_COLOR: always + +jobs: + crates: + name: Publish to crates.io + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Verify workspace version matches the tag + run: | + VER="$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')" + TAG="${GITHUB_REF_NAME#v}" + if [ "$VER" != "$TAG" ]; then + echo "::error::workspace version ($VER) does not match tag ($TAG)" + exit 1 + fi + + # Dependency order; modern cargo waits for each crate to index before returning. + - name: Publish crates + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + run: | + cargo publish -p codeoid-protocol + cargo publish -p codeoid-client + cargo publish -p codeoid-tui + + binaries: + name: Binary (${{ matrix.target }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - { os: ubuntu-latest, target: x86_64-unknown-linux-gnu } + - { os: macos-latest, target: aarch64-apple-darwin } + - { os: macos-13, target: x86_64-apple-darwin } + steps: + - uses: actions/checkout@v4 + + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.target }} + + - name: Cache cargo build + uses: Swatinem/rust-cache@v2 + + - name: Build codeoid-tui + run: cargo build --release -p codeoid-tui --target ${{ matrix.target }} + + - name: Package tarball + shell: bash + run: | + DIR="codeoid-tui-${GITHUB_REF_NAME}-${{ matrix.target }}" + mkdir "$DIR" + cp "target/${{ matrix.target }}/release/codeoid-tui" "$DIR/" + cp README.md LICENSE "$DIR/" 2>/dev/null || true + tar -czf "${DIR}.tar.gz" "$DIR" + echo "ASSET=${DIR}.tar.gz" >> "$GITHUB_ENV" + + - name: Upload to GitHub Release + uses: softprops/action-gh-release@v2 + with: + files: ${{ env.ASSET }} + generate_release_notes: true diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..63dd7f0 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,25 @@ +# Changelog + +All notable changes to **codeoid-ui** (the native Rust client for Codeoid) are +documented here. Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); +versioning: [SemVer](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.1.0] - 2026-06-23 + +Initial public release. + +### Added + +- **`codeoid-tui`** — a native [Ratatui](https://ratatui.rs) terminal cockpit for + the Codeoid daemon: a true cell-matrix framebuffer, so it stays jitter-free + under high-frequency streaming deltas. +- **`codeoid-client`** — async WebSocket client (auth handshake, request/response + correlation, and the unsolicited event stream). +- **`codeoid-protocol`** — serde-compatible Rust port of the daemon's wire + protocol; `PROTOCOL_VERSION` is negotiated on connect so client and daemon + versions can move independently. + +[Unreleased]: https://github.com/saucam/codeoid-ui/compare/v0.1.0...HEAD +[0.1.0]: https://github.com/saucam/codeoid-ui/releases/tag/v0.1.0 diff --git a/Cargo.toml b/Cargo.toml index 722638a..f6b764d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,12 +12,14 @@ edition = "2021" rust-version = "1.85" license = "MIT" authors = ["Codeoid "] -repository = "https://github.com/codeoid/codeoid-ui" +repository = "https://github.com/saucam/codeoid-ui" +homepage = "https://github.com/saucam/codeoid-ui" +keywords = ["codeoid", "claude", "tui", "ai-agents", "ratatui"] [workspace.dependencies] # Workspace-internal -codeoid-protocol = { path = "crates/codeoid-protocol" } -codeoid-client = { path = "crates/codeoid-client" } +codeoid-protocol = { path = "crates/codeoid-protocol", version = "0.1.0" } +codeoid-client = { path = "crates/codeoid-client", version = "0.1.0" } # Async runtime tokio = { version = "1.41", features = ["macros", "rt-multi-thread", "sync", "time", "signal", "io-std", "io-util"] } diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..24933c9 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,47 @@ +# Releasing codeoid-ui + +Pushing a `vX.Y.Z` tag publishes the three crates to crates.io and attaches +prebuilt `codeoid-tui` binaries to a GitHub Release — see +[`.github/workflows/release.yml`](.github/workflows/release.yml). + +## One-time setup + +Add a **`CARGO_REGISTRY_TOKEN`** repository secret (Settings → Secrets and +variables → Actions): crates.io → Account Settings → **API Tokens** → new token +scoped to publish. + +(Binary uploads need no extra secret — they use the built-in `GITHUB_TOKEN`.) + +## Cutting a release + +1. Bump the version in [`Cargo.toml`](Cargo.toml): `[workspace.package].version` + **and** the `version = "X.Y.Z"` on the internal path-deps in + `[workspace.dependencies]` (they must match for crates.io). +2. Move the `## [Unreleased]` notes into a new `## [X.Y.Z]` section in + [`CHANGELOG.md`](CHANGELOG.md). +3. Open a PR, get CI green, merge to `main`. +4. Tag from `main` and push (tags are not branch-protected): + + ```bash + git checkout main && git pull + git tag vX.Y.Z && git push origin vX.Y.Z + ``` + +The workflow publishes `codeoid-protocol` → `codeoid-client` → `codeoid-tui` +(in dependency order; cargo waits for each to index) and uploads macOS +(arm64 / x64) and Linux (x64) binaries. Install with: + +```bash +cargo install codeoid-tui # from crates.io +# or download a prebuilt binary from the GitHub Release +``` + +## Notes + +- The **wire protocol** version (`PROTOCOL_VERSION` in `codeoid-protocol`) is + independent of the crate version — bump it only on wire-breaking changes, and + keep it in lockstep with the daemon's `src/protocol/types.ts` in + [codeoid](https://github.com/saucam/codeoid). The handshake negotiates + compatibility, so app versions and the protocol version move independently. +- Both internal crates must be published before `codeoid-tui`; the workflow + handles the ordering. diff --git a/crates/codeoid-client/Cargo.toml b/crates/codeoid-client/Cargo.toml index 75acc6d..1929082 100644 --- a/crates/codeoid-client/Cargo.toml +++ b/crates/codeoid-client/Cargo.toml @@ -6,6 +6,8 @@ rust-version.workspace = true license.workspace = true authors.workspace = true repository.workspace = true +homepage.workspace = true +keywords.workspace = true description = "Async WebSocket client for the Codeoid daemon. Handles auth handshake, request/response correlation, and the unsolicited event stream." [dependencies] diff --git a/crates/codeoid-protocol/Cargo.toml b/crates/codeoid-protocol/Cargo.toml index a717e03..6f792d3 100644 --- a/crates/codeoid-protocol/Cargo.toml +++ b/crates/codeoid-protocol/Cargo.toml @@ -6,6 +6,8 @@ rust-version.workspace = true license.workspace = true authors.workspace = true repository.workspace = true +homepage.workspace = true +keywords.workspace = true description = "Wire protocol types for the Codeoid daemon — serde-compatible Rust port of src/protocol/types.ts." [dependencies] diff --git a/crates/codeoid-tui/Cargo.toml b/crates/codeoid-tui/Cargo.toml index 5ed3483..fa87f4b 100644 --- a/crates/codeoid-tui/Cargo.toml +++ b/crates/codeoid-tui/Cargo.toml @@ -6,6 +6,8 @@ rust-version.workspace = true license.workspace = true authors.workspace = true repository.workspace = true +homepage.workspace = true +keywords.workspace = true description = "Ratatui-based terminal cockpit for the Codeoid daemon." [[bin]]