From c02e04a194abcf4d6d3e9fa40be37ba63c8644e2 Mon Sep 17 00:00:00 2001 From: "Gerard Castillo Lasheras (BI X)" Date: Wed, 30 Apr 2025 22:40:22 +0200 Subject: [PATCH 1/7] rustup managed rust installation enabling runtime toolchain and version selection --- .../continuous-integration-workflow.yml | 10 ++-- be-rust-axum/Jenkinsfile.template | 3 ++ .../rust-template/.pre-commit-config.yaml | 4 +- be-rust-axum/rust-template/Cargo.toml | 47 +++++++++++++++---- be-rust-axum/rust-template/README.md | 2 + .../rust-template/cargo-generate.toml | 2 + be-rust-axum/rust-template/metadata.yml | 2 +- be-rust-axum/rust-template/rust-toolchain | 1 + be-rust-axum/rust-template/src/api/router.rs | 2 +- .../rust-template/src/api/routes/status.rs | 2 +- .../rust-template/src/config/settings.rs | 5 +- be-rust-axum/rust-template/src/main.rs | 2 +- .../rust-template/tests/status_test.rs | 2 +- .../rust/docker/Dockerfile.ubi8 | 18 +++---- common/jenkins-agents/rust/ocp-config/bc.yml | 10 ++-- docs/modules/jenkins-agents/pages/rust.adoc | 35 ++++++++++---- .../quickstarters/pages/be-rust-axum.adoc | 19 ++++---- 17 files changed, 107 insertions(+), 59 deletions(-) create mode 100644 be-rust-axum/rust-template/cargo-generate.toml create mode 100644 be-rust-axum/rust-template/rust-toolchain diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index 676eaa853..8665e4517 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -108,12 +108,12 @@ jobs: working-directory: common/jenkins-agents/rust/docker run: | docker build --tag agent-rust-test-ubi8 --file Dockerfile.ubi8 \ - --build-arg rustVersion=1.83.0 \ + --build-arg rustVersion=1.86.0 \ --build-arg rustToolchain=x86_64-unknown-linux-gnu \ - --build-arg cargoNextestVersion=0.9.87 \ - --build-arg cargoLlvmCovVersion=0.6.15 \ - --build-arg cargoGenerateVersion=0.22.1 \ - --build-arg cargoDenyVersion=0.16.3 \ + --build-arg cargoNextestVersion=0.9.94 \ + --build-arg cargoLlvmCovVersion=0.6.16 \ + --build-arg cargoGenerateVersion=0.23.3 \ + --build-arg cargoDenyVersion=0.18.2 \ . jenkins-agent-terraform-2306-ubi8: diff --git a/be-rust-axum/Jenkinsfile.template b/be-rust-axum/Jenkinsfile.template index e56434569..0be1aa1cc 100644 --- a/be-rust-axum/Jenkinsfile.template +++ b/be-rust-axum/Jenkinsfile.template @@ -65,6 +65,9 @@ def stageCI(def context) { mkdir -p build/test-results/test mkdir -p build/test-results/coverage + # If required, pre-install llvm-tools-preview to avoid interactive prompt when not using default Jenkins agent toolchain + # rustup component add llvm-tools-preview --toolchain ${rustVersion} + # Tests with JUnit XML report, as defined in .config/nextest.toml, and coverage LLVM cov report cargo llvm-cov nextest --profile ci --lcov --output-path ./build/test-results/coverage/lcov.info cp -r target/nextest/ci/results.xml build/test-results/test diff --git a/be-rust-axum/rust-template/.pre-commit-config.yaml b/be-rust-axum/rust-template/.pre-commit-config.yaml index 1b31d29ca..24f4276c1 100644 --- a/be-rust-axum/rust-template/.pre-commit-config.yaml +++ b/be-rust-axum/rust-template/.pre-commit-config.yaml @@ -1,10 +1,10 @@ repos: - repo: https://github.com/gitleaks/gitleaks - rev: v8.22.1 + rev: v8.25.1 hooks: - id: gitleaks - repo: https://github.com/EmbarkStudios/cargo-deny - rev: 0.16.3 + rev: 0.18.2 hooks: - id: cargo-deny args: ["--all-features", "check"] # optionally modify the arguments for cargo-deny (default arguments shown here) diff --git a/be-rust-axum/rust-template/Cargo.toml b/be-rust-axum/rust-template/Cargo.toml index cd57a6b42..7391affae 100644 --- a/be-rust-axum/rust-template/Cargo.toml +++ b/be-rust-axum/rust-template/Cargo.toml @@ -2,35 +2,37 @@ # Here the project-name (Rust project) is your ODS component name name = "{{project-name}}" version = "0.1.0" -edition = "2021" +edition = "2024" +rust-version = "1.86" description = "{{project-name}} component - from the OpenDevStack Rust QuickStarter." license = "MIT OR Apache-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] # one can add more dependencies via cargo to Cargo.toml as shown next: cargo add axum -F axum/http2 -axum = { version = "0.8", features = ["http2"] } -tokio = { version = "1.40", features = ["rt-multi-thread", "macros", "signal"] } +axum = { version = "0.8", features = ["http2", "macros", "multipart"] } +tokio = { version = "1.44", features = ["rt-multi-thread", "macros", "signal"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -http = "1.1" +http = "1.3" http-body-util = "0.1" +# Highly encouraged to use URL encoding when working with any URI string +# urlencoding = "2.1" bytes = "1.7" thiserror = "2.0" tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["tracing", "env-filter"] } +tracing-subscriber = { version = "0.3", features = ["tracing", "env-filter", "json", "ansi", "fmt"] } lazy_static = "1.5" envy = "0.4" dotenvy = "0.15" -# Nice HTTP middlewares from Tower crate, to be added to router.rs. -# Uncomment as per need, check official docs. +# HTTP middlewares from Tower crate, to be added to router.rs. # tower-http = { version = "0.6", features = [ # "trace", # "compression-br", @@ -40,9 +42,36 @@ dotenvy = "0.15" # ] } # SQLx is the recommended safe and performant package to work with relational DBs like PostgreSQL; check official docs -# sqlx = { version = "0.8", features = [ "runtime-tokio", "tls-rustls", "postgres", "uuid", "json", "time", "macros", "migrate" ] } +# sqlx = { version = "0.8", features = [ +# "runtime-tokio", +# "tls-rustls-ring-native-roots", +# "postgres", +# "uuid", +# "json", +# "chrono", +# "macros", +# "migrate" +# ]} + +# OTEL; check official docs +# opentelemetry = { version = "0.29", features = ["trace", "metrics"] } +# opentelemetry_sdk = { version = "0.29", features = ["rt-tokio"] } +# opentelemetry-otlp = { version = "0.29", features = ["http-proto", "reqwest-client", "reqwest-rustls"] } +# opentelemetry-http = { version = "0.29" } +# opentelemetry-stdout = { version = "0.29", features = ["trace"] } +# opentelemetry-appender-tracing = { version = "0.29" } +# opentelemetry-semantic-conventions = { version = "0.29" } +# tracing-opentelemetry = { version = "0.30" } + +# OpenAPI; check official docs +# utoipa = { version = "5.3", features = ["axum_extras", "uuid", "chrono"] } +# utoipa-axum = "0.2" +# utoipa-swagger-ui = { version = "9.0", features = ["axum"] } +# # utoipa-redoc = { version = "5.0", features = ["axum"] } +# # utoipa-rapidoc = { version = "5.0", features = ["axum"] } +# # utoipa-scalar = { version = "0.2", features = ["axum"] } [dev-dependencies] -# mockito = "1.5" # mockito is recommended when requiring mocking network requests to either external or internal services +# mockito = "1.7" # mockito is recommended when requiring mocking network requests to either external or internal services temp-env = { version = "0.3", features = ["async_closure"] } # it is highly recommended the usage of cargo nextest run instead of cargo test; this way each test runs on its own process tower = { version = "0.5", features = ["util"] } diff --git a/be-rust-axum/rust-template/README.md b/be-rust-axum/rust-template/README.md index 312f57ee0..cf96f115e 100644 --- a/be-rust-axum/rust-template/README.md +++ b/be-rust-axum/rust-template/README.md @@ -2,6 +2,8 @@ The official OpenDevStack documentation for this QuickStarter can be found [here](https://www.opendevstack.org/ods-documentation/opendevstack/latest/quickstarters/be-rust-axum.html). +Check also the official docs of the [Jenkins Rust Agent](https://www.opendevstack.org/ods-documentation/opendevstack/latest/jenkins-agents/rust.html) this Quickstarter makes use of. There you can see the setup and tools it provides. + ## Pre-commit hooks This project uses [pre-commit](https://pre-commit.com). diff --git a/be-rust-axum/rust-template/cargo-generate.toml b/be-rust-axum/rust-template/cargo-generate.toml new file mode 100644 index 000000000..a446997dd --- /dev/null +++ b/be-rust-axum/rust-template/cargo-generate.toml @@ -0,0 +1,2 @@ +[template] +exclude = ["chart/templates/*"] diff --git a/be-rust-axum/rust-template/metadata.yml b/be-rust-axum/rust-template/metadata.yml index 7002f343e..c9dbf74aa 100644 --- a/be-rust-axum/rust-template/metadata.yml +++ b/be-rust-axum/rust-template/metadata.yml @@ -1,6 +1,6 @@ --- name: Axum - Rust web framework -description: "Axum is an ergonomic and modular web framework built with Tokio, Tower, and Hyper; written in Rust. Technologies: Axum 0.8.x, Rust 1.83.x" +description: "Axum is an ergonomic and modular web framework built with Tokio, Tower, and Hyper; written in Rust. Technologies: Axum 0.8.x, Rust 1.86.x" supplier: https://github.com/tokio-rs/axum version: 4.x type: ods diff --git a/be-rust-axum/rust-template/rust-toolchain b/be-rust-axum/rust-template/rust-toolchain new file mode 100644 index 000000000..b7844a6ff --- /dev/null +++ b/be-rust-axum/rust-template/rust-toolchain @@ -0,0 +1 @@ +1.86.0 diff --git a/be-rust-axum/rust-template/src/api/router.rs b/be-rust-axum/rust-template/src/api/router.rs index 5e0d3b08f..1e33fed78 100644 --- a/be-rust-axum/rust-template/src/api/router.rs +++ b/be-rust-axum/rust-template/src/api/router.rs @@ -1,7 +1,7 @@ use axum::{Json, Router}; use http::StatusCode; use std::net::SocketAddr; -use tokio::signal::unix::{signal, SignalKind}; +use tokio::signal::unix::{SignalKind, signal}; use tracing::info; use crate::api::routes; diff --git a/be-rust-axum/rust-template/src/api/routes/status.rs b/be-rust-axum/rust-template/src/api/routes/status.rs index 5f23b213b..89481f0b3 100644 --- a/be-rust-axum/rust-template/src/api/routes/status.rs +++ b/be-rust-axum/rust-template/src/api/routes/status.rs @@ -1,4 +1,4 @@ -use axum::{routing::get, Json, Router}; +use axum::{Json, Router, routing::get}; use http::StatusCode; use tracing::debug; diff --git a/be-rust-axum/rust-template/src/config/settings.rs b/be-rust-axum/rust-template/src/config/settings.rs index 86af8c900..634f9aac5 100644 --- a/be-rust-axum/rust-template/src/config/settings.rs +++ b/be-rust-axum/rust-template/src/config/settings.rs @@ -30,10 +30,7 @@ impl Settings { pub fn new() -> Result { dotenv().ok(); - let settings = match envy::from_env::() { - Ok(config) => config, - Err(error) => return Err(error), - }; + let settings = envy::from_env::()?; Ok(settings) } } diff --git a/be-rust-axum/rust-template/src/main.rs b/be-rust-axum/rust-template/src/main.rs index 01a39d69c..f96ee6bec 100644 --- a/be-rust-axum/rust-template/src/main.rs +++ b/be-rust-axum/rust-template/src/main.rs @@ -2,7 +2,7 @@ use {{crate_name}}::api::router::serve; use {{crate_name}}::config::settings::SETTINGS; use std::net::SocketAddr; -use tracing_subscriber::{layer::SubscriberExt, Layer, Registry}; +use tracing_subscriber::{Layer, Registry, layer::SubscriberExt}; #[tokio::main] async fn main() { diff --git a/be-rust-axum/rust-template/tests/status_test.rs b/be-rust-axum/rust-template/tests/status_test.rs index 7d23bc7c5..d65afd982 100644 --- a/be-rust-axum/rust-template/tests/status_test.rs +++ b/be-rust-axum/rust-template/tests/status_test.rs @@ -4,7 +4,7 @@ use tower::ServiceExt; // for `call`, `oneshot`, and `ready` use {{crate_name}}::{api::router::app, models::status::Status}; mod common; -use common::{response_json, RequestBuilderExt}; +use common::{RequestBuilderExt, response_json}; #[tokio::test] async fn get_status_route_ok() { diff --git a/common/jenkins-agents/rust/docker/Dockerfile.ubi8 b/common/jenkins-agents/rust/docker/Dockerfile.ubi8 index cf206f3b2..88c3d4458 100644 --- a/common/jenkins-agents/rust/docker/Dockerfile.ubi8 +++ b/common/jenkins-agents/rust/docker/Dockerfile.ubi8 @@ -16,24 +16,20 @@ ENV CARGO_NEXTEST_VERSION=${cargoNextestVersion} \ CARGO_GENERATE_VERSION=${cargoGenerateVersion} \ CARGO_DENY_VERSION=${cargoDenyVersion} -RUN yum install -y binutils cpp gcc glibc-devel glibc-headers isl kernel-headers libasan libatomic \ +RUN yum update -y && yum install -y binutils cpp gcc glibc-devel glibc-headers isl kernel-headers libasan libatomic \ libgomp libmpc libpkgconf libubsan libxcrypt-devel llvm-libs pkgconf pkgconf-m4 pkgconf-pkg-config \ openssl-devel cpan perl-IPC-Cmd && \ cpan install FindBin -RUN cd /tmp && \ - curl -LfSsO https://static.rust-lang.org/dist/rust-${rustVersion}-${rustToolchain}.tar.gz && \ - tar -xzf rust-${rustVersion}-${rustToolchain}.tar.gz && \ - rm -f rust-${rustVersion}-${rustToolchain}.tar.gz && \ - cd rust-${rustVersion}-${rustToolchain} && \ - ./install.sh && \ +RUN mkdir -p $HOME/.cargo/bin $HOME/.rustup && \ + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- \ + -y --profile complete --default-toolchain ${rustVersion} -t ${rustToolchain} && \ cargo -V && \ - mkdir -p $HOME/.cargo/bin && \ # Download binaries and install to $HOME/.cargo/bin curl --proto '=https' --tlsv1.2 -fsSL https://github.com/nextest-rs/nextest/releases/download/cargo-nextest-$CARGO_NEXTEST_VERSION/cargo-nextest-$CARGO_NEXTEST_VERSION-$rustToolchain.tar.gz | tar xzf - -C "$HOME/.cargo/bin" && \ curl --proto '=https' --tlsv1.2 -fsSL https://github.com/cargo-generate/cargo-generate/releases/download/v$CARGO_GENERATE_VERSION/cargo-generate-v$CARGO_GENERATE_VERSION-$rustToolchain.tar.gz | tar xzf - -C "$HOME/.cargo/bin" && \ # curl --proto '=https' --tlsv1.2 -fsSL https://github.com/taiki-e/cargo-llvm-cov/releases/download/v$CARGO_LLVM_COV_VERSION/cargo-llvm-cov-$rustToolchain.tar.gz | tar xzf - -C "$HOME/.cargo/bin" && \ - #Β cargo LLVM coverage crate is recommended to be compiled as it takes care to add the OS lib dependencies the proper way + # cargo LLVM coverage crate is recommended to be compiled as it takes care to add the OS lib dependencies the proper way cargo install cargo-llvm-cov --locked --version $CARGO_LLVM_COV_VERSION && \ # install cargo deny as release sources do not provide our rust toolchain target cargo install cargo-deny --locked --version $CARGO_DENY_VERSION && \ @@ -43,5 +39,5 @@ RUN cd /tmp && \ cargo generate --version && \ cargo deny --version -RUN chgrp -R 0 $HOME/.cargo && \ - chmod -R g=u $HOME/.cargo +RUN chgrp -R 0 $HOME/.cargo $HOME/.rustup && \ + chmod -R g=u $HOME/.cargo $HOME/.rustup diff --git a/common/jenkins-agents/rust/ocp-config/bc.yml b/common/jenkins-agents/rust/ocp-config/bc.yml index ab1f1f10a..4c89ed9d0 100644 --- a/common/jenkins-agents/rust/ocp-config/bc.yml +++ b/common/jenkins-agents/rust/ocp-config/bc.yml @@ -19,7 +19,7 @@ parameters: - name: RUST_VERSION description: "The Rust version" required: true - value: "1.83.0" + value: "1.86.0" - name: RUST_TOOLCHAIN description: "The Rust target toolchain" required: true @@ -27,19 +27,19 @@ parameters: - name: CARGO_NEXTEST_VERSION description: "The Cargo Nextest testing framework version" required: true - value: "0.9.87" + value: "0.9.94" - name: CARGO_LLVM_COV_VERSION description: "The Cargo LLVM Coverage tool version" required: true - value: "0.6.15" + value: "0.6.16" - name: CARGO_GENERATE_VERSION description: "The Cargo Generate tool version" required: true - value: "0.22.1" + value: "0.23.3" - name: CARGO_DENY_VERSION description: "The Cargo Deny tool version" required: true - value: "0.16.3" + value: "0.18.2" objects: - apiVersion: build.openshift.io/v1 kind: BuildConfig diff --git a/docs/modules/jenkins-agents/pages/rust.adoc b/docs/modules/jenkins-agents/pages/rust.adoc index 2d5420dee..3f8814d11 100644 --- a/docs/modules/jenkins-agents/pages/rust.adoc +++ b/docs/modules/jenkins-agents/pages/rust.adoc @@ -6,18 +6,33 @@ This agent is used to build / execute Rust code and tools. The image is built in the global `ods` project and is named `jenkins-agent-rust`. It can be referenced in a `Jenkinsfile` with `ods/jenkins-agent-rust`. -Minimum Supported Rust Version (MSRV) **1.83**. +== Default MSRV and Edition +Rust installation is managed by `rustup`, which offers a convenient way to load and manage Rust versions automatically. -**NOTE**: Current Rust edition in use is **2021**. See https://doc.rust-lang.org/edition-guide/introduction.html[Rust Edition Guide] for further information. +And, the version defined in the `rust-toolchain` file is the one that the Jenkins Agent will use (even if it is not the default). That file MUST be in the root of the projects' repository. + +Default Minimum Supported Rust Version (MSRV) **1.86**. + +Default Rust edition in use is **2024**. See https://doc.rust-lang.org/edition-guide/introduction.html[Rust Edition Guide] for further information. == Features -1. https://www.rust-lang.org/[Rust] -2. https://github.com/tokio-rs/axum/[Axum] -3. https://doc.rust-lang.org/cargo/[Cargo] -4. https://nexte.st/[Nextest] -5. https://github.com/taiki-e/cargo-llvm-cov[LLVM Coverage] -6. https://cargo-generate.github.io/cargo-generate/[Generate] +The image contains the following tools: + +* Rust toolchain (https://www.rust-lang.org/tools/install[Rustup]) + +* Rust compiler (https://doc.rust-lang.org/rustc/[Rustc]) + +* Rust package manager (https://doc.rust-lang.org/cargo/[Cargo]) + +* Rust Next generation test runner (https://nexte.st/[Cargo Nextest]) + +* Rust code coverage (https://github.com/taiki-e/cargo-llvm-cov[Cargo LLVM Coverage]) + +* Rust code generation (https://cargo-generate.github.io/cargo-generate/[Cargo Generate]) + +* Rust project's dependency graph linter (https://embarkstudios.github.io/cargo-deny/[Cargo Deny]) + +**Do you miss any tool?** Open a https://github.com/opendevstack/ods-quickstarters/issues/new?template=feature_request.md[`feature request`] in the `ods-quickstarters` GitHub repository. == Known limitations -No special HTTP Proxy configuration. -Fixed Rust compiler version (although dependending on specific project's dependencies, it can build on lower or higher Minor **Rust** versions from **1.83.x**). +By default, no Nexus repository/registry nor mirror available for Rust packages and dependencies (https://help.sonatype.com/en/rust-cargo.html[available in Nexus Pro from version 3.73.0]). If not having Nexus Pro v3.37.0+, one can use git repositories or local file system to store and reference Rust packages and dependencies. diff --git a/docs/modules/quickstarters/pages/be-rust-axum.adoc b/docs/modules/quickstarters/pages/be-rust-axum.adoc index b606f764b..9ef1b74f4 100644 --- a/docs/modules/quickstarters/pages/be-rust-axum.adoc +++ b/docs/modules/quickstarters/pages/be-rust-axum.adoc @@ -7,13 +7,13 @@ For Database/Postgres integration it is recommended to use https://github.com/la == Purpose of this quickstarter -This is a Rust project with a common Rust project folder and files structure, with its `main.rs` file for the final binary to be built, and that makes use of the `lib.rs` file, which exposes the crates (AKA modules or packages) of the project (where the business logic happens). Similar to Python project structures. +This is a Rust project with a common Rust project folder and files structure, with its `main.rs` file for the final binary to be built, and that makes use of the `lib.rs` file, which exposes the crates (AKA modules or packages) of the project (where the business logic happens). Similar to Python project structures. One could leverage the use of https://doc.rust-lang.org/cargo/reference/workspaces.html[workspaces] to split the project into multiple crates, but this is not the default behavior of this quickstarter. The quickstarter comes with a simple API-server example written in https://www.rust-lang.org/[Rust] and using the https://github.com/tokio-rs/axum/[Axum] web framework. The package allows to easily build a Rust project, using different Rust crates (packages). It contains the basic setup for Docker, Jenkins, SonarQube and OpenShift. -**NOTE** The project can be also extended to build other types of solutions with, for example, https://www.rust-lang.org/what/wasm/[WASM] or https://esp-rs.github.io/book/introduction.html[IoT]. +**NOTE** The project can be also extended to build other types of solutions like, for example, https://www.rust-lang.org/what/wasm/[WASM] or https://esp-rs.github.io/book/introduction.html[IoT]. == What files / architecture is generated? @@ -63,16 +63,19 @@ It contains the basic setup for Docker, Jenkins, SonarQube and OpenShift. β”œβ”€β”€ πŸ“š README.md - The README file β”œβ”€β”€ πŸ“„ release-manager.yml - Configuration file for the Release Manager β”œβ”€β”€ πŸ“„ rustfmt.toml - The Rust formatter configuration file (for cargo fmt) +β”œβ”€β”€ πŸ“„ rust-toolchain - Making sure teams and CICD use the same Rust toolchain for this project └── πŸ“„ sonar-project.properties - This file contains SonarQube configuration settings ---- +**IMPORTANT**: The Jenkins Rust Agent is using `rustup` to manage the Rust toolchain, so it is important to keep the `rust-toolchain` file up to date, in the root of the project. This file should contain the version of Rust in use for the project. The agent will automatically load (if not being the default at the moment) and use this version when building the project. + == Frameworks used -* https://www.rust-lang.org/[Rust 1.83.x] +* https://www.rust-lang.org/[Rust 1.86.x] * https://github.com/tokio-rs/axum[Axum 0.8.x] * https://nexte.st/[Nextest 0.9.x] * https://github.com/taiki-e/cargo-llvm-cov/[LLVM coverage 0.6.x] -* https://github.com/EmbarkStudios/cargo-deny/[Deny 0.16.x] +* https://github.com/EmbarkStudios/cargo-deny/[Deny 0.18.x] == Usage - how do you start after you provisioned this quickstarter @@ -123,7 +126,7 @@ cargo install cargo-deny # ... ---- -**NOTE** For an extended list of awesome `cargo` extensions and Rust tools check https://blessed.rs/crates/[here] and https://github.com/rust-unofficial/awesome-rust/[here]. +**NOTE** For an extended list of awesome `cargo` extensions and Rust tools check https://blessed.rs/[here] and https://github.com/rust-unofficial/awesome-rust/[here]. === Metadata @@ -190,11 +193,11 @@ The Jenkinsfile is provisioned with this quick starter to ease CI/CD process. In include::partials$secret-scanning-with-gitleaks.adoc -== Builder agent used +== Builder agent used by the Jenkins CICD This quickstarter uses https://www.opendevstack.org/ods-documentation/opendevstack/latest/jenkins-agents/rust.html[Rust] Jenkins builder agent. -**NOTE**: The ODS Jenkins Rust Agent supports Rust versions 1.83.x, and depending on project's dependencies it can also handle Minor Rust versions above and below the supported one. +**IMPORTANT**: By using `rustup` to manage the Rust toolchain, one can easily switch between different versions of Rust and toolchain as needed. This is particularly useful for projects that require specific versions of Rust or when working with multiple projects that have different requirements. See the docker spec and openshift templates https://github.com/opendevstack/ods-quickstarters/tree/master/common/jenkins-agents/rust[here]. @@ -209,7 +212,7 @@ The following main Rust technologies are in use when running this boilerplate: == Known limitations -First of all, please, let us know if you find any limitation or issue to comment on, thanks! +If any, please, open a https://github.com/opendevstack/ods-quickstarters/issues/new?template=feature_request.md[`feature request`] or https://github.com/opendevstack/ods-quickstarters/issues/new?template=bug_report.md[bug report] in the `ods-quickstarters` GitHub repository. === Building with OpenSSL crate or using alternatives === From c8fb1ab9d5b285005f41e6f03e5c299c085def36 Mon Sep 17 00:00:00 2001 From: "Gerard Castillo Lasheras (BI X)" Date: Fri, 2 May 2025 09:15:14 +0200 Subject: [PATCH 2/7] enable easy switch on and off of cargo-deny - closing #1107 --- be-rust-axum/Jenkinsfile.template | 20 +++++++++++--------- docs/modules/jenkins-agents/pages/rust.adoc | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/be-rust-axum/Jenkinsfile.template b/be-rust-axum/Jenkinsfile.template index 0be1aa1cc..66998d099 100644 --- a/be-rust-axum/Jenkinsfile.template +++ b/be-rust-axum/Jenkinsfile.template @@ -10,7 +10,7 @@ odsComponentPipeline( ] ) { context -> odsComponentFindOpenShiftImageOrElse(context) { - stageCI(context) + stageCI(context, true) // set `lintDependencies` to false if cargo-deny is not needed odsComponentStageScanWithSonar(context) stageBuild(context) odsComponentStageBuildOpenShiftImage(context) @@ -27,7 +27,7 @@ def stageBuild(def context) { } } -def stageCI(def context) { +def stageCI(def context, def lintDependencies) { stage('Cargo Check') { sh """ cargo --version @@ -51,13 +51,15 @@ def stageCI(def context) { cargo clippy --message-format=json &> build/test-results/clippy/report.json """ } - stage('Cargo Deny') { - sh """ - mkdir -p build/test-results/deny - cargo deny --format json check &> build/test-results/deny/cargo-deny-report.json - cat build/test-results/deny/cargo-deny-report.json - """ - archiveArtifacts artifacts: 'build/test-results/deny/cargo-deny-report.json', fingerprint: true + if (lintDependencies) { + stage('Cargo Deny') { + sh """ + mkdir -p build/test-results/deny + cargo deny --format json check &> build/test-results/deny/cargo-deny-report.json + cat build/test-results/deny/cargo-deny-report.json + """ + archiveArtifacts artifacts: 'build/test-results/deny/cargo-deny-report.json', fingerprint: true + } } stage('Cargo Test') { sh """ diff --git a/docs/modules/jenkins-agents/pages/rust.adoc b/docs/modules/jenkins-agents/pages/rust.adoc index 3f8814d11..43b0757cf 100644 --- a/docs/modules/jenkins-agents/pages/rust.adoc +++ b/docs/modules/jenkins-agents/pages/rust.adoc @@ -35,4 +35,4 @@ The image contains the following tools: **Do you miss any tool?** Open a https://github.com/opendevstack/ods-quickstarters/issues/new?template=feature_request.md[`feature request`] in the `ods-quickstarters` GitHub repository. == Known limitations -By default, no Nexus repository/registry nor mirror available for Rust packages and dependencies (https://help.sonatype.com/en/rust-cargo.html[available in Nexus Pro from version 3.73.0]). If not having Nexus Pro v3.37.0+, one can use git repositories or local file system to store and reference Rust packages and dependencies. +By default, no Nexus repository/registry nor mirror available for Rust packages and dependencies (only available in https://help.sonatype.com/en/rust-cargo.html[Nexus Pro from version 3.73.0] and/or https://help.sonatype.com/en/ce-onboarding.html[Nexus Community from version 3.77.0]). If not having Nexus Pro v3.37.0+, one can use git repositories or local file system to store and reference Rust packages and dependencies. From ce0732707d5e1e9872476accb440dcb071f5463b Mon Sep 17 00:00:00 2001 From: "Gerard Castillo Lasheras (BI X)" Date: Fri, 2 May 2025 09:26:12 +0200 Subject: [PATCH 3/7] update changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 718be060a..a8956f262 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,14 @@ ### Added - ### Changed - Use npm ci in e2e-cypress quickstarter & Better TypeScript support in e2e-cypress quickstarter ([#1114](https://github.com/opendevstack/ods-quickstarters/pull/1114)) - e2e-cypress get rid of additional chrome installation and switch to edge for pdf generation ([#1112](https://github.com/opendevstack/ods-quickstarters/pull/1112)) - Fix for the integration of the Python Quickstarter and Zephyr ODS integration ([#1125](https://github.com/opendevstack/ods-quickstarters/pull/1125)) +- Rust QS flag to enable or disable cargo-deny for dependency linting, default to true ([#1107](https://github.com/opendevstack/ods-quickstarters/issues/1107)) +- Rust QS enable dynamic toolchain/version support ([#1119](https://github.com/opendevstack/ods-quickstarters/issues/1119)) + + ### Fixed From 4a40578ec0ec7ab9075f64c705c282cda24272d4 Mon Sep 17 00:00:00 2001 From: "Gerard Castillo Lasheras (BI X)" Date: Sun, 27 Jul 2025 12:35:46 +0200 Subject: [PATCH 4/7] rust-toolchain in TOML, rustfmt.toml update and upgrade default MSRV to 1.88.0 --- be-rust-axum/rust-template/Cargo.toml | 2 +- be-rust-axum/rust-template/metadata.yml | 2 +- be-rust-axum/rust-template/rust-toolchain | 1 - .../rust-template/rust-toolchain.toml | 2 ++ be-rust-axum/rust-template/rustfmt.toml | 28 +++++++++++++++---- common/jenkins-agents/rust/ocp-config/bc.yml | 2 +- docs/modules/jenkins-agents/pages/rust.adoc | 2 +- .../quickstarters/pages/be-rust-axum.adoc | 2 +- 8 files changed, 30 insertions(+), 11 deletions(-) delete mode 100644 be-rust-axum/rust-template/rust-toolchain create mode 100644 be-rust-axum/rust-template/rust-toolchain.toml diff --git a/be-rust-axum/rust-template/Cargo.toml b/be-rust-axum/rust-template/Cargo.toml index 7391affae..f0de2da4e 100644 --- a/be-rust-axum/rust-template/Cargo.toml +++ b/be-rust-axum/rust-template/Cargo.toml @@ -3,7 +3,7 @@ name = "{{project-name}}" version = "0.1.0" edition = "2024" -rust-version = "1.86" +rust-version = "1.88" description = "{{project-name}} component - from the OpenDevStack Rust QuickStarter." license = "MIT OR Apache-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/be-rust-axum/rust-template/metadata.yml b/be-rust-axum/rust-template/metadata.yml index c9dbf74aa..fba0aa1cf 100644 --- a/be-rust-axum/rust-template/metadata.yml +++ b/be-rust-axum/rust-template/metadata.yml @@ -1,6 +1,6 @@ --- name: Axum - Rust web framework -description: "Axum is an ergonomic and modular web framework built with Tokio, Tower, and Hyper; written in Rust. Technologies: Axum 0.8.x, Rust 1.86.x" +description: "Axum is an ergonomic and modular web framework built with Tokio, Tower, and Hyper; written in Rust. Technologies: Axum 0.8.x, Rust 1.88.x" supplier: https://github.com/tokio-rs/axum version: 4.x type: ods diff --git a/be-rust-axum/rust-template/rust-toolchain b/be-rust-axum/rust-template/rust-toolchain deleted file mode 100644 index b7844a6ff..000000000 --- a/be-rust-axum/rust-template/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -1.86.0 diff --git a/be-rust-axum/rust-template/rust-toolchain.toml b/be-rust-axum/rust-template/rust-toolchain.toml new file mode 100644 index 000000000..e88baf106 --- /dev/null +++ b/be-rust-axum/rust-template/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.88.0" diff --git a/be-rust-axum/rust-template/rustfmt.toml b/be-rust-axum/rust-template/rustfmt.toml index 10b47a0f3..f9a34f412 100644 --- a/be-rust-axum/rust-template/rustfmt.toml +++ b/be-rust-axum/rust-template/rustfmt.toml @@ -1,6 +1,24 @@ -# rustfmt configurations from master branch, check rustfmt version -# (cargo fmt --version). # https://github.com/rust-lang/rustfmt/blob/master/Configurations.md - -edition = "2021" -tab_spaces = 2 +# ───────────────────────────────────────────── +# πŸ“¦ Edition +edition = "2024" +# ───────────────────────────────────────────── +# πŸ“š Import organization +# group_imports = "StdExternalCrate" # Group: std, external crates, then local +# imports_granularity = "Module" # One use per module line (avoids merge conflicts) +reorder_imports = true # Ensure deterministic ordering +# ───────────────────────────────────────────── +# πŸ“ Formatting rules +use_field_init_shorthand = true # Use shorthand: { foo } instead of { foo: foo } +match_block_trailing_comma = true # Add trailing commas in multiline match arms +# trailing_comma = "Always" # Always use trailing commas in multiline +newline_style = "Unix" # Use \n (LF) for line endings +tab_spaces = 2 # Use 2 spaces per indentation level +max_width = 100 # Line length limit +# ───────────────────────────────────────────── +# 🧼 Style preferences +# normalize_doc_attributes = true # Normalize #[doc] to /// comments +# wrap_comments = true # Automatically wrap long doc/comments +# format_code_in_doc_comments = true # Format Rust code inside doc comments +# blank_lines_upper_bound = 1 # Avoid excessive vertical whitespace +# blank_lines_lower_bound = 0 # Allow compact block spacing when possible diff --git a/common/jenkins-agents/rust/ocp-config/bc.yml b/common/jenkins-agents/rust/ocp-config/bc.yml index 4c89ed9d0..b047284c0 100644 --- a/common/jenkins-agents/rust/ocp-config/bc.yml +++ b/common/jenkins-agents/rust/ocp-config/bc.yml @@ -19,7 +19,7 @@ parameters: - name: RUST_VERSION description: "The Rust version" required: true - value: "1.86.0" + value: "1.88.0" - name: RUST_TOOLCHAIN description: "The Rust target toolchain" required: true diff --git a/docs/modules/jenkins-agents/pages/rust.adoc b/docs/modules/jenkins-agents/pages/rust.adoc index 43b0757cf..2a3f76590 100644 --- a/docs/modules/jenkins-agents/pages/rust.adoc +++ b/docs/modules/jenkins-agents/pages/rust.adoc @@ -11,7 +11,7 @@ Rust installation is managed by `rustup`, which offers a convenient way to load And, the version defined in the `rust-toolchain` file is the one that the Jenkins Agent will use (even if it is not the default). That file MUST be in the root of the projects' repository. -Default Minimum Supported Rust Version (MSRV) **1.86**. +Default Minimum Supported Rust Version (MSRV) **1.88**. Default Rust edition in use is **2024**. See https://doc.rust-lang.org/edition-guide/introduction.html[Rust Edition Guide] for further information. diff --git a/docs/modules/quickstarters/pages/be-rust-axum.adoc b/docs/modules/quickstarters/pages/be-rust-axum.adoc index 9ef1b74f4..9b8f360c9 100644 --- a/docs/modules/quickstarters/pages/be-rust-axum.adoc +++ b/docs/modules/quickstarters/pages/be-rust-axum.adoc @@ -71,7 +71,7 @@ It contains the basic setup for Docker, Jenkins, SonarQube and OpenShift. == Frameworks used -* https://www.rust-lang.org/[Rust 1.86.x] +* https://www.rust-lang.org/[Rust 1.88.x] * https://github.com/tokio-rs/axum[Axum 0.8.x] * https://nexte.st/[Nextest 0.9.x] * https://github.com/taiki-e/cargo-llvm-cov/[LLVM coverage 0.6.x] From d45cfe82f1bf62b8a7ecbea4816b1b6015a875e9 Mon Sep 17 00:00:00 2001 From: "Gerard Castillo Lasheras (BI X)" Date: Thu, 14 Aug 2025 10:43:36 +0200 Subject: [PATCH 5/7] make rust cargo deny depdency auditing disabled by default in Jenkins CICD --- .github/workflows/continuous-integration-workflow.yml | 2 +- be-rust-axum/Jenkinsfile.template | 6 +++--- be-rust-axum/rust-template/README.md | 8 ++++++++ be-rust-axum/testdata/golden/jenkins-build-stages.json | 4 ---- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index 8665e4517..4f4a40ff2 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -108,7 +108,7 @@ jobs: working-directory: common/jenkins-agents/rust/docker run: | docker build --tag agent-rust-test-ubi8 --file Dockerfile.ubi8 \ - --build-arg rustVersion=1.86.0 \ + --build-arg rustVersion=1.88.0 \ --build-arg rustToolchain=x86_64-unknown-linux-gnu \ --build-arg cargoNextestVersion=0.9.94 \ --build-arg cargoLlvmCovVersion=0.6.16 \ diff --git a/be-rust-axum/Jenkinsfile.template b/be-rust-axum/Jenkinsfile.template index 66998d099..6c794a64c 100644 --- a/be-rust-axum/Jenkinsfile.template +++ b/be-rust-axum/Jenkinsfile.template @@ -10,7 +10,7 @@ odsComponentPipeline( ] ) { context -> odsComponentFindOpenShiftImageOrElse(context) { - stageCI(context, true) // set `lintDependencies` to false if cargo-deny is not needed + stageCI(context, false) // set `auditDependencies` to true if using cargo-deny odsComponentStageScanWithSonar(context) stageBuild(context) odsComponentStageBuildOpenShiftImage(context) @@ -27,7 +27,7 @@ def stageBuild(def context) { } } -def stageCI(def context, def lintDependencies) { +def stageCI(def context, def auditDependencies) { stage('Cargo Check') { sh """ cargo --version @@ -51,7 +51,7 @@ def stageCI(def context, def lintDependencies) { cargo clippy --message-format=json &> build/test-results/clippy/report.json """ } - if (lintDependencies) { + if (auditDependencies) { stage('Cargo Deny') { sh """ mkdir -p build/test-results/deny diff --git a/be-rust-axum/rust-template/README.md b/be-rust-axum/rust-template/README.md index cf96f115e..62a8211ec 100644 --- a/be-rust-axum/rust-template/README.md +++ b/be-rust-axum/rust-template/README.md @@ -13,6 +13,14 @@ This project uses [pre-commit](https://pre-commit.com). pre-commit install ``` +The provided pre-commit hooks are: +- gitleaks (check for secrets) +- cargo-deny (dependency auditing, see/update `deny.toml` config file) +- cargo-fmt (formatter, see/update `rustfmt.toml` config file) +- cargo-clippy (linter) + +**NOTE**: the cargo hooks also run in Jenkins CICD, but cargo deny is disabled by default, see Jenkinsfile. + ## Adding caching in your CICD One can improve the build pipeline time by implementing a caching mechanism as shown next: diff --git a/be-rust-axum/testdata/golden/jenkins-build-stages.json b/be-rust-axum/testdata/golden/jenkins-build-stages.json index 9335e6e90..0db2cef39 100644 --- a/be-rust-axum/testdata/golden/jenkins-build-stages.json +++ b/be-rust-axum/testdata/golden/jenkins-build-stages.json @@ -15,10 +15,6 @@ "stage": "Cargo Clippy", "status": "SUCCESS" }, - { - "stage": "Cargo Deny", - "status": "SUCCESS" - }, { "stage": "Cargo Test", "status": "SUCCESS" From 758ee900c0abf0041f63016fd822aad7408bd277 Mon Sep 17 00:00:00 2001 From: "Vazquez,Brais (IT EDP)" Date: Mon, 3 Nov 2025 18:01:15 +0100 Subject: [PATCH 6/7] remove yum update --- common/jenkins-agents/rust/docker/Dockerfile.ubi8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/jenkins-agents/rust/docker/Dockerfile.ubi8 b/common/jenkins-agents/rust/docker/Dockerfile.ubi8 index 88c3d4458..216ff1716 100644 --- a/common/jenkins-agents/rust/docker/Dockerfile.ubi8 +++ b/common/jenkins-agents/rust/docker/Dockerfile.ubi8 @@ -16,7 +16,7 @@ ENV CARGO_NEXTEST_VERSION=${cargoNextestVersion} \ CARGO_GENERATE_VERSION=${cargoGenerateVersion} \ CARGO_DENY_VERSION=${cargoDenyVersion} -RUN yum update -y && yum install -y binutils cpp gcc glibc-devel glibc-headers isl kernel-headers libasan libatomic \ +RUN yum install -y binutils cpp gcc glibc-devel glibc-headers isl kernel-headers libasan libatomic \ libgomp libmpc libpkgconf libubsan libxcrypt-devel llvm-libs pkgconf pkgconf-m4 pkgconf-pkg-config \ openssl-devel cpan perl-IPC-Cmd && \ cpan install FindBin From de1c69ec366129222bfd236d1401e4aa988bb901 Mon Sep 17 00:00:00 2001 From: "Vazquez,Brais (IT EDP)" Date: Tue, 4 Nov 2025 15:45:07 +0100 Subject: [PATCH 7/7] Update Dockerfile to include RUST_VERSION in environment variables and fix commented rustup command --- be-rust-axum/Jenkinsfile.template | 2 +- common/jenkins-agents/rust/docker/Dockerfile.ubi8 | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/be-rust-axum/Jenkinsfile.template b/be-rust-axum/Jenkinsfile.template index 6c794a64c..00b402187 100644 --- a/be-rust-axum/Jenkinsfile.template +++ b/be-rust-axum/Jenkinsfile.template @@ -68,7 +68,7 @@ def stageCI(def context, def auditDependencies) { mkdir -p build/test-results/coverage # If required, pre-install llvm-tools-preview to avoid interactive prompt when not using default Jenkins agent toolchain - # rustup component add llvm-tools-preview --toolchain ${rustVersion} + # rustup component add llvm-tools-preview --toolchain ${RUST_VERSION} # Tests with JUnit XML report, as defined in .config/nextest.toml, and coverage LLVM cov report cargo llvm-cov nextest --profile ci --lcov --output-path ./build/test-results/coverage/lcov.info diff --git a/common/jenkins-agents/rust/docker/Dockerfile.ubi8 b/common/jenkins-agents/rust/docker/Dockerfile.ubi8 index 216ff1716..21f5d10bd 100644 --- a/common/jenkins-agents/rust/docker/Dockerfile.ubi8 +++ b/common/jenkins-agents/rust/docker/Dockerfile.ubi8 @@ -14,7 +14,8 @@ ENV USER="rust-agent" ENV CARGO_NEXTEST_VERSION=${cargoNextestVersion} \ CARGO_LLVM_COV_VERSION=${cargoLlvmCovVersion} \ CARGO_GENERATE_VERSION=${cargoGenerateVersion} \ - CARGO_DENY_VERSION=${cargoDenyVersion} + CARGO_DENY_VERSION=${cargoDenyVersion} \ + RUST_VERSION=${rustVersion} RUN yum install -y binutils cpp gcc glibc-devel glibc-headers isl kernel-headers libasan libatomic \ libgomp libmpc libpkgconf libubsan libxcrypt-devel llvm-libs pkgconf pkgconf-m4 pkgconf-pkg-config \