From c5fc33958f9d79e4bbbd42aef74d2f425867e1df Mon Sep 17 00:00:00 2001 From: tison Date: Sat, 1 Aug 2026 01:06:22 +0800 Subject: [PATCH 1/3] ci: strengthen default quality gates --- .github/workflows/ci-bootstrap.yml | 8 +++-- .github/workflows/ci.yml | 16 ++++++++-- taplo.toml | 2 +- xtask/src/main.rs | 49 +++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-bootstrap.yml b/.github/workflows/ci-bootstrap.yml index bf80656..6eef0c5 100644 --- a/.github/workflows/ci-bootstrap.yml +++ b/.github/workflows/ci-bootstrap.yml @@ -19,6 +19,9 @@ on: push: branches: [ main ] +permissions: + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.number || github.run_id }} cancel-in-progress: true @@ -27,12 +30,13 @@ jobs: bootstrap: name: Bootstrap runs-on: ubuntu-24.04 + timeout-minutes: 30 steps: - uses: actions/checkout@v7 - name: Install toolchain uses: dtolnay/rust-toolchain@nightly - uses: Swatinem/rust-cache@v2 - name: Bootstrap cleanup - run: cargo x bootstrap --cleanup + run: cargo +nightly x bootstrap --cleanup - name: Bootstrap cleanup (After) - run: cargo x bootstrap --cleanup + run: cargo +nightly x bootstrap --cleanup diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2537820..b48543e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,9 @@ on: push: branches: [ main ] +permissions: + contents: read + # Concurrency strategy: # github.workflow: distinguish this workflow from others # github.event_name: distinguish `push` event from `pull_request` event @@ -36,21 +39,25 @@ jobs: check: name: Check runs-on: ubuntu-24.04 + timeout-minutes: 30 steps: - uses: actions/checkout@v7 - - name: Install toolchain + - name: Install nightly toolchain uses: dtolnay/rust-toolchain@nightly with: components: rustfmt,clippy + - name: Install stable toolchain + uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - uses: taiki-e/install-action@v2 with: - tool: typos-cli,taplo-cli,hawkeye - - run: cargo x lint + tool: typos-cli,taplo-cli,hawkeye,cargo-semver-checks + - run: cargo +nightly x lint msrv: name: Resolve MSRV runs-on: ubuntu-24.04 + timeout-minutes: 30 outputs: rust-versions: ${{ steps.metadata.outputs.rust-versions }} steps: @@ -65,10 +72,12 @@ jobs: name: Run tests needs: msrv strategy: + fail-fast: false matrix: os: [ ubuntu-24.04, macos-14, windows-2022 ] rust-version: ${{ fromJson(needs.msrv.outputs.rust-versions) }} runs-on: ${{ matrix.os }} + timeout-minutes: 30 steps: - uses: actions/checkout@v7 - uses: Swatinem/rust-cache@v2 @@ -85,6 +94,7 @@ jobs: required: name: Required runs-on: ubuntu-24.04 + timeout-minutes: 30 if: ${{ always() }} needs: - check diff --git a/taplo.toml b/taplo.toml index 8bb3198..ebbb309 100644 --- a/taplo.toml +++ b/taplo.toml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -exclude = ["target"] +exclude = ["target/**"] include = ["Cargo.toml", "**/*.toml"] [formatting] diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 0b1f7f7..2c6a471 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -14,6 +14,7 @@ //! An xtask binary for managing workspace tasks. +use std::io::Write; use std::path::Path; use std::process::Command as StdCommand; @@ -50,7 +51,7 @@ enum SubCommand { Build(CommandBuild), #[clap(about = "Bootstrap a new project from this template.")] Bootstrap(CommandBootstrap), - #[clap(about = "Run workspace quality checks.")] + #[clap(about = "Run code quality and API compatibility checks.")] Lint(CommandLint), #[clap(about = "Run workspace unit tests.")] Test(CommandTest), @@ -106,6 +107,8 @@ impl CommandLint { run_command(make_taplo_cmd(self.fix)); run_command(make_typos_cmd()); run_command(make_hawkeye_cmd(self.fix)); + run_command(make_doc_cmd()); + run_semver_check(); } } @@ -136,6 +139,23 @@ fn run_command(mut cmd: StdCommand) { assert!(status.success(), "command failed: {status}"); } +fn run_semver_check() { + let mut cmd = make_semver_check_cmd(); + println!("{cmd:?}"); + let output = cmd.output().expect("failed to execute cargo-semver-checks"); + + if !output.status.success() + && String::from_utf8_lossy(&output.stderr).contains("No available baseline versions for") + { + println!("No published baseline found; skipping semver checks."); + return; + } + + std::io::stdout().write_all(&output.stdout).unwrap(); + std::io::stderr().write_all(&output.stderr).unwrap(); + assert!(output.status.success(), "command failed: {}", output.status); +} + fn make_build_cmd(locked: bool) -> StdCommand { let mut cmd = find_command("cargo"); cmd.args([ @@ -192,6 +212,33 @@ fn make_clippy_cmd(fix: bool) -> StdCommand { cmd } +fn make_doc_cmd() -> StdCommand { + let mut cmd = find_command("cargo"); + cmd.env("RUSTDOCFLAGS", "-D warnings --cfg docsrs"); + cmd.args([ + "+nightly", + "doc", + "--workspace", + "--all-features", + "--no-deps", + ]); + cmd +} + +fn make_semver_check_cmd() -> StdCommand { + ensure_installed("cargo-semver-checks", "cargo-semver-checks"); + let mut cmd = find_command("cargo"); + // cargo-semver-checks supports selected rustdoc JSON versions, not a rolling nightly format. + cmd.args([ + "+stable", + "semver-checks", + "check-release", + "--workspace", + "--all-features", + ]); + cmd +} + fn make_hawkeye_cmd(fix: bool) -> StdCommand { ensure_installed("hawkeye", "hawkeye"); let mut cmd = find_command("hawkeye"); From b26098bca4704dcce8bed11b831c2d14619ea72b Mon Sep 17 00:00:00 2001 From: tison Date: Sat, 1 Aug 2026 11:23:18 +0800 Subject: [PATCH 2/3] ci: defer semver compatibility checks --- .github/workflows/ci.yml | 4 +--- xtask/src/main.rs | 35 +---------------------------------- 2 files changed, 2 insertions(+), 37 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b48543e..f7f97c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,12 +46,10 @@ jobs: uses: dtolnay/rust-toolchain@nightly with: components: rustfmt,clippy - - name: Install stable toolchain - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - uses: taiki-e/install-action@v2 with: - tool: typos-cli,taplo-cli,hawkeye,cargo-semver-checks + tool: typos-cli,taplo-cli,hawkeye - run: cargo +nightly x lint msrv: diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 2c6a471..6d6d823 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -14,7 +14,6 @@ //! An xtask binary for managing workspace tasks. -use std::io::Write; use std::path::Path; use std::process::Command as StdCommand; @@ -51,7 +50,7 @@ enum SubCommand { Build(CommandBuild), #[clap(about = "Bootstrap a new project from this template.")] Bootstrap(CommandBootstrap), - #[clap(about = "Run code quality and API compatibility checks.")] + #[clap(about = "Run code quality and documentation checks.")] Lint(CommandLint), #[clap(about = "Run workspace unit tests.")] Test(CommandTest), @@ -108,7 +107,6 @@ impl CommandLint { run_command(make_typos_cmd()); run_command(make_hawkeye_cmd(self.fix)); run_command(make_doc_cmd()); - run_semver_check(); } } @@ -139,23 +137,6 @@ fn run_command(mut cmd: StdCommand) { assert!(status.success(), "command failed: {status}"); } -fn run_semver_check() { - let mut cmd = make_semver_check_cmd(); - println!("{cmd:?}"); - let output = cmd.output().expect("failed to execute cargo-semver-checks"); - - if !output.status.success() - && String::from_utf8_lossy(&output.stderr).contains("No available baseline versions for") - { - println!("No published baseline found; skipping semver checks."); - return; - } - - std::io::stdout().write_all(&output.stdout).unwrap(); - std::io::stderr().write_all(&output.stderr).unwrap(); - assert!(output.status.success(), "command failed: {}", output.status); -} - fn make_build_cmd(locked: bool) -> StdCommand { let mut cmd = find_command("cargo"); cmd.args([ @@ -225,20 +206,6 @@ fn make_doc_cmd() -> StdCommand { cmd } -fn make_semver_check_cmd() -> StdCommand { - ensure_installed("cargo-semver-checks", "cargo-semver-checks"); - let mut cmd = find_command("cargo"); - // cargo-semver-checks supports selected rustdoc JSON versions, not a rolling nightly format. - cmd.args([ - "+stable", - "semver-checks", - "check-release", - "--workspace", - "--all-features", - ]); - cmd -} - fn make_hawkeye_cmd(fix: bool) -> StdCommand { ensure_installed("hawkeye", "hawkeye"); let mut cmd = find_command("hawkeye"); From ffde3a3900033c67a4875901b8e2b6ffdc25310a Mon Sep 17 00:00:00 2001 From: tison Date: Sat, 1 Aug 2026 11:29:34 +0800 Subject: [PATCH 3/3] fixup Signed-off-by: tison --- .github/workflows/ci-bootstrap.yml | 7 ++----- .github/workflows/ci.yml | 5 +---- xtask/src/main.rs | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-bootstrap.yml b/.github/workflows/ci-bootstrap.yml index 6eef0c5..9323d05 100644 --- a/.github/workflows/ci-bootstrap.yml +++ b/.github/workflows/ci-bootstrap.yml @@ -19,9 +19,6 @@ on: push: branches: [ main ] -permissions: - contents: read - concurrency: group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.number || github.run_id }} cancel-in-progress: true @@ -37,6 +34,6 @@ jobs: uses: dtolnay/rust-toolchain@nightly - uses: Swatinem/rust-cache@v2 - name: Bootstrap cleanup - run: cargo +nightly x bootstrap --cleanup + run: cargo x bootstrap --cleanup - name: Bootstrap cleanup (After) - run: cargo +nightly x bootstrap --cleanup + run: cargo x bootstrap --cleanup diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7f97c6..5e76882 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,9 +19,6 @@ on: push: branches: [ main ] -permissions: - contents: read - # Concurrency strategy: # github.workflow: distinguish this workflow from others # github.event_name: distinguish `push` event from `pull_request` event @@ -50,7 +47,7 @@ jobs: - uses: taiki-e/install-action@v2 with: tool: typos-cli,taplo-cli,hawkeye - - run: cargo +nightly x lint + - run: cargo x lint msrv: name: Resolve MSRV diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 6d6d823..4602bed 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -50,7 +50,7 @@ enum SubCommand { Build(CommandBuild), #[clap(about = "Bootstrap a new project from this template.")] Bootstrap(CommandBootstrap), - #[clap(about = "Run code quality and documentation checks.")] + #[clap(about = "Run workspace quality checks.")] Lint(CommandLint), #[clap(about = "Run workspace unit tests.")] Test(CommandTest),