diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..8e0f629 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,47 @@ +name: Publish + +on: + push: + tags: + - "v*" + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: publish-${{ github.ref }} + cancel-in-progress: false + +env: + CARGO_INCREMENTAL: "0" + CARGO_TERM_COLOR: always + +jobs: + publish: + name: Publish to crates.io + runs-on: ubuntu-latest + timeout-minutes: 45 + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup-rust + with: + toolchain: stable + - name: Verify tag matches Cargo.toml + if: startsWith(github.ref, 'refs/tags/') + run: | + version=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1) + tag="${GITHUB_REF_NAME#v}" + if [[ "$tag" != "$version" ]]; then + echo "Tag $GITHUB_REF_NAME does not match Cargo.toml version $version" >&2 + exit 1 + fi + - uses: rust-lang/crates-io-auth-action@v1 + id: auth + - name: Publish + run: cargo publish --locked + env: + CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9f5c87a..5672784 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -91,6 +91,50 @@ cargo bench --bench timer_drift Use benchmark results to evaluate a measured media-path change; do not treat a single machine's timing as a portable SDK guarantee. +## Publishing + +The crate name on crates.io is [`getstream`](https://crates.io/crates/getstream). +There is no `stream/` org prefix — ownership is whichever crates.io accounts +(and optional GitHub teams) you add as owners. + +### First publish (local) + +1. Sign in to [crates.io](https://crates.io) with GitHub. +2. Create a token at [crates.io/settings/tokens](https://crates.io/settings/tokens) + with the `publish-new` scope, then run `cargo login` and paste it. +3. From a clean checkout of the release commit: + + ```bash + cargo publish --locked --dry-run + cargo publish --locked + ``` + +4. On the crate's crates.io settings page, add other Stream maintainers as + owners (`cargo owner --add `). If the GetStream GitHub org + has authorized crates.io, you can also add a team with + `cargo owner --add github:GetStream:`. + +A version can never be overwritten. To pull a broken release from new +downloads, use `cargo yank --version `. + +### Later releases (GitHub Actions) + +After the crate exists, configure Trusted Publishing on the crate settings +page: repository `GetStream/stream-video-rust`, workflow `publish.yml`, no +environment. That lets GitHub Actions publish without storing a crates.io +token. + +Bump `version` in `Cargo.toml`, merge to `main`, then tag the same value: + +```bash +# Cargo.toml version is 0.1.0-preview.1 → tag v0.1.0-preview.1 +git tag -a v0.1.0-preview.1 -m "v0.1.0-preview.1" +git push origin v0.1.0-preview.1 +``` + +The [Publish](.github/workflows/publish.yml) workflow verifies the tag matches +`Cargo.toml` and runs `cargo publish --locked`. + ## Pull requests - Keep changes focused and include tests for observable behavior. diff --git a/Cargo.toml b/Cargo.toml index 3b23f6d..78ed565 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,9 @@ name = "getstream" version = "0.1.0-preview.1" edition = "2024" rust-version = "1.88" +authors = ["Stream.io, Inc. "] license-file = "LICENSE" -description = "Rust SDK for Stream Video (server REST + SFU WebRTC)." +description = "Official Rust SDK for Stream Video (server REST + SFU WebRTC)." readme = "README.md" repository = "https://github.com/GetStream/stream-video-rust" homepage = "https://getstream.io/video/" @@ -27,11 +28,13 @@ include = [ ] [package.metadata.docs.rs] -# docs.rs builds the full native media stack: its build image ships libvpx-dev, -# cmake, clang, and pkg-config, which is everything `env-libvpx-sys` (system -# libvpx via pkg-config + bindgen) and `opusic-sys` (vendored libopus via CMake) -# need. The crate has no Cargo features, so nothing else to select here. -rustdoc-args = ["--cfg", "docsrs"] +# docs.rs uses rust-lang/crates-build-env, which ships libvpx-dev, cmake, clang, +# and pkg-config — everything `env-libvpx-sys` (system libvpx via pkg-config + +# bindgen) and `opusic-sys` (vendored libopus via CMake) need. Restrict to the +# Linux gnu target: the default extra targets (Windows/macOS) are cross-built +# and cannot discover a system libvpx. The crate has no Cargo features. +targets = ["x86_64-unknown-linux-gnu"] +rustdoc-args = ["--cfg", "docsrs", "--generate-link-to-definition"] # WebRTC (SFU join/publish/subscribe/media) is the core purpose of this SDK, so # the RTC stack is always compiled in — there is no `webrtc` Cargo feature. A diff --git a/README.md b/README.md index 48e5ca5..c983263 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 🦀 Official Rust SDK for [Stream Video](https://getstream.io/video/) +# 🦀 Official Rust SDK for [Stream Video](https://getstream.io/video/) (Preview) [![crates.io](https://img.shields.io/crates/v/getstream.svg)](https://crates.io/crates/getstream) [![docs.rs](https://img.shields.io/docsrs/getstream)](https://docs.rs/getstream) @@ -41,6 +41,24 @@ remote audio and video, transform it, and publish media back into the call. video bitrate, and control SFU-side noise cancellation. - Emit structured, secret-redacted diagnostics through `tracing`. +## Crate map + +crates.io has no organization namespace. This package is Stream's official +Rust crate, published as [`getstream`](https://crates.io/crates/getstream). + +| Item | Role | +| --- | --- | +| [`Stream`](https://docs.rs/getstream/latest/getstream/struct.Stream.html) | Server client: users, tokens, and webhook verification | +| [`Call`](https://docs.rs/getstream/latest/getstream/struct.Call.html) / [`VideoClient`](https://docs.rs/getstream/latest/getstream/struct.VideoClient.html) | Video REST and `Call::join` | +| [`rtc`](https://docs.rs/getstream/latest/getstream/rtc/index.html) | SFU participant, local/remote tracks, and PCM utilities | +| [`models`](https://docs.rs/getstream/latest/getstream/models/index.html) | REST request and response types | +| [`ClientConfig`](https://docs.rs/getstream/latest/getstream/struct.ClientConfig.html) | HTTP timeouts, retries, and payload limits | +| [`webhook`](https://docs.rs/getstream/latest/getstream/webhook/index.html) | Signature verification and typed events | + +The wire-level `rtc` transport modules (`proto`, `peer`, `sfu_ws`, `signal`, +`publisher`, `tracer`, `coordinator_ws`) are public because they track Stream's +SFU protocol, but they are exempt from compatibility guarantees. + ## Requirements The WebRTC media stack is part of every build. Install Rust 1.88 or newer, a C @@ -60,22 +78,25 @@ sudo apt install libvpx-dev cmake pkg-config build-essential ## Installation ```bash -cargo add getstream tokio tracing +cargo add getstream@0.1.0-preview.1 tokio tracing ``` Or in `Cargo.toml`: ```toml [dependencies] -getstream = "0.1" +getstream = "0.1.0-preview.1" tokio = { version = "1", features = ["macros", "rt-multi-thread", "signal"] } tracing = "0.1" ``` +`getstream = "0.1"` will not match this preview. Cargo only selects a pre-release +when the version requirement includes one. + The API reference is published at [docs.rs/getstream](https://docs.rs/getstream); from a checkout, generate it locally with `cargo doc --open`. -While the crate is `0.x`, minor releases may contain breaking changes. The +This is a `0.x` preview, so minor releases may contain breaking changes. The wire-level `rtc` transport modules (`proto`, `peer`, `sfu_ws`, `signal`, `publisher`, `tracer`, `coordinator_ws`) track Stream's SFU protocol directly and are exempt from compatibility guarantees at any version bump. diff --git a/src/client.rs b/src/client.rs index 324a4b4..c0c2a05 100644 --- a/src/client.rs +++ b/src/client.rs @@ -4,6 +4,10 @@ //! timeout, 30s request timeout, 10s connect timeout. Requests are authenticated //! with a server JWT (`{"server": true}`) sent as `Authorization` + //! `Stream-Auth-Type: jwt`, and every request carries the `api_key` query param. +//! +//! The HTTP client itself is crate-private. Public tunables ([`ClientConfig`], +//! [`RetryConfig`], [`NetworkLimits`]) are re-exported at the crate root for +//! [`crate::Stream::with_config`]. use std::time::{Duration, SystemTime, UNIX_EPOCH}; diff --git a/src/lib.rs b/src/lib.rs index 1b8a44b..fa2d92e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,8 @@ #![doc = include_str!("../README.md")] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/8597527?s=32&v=4")] +#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/8597527?s=128&v=4")] +#![doc(issue_tracker_base_url = "https://github.com/GetStream/stream-video-rust/issues/")] pub mod client; pub mod error; @@ -10,10 +14,16 @@ pub mod webhook; use std::sync::Arc; -use client::{Client, ClientConfig, NetworkLimits}; +use client::Client; +#[doc(inline)] +pub use client::{ClientConfig, DEFAULT_BASE_URL, NetworkLimits, RetryConfig}; +#[doc(inline)] pub use error::{ApiError, Error, Result, TokenError, WebhookError}; +#[doc(inline)] pub use token::{TokenClaims, TokenOptions}; +#[doc(inline)] pub use video::{Call, VideoClient}; +#[doc(inline)] pub use webhook::{WebhookEvent, parse_event, verify_signature}; /// Environment variable holding the Stream API key.