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
42 changes: 42 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,45 @@ env:
CARGO_TERM_COLOR: always

jobs:
# What a pull request touched decides what the rest of this file runs. On a
# push there is no base to compare against, so everything counts as changed
# and main is gated on the whole file exactly as before.
changes:
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
code: ${{ steps.filter.outputs.code }}
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
with:
fetch-depth: 0
- id: filter
env:
BASE: ${{ github.event.pull_request.base.sha }}
run: |
if [ -z "$BASE" ]; then
echo "code=true" >> "$GITHUB_OUTPUT"
echo "not a pull request; everything runs"
exit 0
fi
# Named as what cannot affect a build rather than what can, so a new
# kind of file is treated as code until someone says otherwise. That
# matters more here than the saved minutes: README.md is absent from
# this list because every Rust snippet in it is a doctest, and
# `cargo package` ships it.
if git diff --name-only "$BASE"...HEAD \
| grep -qvE '^(DESIGN|CHANGELOG)\.md$|^images/'; then
echo "code=true" >> "$GITHUB_OUTPUT"
else
echo "code=false" >> "$GITHUB_OUTPUT"
echo "only prose and images changed; the cargo jobs are skipped"
fi

test:
runs-on: ubuntu-latest
timeout-minutes: 30
needs: changes
if: needs.changes.outputs.code == 'true'
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
Expand All @@ -31,6 +67,8 @@ jobs:
examples:
runs-on: ubuntu-latest
timeout-minutes: 30
needs: changes
if: needs.changes.outputs.code == 'true'
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
Expand All @@ -47,6 +85,8 @@ jobs:
msrv:
runs-on: ubuntu-latest
timeout-minutes: 30
needs: changes
if: needs.changes.outputs.code == 'true'
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- uses: dtolnay/rust-toolchain@e09e0d4c1f9d84cdd46855833435a743d2e6b596 # 1.70.0
Expand All @@ -59,6 +99,8 @@ jobs:
packaging:
runs-on: ubuntu-latest
timeout-minutes: 60
needs: changes
if: needs.changes.outputs.code == 'true'
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,17 @@ cargo run --example validate # early cancellation, and the lowering report
cargo run --example sse # the realistic shape: JSON inside a data: stream
```

## Development

`scripts/dev.sh` points git at the committed hooks and then runs the gate CI
runs: build, fmt, clippy, the tests, and the doctests. The doctests are a
separate step because `--all-targets` does not run them, and they are what keeps
the snippets above honest.

```sh
scripts/dev.sh
```

## Framing

jawohl parses JSON, not the envelope around it. Provider streams wrap fragments
Expand Down
44 changes: 44 additions & 0 deletions scripts/dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env bash
# Stand up a fresh jawohl checkout: hooks, then the gate CI runs. Safe to
# re-run; every step is idempotent.
set -euo pipefail

cd "$(dirname "${BASH_SOURCE[0]}")/.."

# A clone runs no hooks until it is pointed at them: core.hooksPath is per-clone
# configuration, so nothing a checkout carries can set it for you.
git config core.hooksPath .githooks
if [ ! -d .githooks ]; then
echo "note: .githooks is fleet-managed and not synced here yet; git will"
echo " start using it the moment ordnung writes it."
fi

if ! command -v cargo >/dev/null; then
echo "error: cargo is not on PATH; install Rust from https://rustup.rs" >&2
exit 1
fi

echo "== build"
cargo build --all-targets

echo "== fmt"
cargo fmt --all -- --check

echo "== clippy"
cargo clippy --all-targets -- -D warnings

echo "== test"
cargo test --all-targets

# Every Rust snippet in the README is a doctest, so this is what stops the front
# page from drifting away from the crate. It is a separate cargo invocation
# because --all-targets does not run doctests.
echo "== doctests"
cargo test --doc

echo
echo "ready. the examples double as documentation:"
echo " cargo run --example complete # finish truncated documents"
echo " cargo run --example streaming # chunk by chunk"
echo " cargo run --example validate # early cancellation"
echo " cargo run --example sse # JSON inside a data: stream"