πΊπΈ English Β·
π¨π³ δΈζ
Β Β Β Β Β Β |Β Β Β Β Β
TableΒ ofΒ ContentsΒ
π¦ Jenkins API SDK in pure Rust β async and blocking clients, typed endpoints, pluggable middleware & zero magic strings.
| Feature | Description |
|---|---|
| Async and Blocking | Choose the I/O model at compile-time: async by default, enable blocking for non-async environments. |
| Core services | Discoverable client.jobs()/queue()/system()/... APIs β no manual path building. |
| Composable middleware | Ready-made CSRF-crumb fetching, retries, custom transports β just chain builders. |
| No magic strings | URL build, query/form encoding, error mapping & JSON decoding handled for you. |
| Pure Rust by default | Built on reqx; default TLS is rustls, with optional native-tls backend. |
Quick-glance architecture (click to collapse)
flowchart LR
%% ββ Your App ββββββββββββββββββββββββββ
subgraph A["Your App"]
direction TB
CLI["Binary / Service"]
end
%% ββ SDK Core ββββββββββββββββββββββββββ
subgraph S["jenkins-sdk-rust"]
direction LR
Builder["Client Builder"] --> Client["Jenkins<br/>Async / Blocking"] --> Middleware["Middleware<br/><sub>retry β’ crumbs β’ custom</sub>"] --> Service["Core Services<br/><sub>jobs β’ queue β’ system β’ ...</sub>"]
end
%% ββ External ββββββββββββββββββββββββββ
subgraph J["Jenkins Master"]
direction TB
API["REST API"]
end
%% ββ Flows βββββββββββββββββββββββββββββ
CLI --> Builder
Service --> API
%% ββ Styling βββββββββββββββββββββββββββ
classDef app fill:#e3f2fd,stroke:#1976d2,stroke-width:1px;
classDef sdk fill:#e8f5e9,stroke:#388e3c,stroke-width:1px;
classDef server fill:#fff8e1,stroke:#f57f17,stroke-width:1px;
class CLI app;
class Builder,Client,Middleware,Service sdk;
class API server;
| Service | APIs (core) | Status |
|---|---|---|
system() |
typed root/whoAmI/crumb + /overallLoad/api/json and /loadStatistics/api/json, /jnlpJars/agent.jar, /jnlpJars/jenkins-cli.jar, /config.xml get/update, /quietDown/cancelQuietDown/reload/safeRestart/restart/exit |
β |
jobs() |
typed list/get + typed lastBuild selectors/build info, consoleText, logText/progressiveText, artifact download, stop/term/kill/doDelete/toggleLogKeep/submitDescription, config.xml get/update, createItem(xml), copy/rename/delete/enable/disable |
β |
queue() |
typed list/item + cancel | β |
computers() |
typed list/computer + typed executors_info(), doCreateItem(xml)/copy, toggleOffline/doDelete, config.xml get/update, connect/disconnect/launchSlaveAgent |
β |
views() |
typed list/get, createView(xml), config.xml get/update, doDelete/doRename, addJobToView/removeJobFromView |
β |
users() |
typed /user/<id>/api/json, typed /whoAmI/api/json, config.xml get/update |
β |
people() |
typed /people/api/json, typed /asynchPeople/api/json |
β |
# quickest
cargo add jenkins-sdk# Cargo.toml β async client (default)
[dependencies]
jenkins-sdk = "0.1"
# async client with explicit TLS backend
# jenkins-sdk = { version = "0.1", default-features = false, features = ["async-rustls-ring"] }
# jenkins-sdk = { version = "0.1", default-features = false, features = ["async-rustls-aws-lc-rs"] }
# jenkins-sdk = { version = "0.1", default-features = false, features = ["async-native-tls"] }
# blocking client (choose one TLS backend)
# jenkins-sdk = { version = "0.1", default-features = false, features = ["blocking-rustls-ring"] }
# jenkins-sdk = { version = "0.1", default-features = false, features = ["blocking-rustls-aws-lc-rs"] }
# jenkins-sdk = { version = "0.1", default-features = false, features = ["blocking-native-tls"] }Base URL can include a sub-path (e.g.
https://example.com/jenkins); a trailing/is optional, the SDK normalises it for you.
use jenkins_sdk::{Client, TlsRootStore};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), jenkins_sdk::Error> {
// Build a client with some sugar:
let j = Client::builder("https://jenkins.example.com")?
.auth_basic("user", "apitoken")
// Optional: choose runtime trust roots explicitly.
.tls_root_store(TlsRootStore::BackendDefault)
.with_retry(3, Duration::from_millis(300))
.with_crumb(Duration::from_secs(1800))
.build()?;
// Queue length
let q = j.queue().list(None).await?;
println!("queue items = {}", q.items.len());
// Executor stats (typed deserialisation)
let mut ex = j.computers().executors_info().await?;
ex = ex.calc_idle();
println!("idle executors = {}", ex.idle_executors);
// Typed job list
let jobs = j.jobs().list().await?;
if let Some(first) = jobs.jobs.first() {
println!("first job = {}", first.name);
}
Ok(())
}By default, system proxy environment variables (HTTP_PROXY/HTTPS_PROXY/NO_PROXY) are respected.
Call .no_system_proxy() to disable that behavior for this client.
// Compile with one of:
// `default-features = false, features = ["blocking-rustls-ring"]`
// `default-features = false, features = ["blocking-rustls-aws-lc-rs"]`
// `default-features = false, features = ["blocking-native-tls"]`.
use jenkins_sdk::BlockingClient;
use std::time::Duration;
fn main() -> Result<(), jenkins_sdk::Error> {
let j = BlockingClient::builder("https://jenkins.example.com")?
.auth_basic("user", "apitoken")
.timeout(Duration::from_secs(15))
.with_retry(2, Duration::from_millis(250))
.build()?;
let q = j.queue().list(None)?;
println!("queue items = {}", q.items.len());
Ok(())
}Note: when using the blocking client inside a Tokio runtime, call it via
tokio::task::spawn_blockingor a dedicated thread pool.
See CHANGELOG.md for release notes.
This project is licensed under the MIT License.