This is an automated email from the ASF dual-hosted git repository.

numinnex pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iggy.git


The following commit(s) were added to refs/heads/master by this push:
     new 7c6d899b4 feat(ci,rust): declare MSRV 1.95 and enforce it in CI (#3558)
7c6d899b4 is described below

commit 7c6d899b43d5dc0215580342d3b9a8a7e3c80182
Author: Hubert Gruszecki <[email protected]>
AuthorDate: Thu Jun 25 09:13:26 2026 +0200

    feat(ci,rust): declare MSRV 1.95 and enforce it in CI (#3558)
---
 .github/actions/rust/pre-merge/action.yml | 24 ++++++++++++++++++++++--
 .github/config/components.yml             | 16 ++++++++++++++++
 Cargo.toml                                |  5 ++++-
 core/binary_protocol/Cargo.toml           |  1 +
 core/cli/Cargo.toml                       |  1 +
 core/common/Cargo.toml                    |  1 +
 core/sdk/Cargo.toml                       |  1 +
 scripts/verify-crates-publish.sh          | 29 +++++++++++++++++++++++++++++
 8 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/.github/actions/rust/pre-merge/action.yml 
b/.github/actions/rust/pre-merge/action.yml
index 43175bbb0..536e3056e 100644
--- a/.github/actions/rust/pre-merge/action.yml
+++ b/.github/actions/rust/pre-merge/action.yml
@@ -20,7 +20,7 @@ description: Rust pre-merge testing and linting github iggy 
actions
 
 inputs:
   task:
-    description: "Task to run (check, fmt, clippy, sort, machete, doctest, 
verify-publish, test-1, test-2, compat, miri)"
+    description: "Task to run (check, check-msrv, fmt, clippy, sort, machete, 
doctest, verify-publish, test-1, test-2, compat, miri)"
     required: true
   component:
     description: "Component name (for context)"
@@ -36,6 +36,11 @@ runs:
         # Miri builds against a nightly toolchain with a separate `target/miri`
         # subtree; isolate its cache from the stable `dev` namespace so the
         # two don't evict each other.
+        # check-msrv stays on `dev`: only `dev` is ever saved (by
+        # coverage-baseline), so a dedicated key would be cold every run. It
+        # reads only (pre-merge save-cache=false), so it cannot churn `dev`;
+        # the warm `~/.cargo` restore is a free win, and its 1.95 target
+        # artifacts rebuild regardless since the rustc hash differs.
         shared-key: ${{ inputs.task == 'miri' && 'miri' || 'dev' }}
         # fmt/sort/machete never build into target/, so the multi-GB cache
         # restore is pure overhead. Compiling legs 
(check/clippy/doctest/test-*)
@@ -44,7 +49,7 @@ runs:
         # Light legs fit in the runner's ~89 GiB default headroom; skip the
         # ~20-45s reclaim. Disk-heavy legs (coverage build + testcontainers
         # images on test-*, cross-builds, miri, verify-publish) keep it.
-        free-disk-space: ${{ (inputs.task == 'fmt' || inputs.task == 'sort' || 
inputs.task == 'clippy' || inputs.task == 'check' || inputs.task == 'machete' 
|| inputs.task == 'doctest') && 'false' || 'true' }}
+        free-disk-space: ${{ (inputs.task == 'fmt' || inputs.task == 'sort' || 
inputs.task == 'clippy' || inputs.task == 'check' || inputs.task == 
'check-msrv' || inputs.task == 'machete' || inputs.task == 'doctest') && 
'false' || 'true' }}
 
     - name: Install cargo-sort
       if: inputs.task == 'sort'
@@ -132,6 +137,21 @@ runs:
       run: cargo check --all --all-features
       shell: bash
 
+    # MSRV gate: compile-check the published crates against the declared
+    # workspace `rust-version`. The MSRV is read from Cargo.toml so this stays
+    # in sync with the single source of truth. The `+<msrv>` override beats the
+    # rust-toolchain.toml pin. check-only: downstream consumers compile our
+    # libs (not our tests), so dev-deps needing newer Rust are out of scope.
+    - name: Cargo check on MSRV
+      if: inputs.task == 'check-msrv'
+      run: |
+        MSRV=$(grep -oP -m1 '^rust-version\s*=\s*"\K[^"]+' Cargo.toml)
+        echo "::notice::Checking published crates against MSRV ${MSRV}"
+        rustup toolchain install "$MSRV" --profile minimal --no-self-update
+        cargo "+$MSRV" check --locked --all-features \
+          -p iggy -p iggy_common -p iggy_binary_protocol -p iggy-cli
+      shell: bash
+
     - name: Cargo fmt
       if: inputs.task == 'fmt'
       run: cargo fmt --all -- --check
diff --git a/.github/config/components.yml b/.github/config/components.yml
index 79b11a255..932b4192c 100644
--- a/.github/config/components.yml
+++ b/.github/config/components.yml
@@ -44,6 +44,22 @@ components:
     tasks:
       - "verify-publish"
 
+  # MSRV gate for the four crates we ship to crates.io. Compile-checks them
+  # against the workspace `rust-version` so the published MSRV stays honest.
+  # Source-scoped (not just Cargo.toml) because an MSRV break usually comes
+  # from a crate using an API newer than the floor.
+  rust-msrv:
+    depends_on:
+      - "rust-workspace" # Cargo.lock / toolchain bumps can shift the floor
+      - "ci-infrastructure" # action.yml edits should re-run the check
+    paths:
+      - "core/sdk/**"
+      - "core/common/**"
+      - "core/binary_protocol/**"
+      - "core/cli/**"
+    tasks:
+      - "check-msrv"
+
   # CI/CD infrastructure changes that require full regression
   ci-infrastructure:
     paths:
diff --git a/Cargo.toml b/Cargo.toml
index 4c6777fde..a5a2b5203 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -64,7 +64,10 @@ members = [
     "examples/rust",
 ]
 exclude = ["foreign/cpp", "foreign/php", "foreign/python"]
-resolver = "2"
+resolver = "3"
+
+[workspace.package]
+rust-version = "1.95"
 
 [workspace.dependencies]
 actix-cors = "0.7.1"
diff --git a/core/binary_protocol/Cargo.toml b/core/binary_protocol/Cargo.toml
index 7b28fd618..dc61a4919 100644
--- a/core/binary_protocol/Cargo.toml
+++ b/core/binary_protocol/Cargo.toml
@@ -20,6 +20,7 @@ name = "iggy_binary_protocol"
 version = "0.10.1-edge.2"
 description = "Wire protocol types and codec for the Iggy binary protocol. 
Shared between server and SDK."
 edition = "2024"
+rust-version.workspace = true
 license = "Apache-2.0"
 keywords = ["iggy", "messaging", "streaming"]
 categories = ["command-line-utilities", "database", "network-programming"]
diff --git a/core/cli/Cargo.toml b/core/cli/Cargo.toml
index 1c4d4ef32..6208dee3d 100644
--- a/core/cli/Cargo.toml
+++ b/core/cli/Cargo.toml
@@ -19,6 +19,7 @@
 name = "iggy-cli"
 version = "0.13.1-edge.1"
 edition = "2024"
+rust-version.workspace = true
 authors = ["[email protected]"]
 repository = "https://github.com/apache/iggy";
 homepage = "https://iggy.apache.org";
diff --git a/core/common/Cargo.toml b/core/common/Cargo.toml
index 3031412a0..fd86f57b9 100644
--- a/core/common/Cargo.toml
+++ b/core/common/Cargo.toml
@@ -20,6 +20,7 @@ name = "iggy_common"
 version = "0.10.1-edge.2"
 description = "Iggy is the persistent message streaming platform written in 
Rust, supporting QUIC, TCP and HTTP transport protocols, capable of processing 
millions of messages per second."
 edition = "2024"
+rust-version.workspace = true
 license = "Apache-2.0"
 keywords = ["iggy", "messaging", "streaming"]
 categories = ["command-line-utilities", "database", "network-programming"]
diff --git a/core/sdk/Cargo.toml b/core/sdk/Cargo.toml
index 560d1f5b0..658550485 100644
--- a/core/sdk/Cargo.toml
+++ b/core/sdk/Cargo.toml
@@ -20,6 +20,7 @@ name = "iggy"
 version = "0.10.1-edge.2"
 description = "Iggy is the persistent message streaming platform written in 
Rust, supporting QUIC, TCP and HTTP transport protocols, capable of processing 
millions of messages per second."
 edition = "2024"
+rust-version.workspace = true
 license = "Apache-2.0"
 keywords = ["iggy", "messaging", "streaming"]
 categories = ["command-line-utilities", "database", "network-programming"]
diff --git a/scripts/verify-crates-publish.sh b/scripts/verify-crates-publish.sh
index 6464cae86..f78cce945 100755
--- a/scripts/verify-crates-publish.sh
+++ b/scripts/verify-crates-publish.sh
@@ -170,6 +170,35 @@ if ! git diff --quiet HEAD -- Cargo.toml; then
     exit 1
 fi
 
+# ---------------------------------------------------------------------------
+# 0b. MSRV contract: the four crates we publish must advertise an MSRV on
+#     crates.io. The rust-msrv CI gate compile-checks against the floor, but
+#     it pins the toolchain regardless of the manifest, so it cannot notice
+#     the `rust-version` field silently disappearing. Assert it here, at the
+#     publish boundary, plus that every crate agrees on the value.
+# ---------------------------------------------------------------------------
+if ! command -v jq >/dev/null 2>&1; then
+    err "jq is required for the MSRV check but is not on PATH"
+    exit 1
+fi
+metadata="$(cargo metadata --format-version 1 --no-deps)"
+msrv=""
+for crate in "${CRATES[@]}"; do
+    crate_msrv="$(jq -r --arg c "$crate" \
+        '.packages[] | select(.name == $c) | .rust_version // ""' <<< 
"$metadata")"
+    if [[ -z "$crate_msrv" ]]; then
+        err "${crate} declares no rust-version; published MSRV would be unset"
+        exit 1
+    fi
+    if [[ -z "$msrv" ]]; then
+        msrv="$crate_msrv"
+    elif [[ "$crate_msrv" != "$msrv" ]]; then
+        err "MSRV mismatch: ${crate} pins ${crate_msrv}, expected ${msrv}"
+        exit 1
+    fi
+done
+log "Published crates declare MSRV ${msrv}"
+
 # ---------------------------------------------------------------------------
 # 1. Start the local registry
 # ---------------------------------------------------------------------------

Reply via email to