diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..6fcc0968 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,81 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + +# Cancel superseded runs on the same ref (a new push/PR sync) to save runners. +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + # Incremental compilation bloats the cache and buys nothing in CI's cold builds. + CARGO_INCREMENTAL: "0" + +jobs: + fmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + # Installs the toolchain + components pinned in rust-toolchain.toml. + - name: Install Rust toolchain + run: rustup show active-toolchain || rustup toolchain install + - run: cargo fmt --all -- --check + + clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Rust toolchain + run: rustup show active-toolchain || rustup toolchain install + - name: Install Protoc + uses: arduino/setup-protoc@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: Swatinem/rust-cache@v2 + with: + shared-key: ci-clippy + # Restore on every run, but only write the cache from main so PRs can't + # pollute it and we stay within the repo's 10 GB cache budget. + save-if: ${{ github.ref == 'refs/heads/main' }} + - run: cargo clippy --all-features --all-targets -- -D warnings + + test: + name: Test Suite + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Install Rust toolchain + run: rustup show active-toolchain || rustup toolchain install + - name: Install Protoc + uses: arduino/setup-protoc@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: Swatinem/rust-cache@v2 + with: + shared-key: ci-test + save-if: ${{ github.ref == 'refs/heads/main' }} + - run: cargo test --all-features --locked + + check: + name: Check (windows) + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - name: Install Rust toolchain + run: rustup show active-toolchain || rustup toolchain install + - name: Install Protoc + uses: arduino/setup-protoc@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: Swatinem/rust-cache@v2 + with: + shared-key: ci-check-windows + save-if: ${{ github.ref == 'refs/heads/main' }} + - run: cargo check --all-features --locked diff --git a/.github/workflows/publish-crates.yml b/.github/workflows/publish-crates.yml new file mode 100644 index 00000000..224c57fa --- /dev/null +++ b/.github/workflows/publish-crates.yml @@ -0,0 +1,34 @@ +name: Publish (crates.io) + +# Reusable workflow invoked by the cargo-dist release pipeline as a custom +# `publish-jobs` entry. dist calls it with the release plan and `secrets: inherit` +# only on real tag releases, after the `host` job has created the GitHub release. +on: + workflow_call: + inputs: + plan: + description: "The release plan emitted by cargo-dist" + required: true + type: string + +jobs: + crates-io: + name: cargo publish + runs-on: ubuntu-latest + timeout-minutes: 25 + env: + CARGO_TERM_COLOR: always + CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + # Pinned via rust-toolchain.toml. + - name: Install Rust toolchain + run: rustup show active-toolchain || rustup toolchain install + - name: Install Protoc + uses: arduino/setup-protoc@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + - name: cargo publish + run: cargo publish --all-features --locked diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 6e7c22c1..00000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Publish -permissions: - "contents": "write" - -on: - workflow_dispatch: {} - workflow_run: - workflows: [Release] - types: [completed] - -jobs: - crates_io_publish: - name: Publish - runs-on: ubuntu-latest - timeout-minutes: 25 - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - - name: cargo-release Cache - id: cargo_release_cache - uses: actions/cache@v4 - with: - path: ~/.cargo/bin/cargo-release - key: ${{ runner.os }}-cargo-release - - - run: cargo install cargo-release - if: steps.cargo_release_cache.outputs.cache-hit != 'true' - - - name: cargo login - run: cargo login ${{ secrets.CRATES_IO_TOKEN }} - - - name: "cargo release publish" - run: |- - cargo release \ - publish \ - --workspace \ - --all-features \ - --allow-branch HEAD \ - --no-confirm \ - --no-verify \ - --execute diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0f6c7391..fa400f12 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -332,15 +332,30 @@ jobs: done git push + custom-publish-crates: + needs: + - plan + - host + if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }} + uses: ./.github/workflows/publish-crates.yml + with: + plan: ${{ needs.plan.outputs.val }} + secrets: inherit + # publish jobs get escalated permissions + permissions: + "id-token": "write" + "packages": "write" + announce: needs: - plan - host - publish-homebrew-formula + - custom-publish-crates # use "always() && ..." to allow us to wait for all publish jobs while # still allowing individual publish jobs to skip themselves (for prereleases). # "host" however must run to completion, no skipping allowed! - if: ${{ always() && needs.host.result == 'success' && (needs.publish-homebrew-formula.result == 'skipped' || needs.publish-homebrew-formula.result == 'success') }} + if: ${{ always() && needs.host.result == 'success' && (needs.publish-homebrew-formula.result == 'skipped' || needs.publish-homebrew-formula.result == 'success') && (needs.custom-publish-crates.result == 'skipped' || needs.custom-publish-crates.result == 'success') }} runs-on: "ubuntu-22.04" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml deleted file mode 100644 index cde8a6bc..00000000 --- a/.github/workflows/validate.yml +++ /dev/null @@ -1,92 +0,0 @@ -# Based on https://github.com/actions-rs/meta/blob/master/recipes/quickstart.md - -on: - push: - branches: - - "**" - tags-ignore: - - v* - -name: Validate - -jobs: - check: - name: Check - strategy: - fail-fast: false - matrix: - os: [windows-latest, ubuntu-latest] - rust: [stable] - runs-on: ${{ matrix.os }} - steps: - - name: Checkout sources - uses: actions/checkout@v4 - - - name: Install stable toolchain - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - override: true - - - name: Install Protoc - uses: arduino/setup-protoc@v3 - - - name: Run cargo check - uses: actions-rs/cargo@v1 - with: - command: check - args: --all-features - - test: - name: Test Suite - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v4 - - - name: Install stable toolchain - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - - name: Install Protoc - uses: arduino/setup-protoc@v3 - - - name: Run cargo test - uses: actions-rs/cargo@v1 - with: - command: test - args: --all-features - - lints: - name: Lint Rust - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v4 - - - name: Install stable toolchain - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - components: rustfmt, clippy - - - name: Install Protoc - uses: arduino/setup-protoc@v3 - - - name: Run cargo fmt - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - - - name: Run cargo clippy - uses: actions-rs/cargo@v1 - with: - command: clippy - args: --all-features --all-targets -- -D warnings diff --git a/dist-workspace.toml b/dist-workspace.toml index a46922d6..2e8e3931 100644 --- a/dist-workspace.toml +++ b/dist-workspace.toml @@ -20,7 +20,7 @@ install-updater = true # A GitHub repo to push Homebrew formulas to tap = "txpipe/homebrew-tap" # Publish jobs to run in CI -publish-jobs = ["homebrew"] +publish-jobs = ["homebrew", "./publish-crates"] # A namespace to use when publishing this package to the npm registry npm-scope = "@txpipe" diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..1c0730c2 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "1.89" +components = ["rustfmt", "clippy"]