From 8abe1e39276a9d33dfb290dfa1c73e1f67f96564 Mon Sep 17 00:00:00 2001 From: John Eckersberg Date: Tue, 9 Jun 2026 17:43:20 -0400 Subject: [PATCH] Add CI and release automation - GitHub Actions CI workflow with test matrix (stable/beta/nightly on Linux), rustfmt check, and a required-checks sentinel job - Semver-checks job is present but disabled until after the initial crates.io publish - Tests run with and without the serde feature - Trusted publishing workflow for crates.io releases triggered by version tags (v*) Assisted-by: OpenCode (claude-opus-4-6) Signed-off-by: John Eckersberg --- .github/workflows/ci.yml | 78 ++++++++++++++++++++++++++ .github/workflows/cratesio-release.yml | 17 ++++++ 2 files changed, 95 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/cratesio-release.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..56e333f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,78 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +env: + CARGO_TERM_COLOR: always + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + test: + name: Test (${{ matrix.build }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + build: [stable, beta, nightly] + include: + - build: stable + os: ubuntu-latest + rust: stable + - build: beta + os: ubuntu-latest + rust: beta + - build: nightly + os: ubuntu-latest + rust: nightly + steps: + - uses: actions/checkout@v6 + - name: Install Rust + run: rustup update ${{ matrix.rust }} --no-self-update && rustup default ${{ matrix.rust }} + shell: bash + - run: cargo test + - run: cargo test --features serde + + rustfmt: + name: Rustfmt + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v6 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - run: cargo fmt -- --check + + semver-checks: + # TODO: Re-enable after initial crates.io publish + if: false + name: Semver Checks + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - uses: actions/checkout@v6 + - uses: obi1kenobi/cargo-semver-checks-action@v2 + + # Sentinel job for required checks - configure this job name in + # repository settings as the single required status check. + required-checks: + if: always() + needs: [test, rustfmt] + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - run: exit 1 + if: >- + needs.test.result != 'success' || + needs.rustfmt.result != 'success' diff --git a/.github/workflows/cratesio-release.yml b/.github/workflows/cratesio-release.yml new file mode 100644 index 0000000..92e8436 --- /dev/null +++ b/.github/workflows/cratesio-release.yml @@ -0,0 +1,17 @@ +# See https://crates.io/docs/trusted-publishing +name: Publish to crates.io +on: + push: + tags: ['v*'] +jobs: + publish: + runs-on: ubuntu-24.04 + permissions: + id-token: write + steps: + - uses: actions/checkout@v6 + - uses: rust-lang/crates-io-auth-action@v1 + id: auth + - run: cargo publish + env: + CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}