Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: CI

on:
push:
branches: [main]
pull_request:

permissions:
contents: read

env:
CARGO_TERM_COLOR: always
RUSTFLAGS: -D warnings

jobs:
fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: cargo fmt --check

clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --all-features --all-targets -- -D warnings
- run: cargo clippy --no-default-features --all-targets -- -D warnings

test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
toolchain: [stable, "1.85"]
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.toolchain }}
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@nextest
- run: cargo nextest run --all-features
# nextest does not run doctests; the README compiles here.
- run: cargo test --all-features --doc

features:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo check --no-default-features
- run: cargo check --no-default-features --features oauth
- run: cargo check --no-default-features --features tracing
- run: cargo check --all-features
- run: cargo check --no-default-features --features native-tls

wasm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
- run: cargo check --target wasm32-unknown-unknown
Comment thread
Zingzy marked this conversation as resolved.
Resolved
# getrandom's wasm backend is chosen by the final binary via RUSTFLAGS;
# this check builds the way a wasm consumer of the oauth feature must.
- run: cargo check --target wasm32-unknown-unknown --features oauth
env:
RUSTFLAGS: -D warnings --cfg getrandom_backend="wasm_js"

docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo doc --all-features --no-deps
env:
RUSTDOCFLAGS: -D warnings

deny:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: EmbarkStudios/cargo-deny-action@v2

semver:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: obi1kenobi/cargo-semver-checks-action@v2
with:
feature-group: all-features

spec-drift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Compare committed openapi.json with the backend's
run: |
curl -fsSL https://raw.githubusercontent.com/spoo-me/spoo/main/openapi.json -o upstream-openapi.json
diff -q openapi.json upstream-openapi.json
28 changes: 28 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Release

# Publishes to crates.io via Trusted Publishing (OIDC) when a GitHub
# release is published. Requires the crates.io trusted-publisher
# configuration for this repository.
on:
release:
types: [published]

permissions:
contents: read

jobs:
publish:
runs-on: ubuntu-latest
environment: release
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- run: cargo test --all-features
- uses: rust-lang/crates-io-auth-action@v1
id: auth
- run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
/target
Cargo.lock
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Changelog

## 0.2.0 (unreleased)

Rewrite against the spoo.me v1 API. Every endpoint the 0.1.x crate called
was removed in the platform's v1 overhaul, so this is a clean break; see
MIGRATION.md. The design language of the original crate by
[rdni](https://github.com/rdni) carries over: consuming builders, layered
errors, documentation on every public item.

- v1 coverage: shorten (alphanumeric and emoji aliases), alias check, link
management (list/get/get-by-address/update/set-status/delete), bulk
delete/status/expiry/domain, claiming anonymous links, account and
per-link statistics, streaming exports, public stats and previews, the
emoji catalogue (ETag-cached), identity read.
- Authentication: API keys, anonymous mode, and Sign in with Spoo behind
the `oauth` feature (PKCE, device-code exchange, self-refreshing
single-flight sessions).
- Tri-state PATCH updates: untouched fields keep their stored values,
`remove_*` methods clear a setting explicitly.
- Typed errors with the backend's machine-readable codes, rate-limit
metadata, and predicates (`is_not_found`, `is_rate_limited`,
`is_blocked`, `is_password_required`).
- Automatic retries with jittered backoff capped at 8 seconds, honoring
both legal `Retry-After` forms; POST and PATCH replay only where the
server provably did no work.
- Server-suggested export filenames are sanitized to safe bare names.
- Raw typed passthroughs (`client.get/post/patch/delete`) for endpoints the
SDK does not cover yet.
- `#![forbid(unsafe_code)]`, panic-free library paths enforced by lints,
wasm32 support, `stream`/`oauth`/`tracing`/`native-tls` features.
- License changed to MIT (0.1.x releases remain Apache-2.0).

## 0.1.1 and earlier

The original crate by rdni, targeting the pre-2026 spoo.me API
(form-encoded shorten/stats/export endpoints). Apache-2.0.
Loading