jenkins-sdk

Crates.iojenkins-sdk
lib.rsjenkins-sdk
version0.1.16
created_at2025-02-28 14:42:01.329398+00
updated_at2026-01-13 14:32:56.968107+00
descriptionJenkins API SDK in pure Rust with async and blocking clients, typed endpoints, pluggable middleware, and zero magic strings.
homepagehttps://github.com/lvillis/jenkins-sdk-rust
repositoryhttps://github.com/lvillis/jenkins-sdk-rust
max_upload_size
id1572887
size275,389
(lvillis)

documentation

https://github.com/lvillis/jenkins-sdk-rust#readme

README

🇺🇸 English · 🇨🇳 中文       |      Table of Contents ↗️

jenkins-sdk-rust

📦 Jenkins API SDK in pure Rust — async and blocking clients, typed endpoints, pluggable middleware & zero magic strings.

crates.io version docs.rs docs CI status downloads repo size say thanks

✨ Features

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, tiny deps Built on reqwest + rustls; no C bindings, minimal footprint.

🖼 Architecture

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&nbsp;Builder"] --> Client["Jenkins<br/>Async&nbsp;/&nbsp;Blocking"] --> Middleware["Middleware<br/><sub>retry • crumbs • custom</sub>"] --> Service["Core&nbsp;Services<br/><sub>jobs • queue • system • ...</sub>"]
  end

%% ── External ──────────────────────────
  subgraph J["Jenkins&nbsp;Master"]
    direction TB
    API["REST&nbsp;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;

🚀 Supported API Matrix

Service APIs (core) Status
system() /api/json, /whoAmI/api/json, /crumbIssuer/api/json, /overallLoad/api/json, /loadStatistics/api/json, /jnlpJars/agent.jar, /jnlpJars/jenkins-cli.jar, /config.xml get/update, /quietDown/cancelQuietDown/reload/safeRestart/restart/exit
jobs() list/get + 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() list/item/cancel
computers() list/computer + typed executors_info(), doCreateItem(xml)/copy, toggleOffline/doDelete, config.xml get/update, connect/disconnect/launchSlaveAgent
views() list/get, createView(xml), config.xml get/update, doDelete/doRename, addJobToView/removeJobFromView
users() /user/<id>/api/json, /whoAmI/api/json, config.xml get/update
people() /people/api/json, /asynchPeople/api/json

📥 Installation

# quickest
cargo add jenkins-sdk
# Cargo.toml — async client (default)
[dependencies]
jenkins-sdk = "0.1"

# blocking client (choose one TLS backend)
# jenkins-sdk = { version = "0.1", default-features = false, features = ["blocking", "rustls"] }
# jenkins-sdk = { version = "0.1", default-features = false, features = ["blocking", "native-tls"] }

⚡Quick Start

Base URL can include a sub-path (e.g. https://example.com/jenkins); a trailing / is optional, the SDK normalises it for you.

Async Example

use jenkins_sdk::Client;
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")
    .no_system_proxy()
    .with_retry(3, Duration::from_millis(300))
    .with_crumb(Duration::from_secs(1800))
    .build()?;

  // Queue length
  let q: serde_json::Value = j.queue().list(None).await?;
  println!("queue items = {}", q["items"].as_array().map_or(0, |a| a.len()));

  // Executor stats (typed deserialisation)
  let mut ex = j.computers().executors_info().await?;
  ex = ex.calc_idle();
  println!("idle executors = {}", ex.idle_executors);

  // Raw job list
  let jobs: serde_json::Value = j.jobs().list().await?;
  println!("first job = {}", jobs["jobs"][0]["name"]);

  Ok(())
}

Blocking Example

// Compile with `default-features = false, features = ["blocking", "rustls"]`
// or `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: serde_json::Value = j.queue().list(None)?;
  println!("queue items = {}", q["items"].as_array().unwrap().len());
  Ok(())
}

Any Endpoint (Unstable Raw Request)

Enable the unstable-raw feature and use raw::Request + execute() when an API endpoint isn't modeled yet:

use jenkins_sdk::Client;
use jenkins_sdk::raw::Request;

# async fn demo(client: Client) -> Result<(), jenkins_sdk::Error> {
  let resp = client
    .execute(&Request::get(["api", "json"]).query_pair("tree", "jobs[name]"))
    .await?;
  let root: serde_json::Value = resp.json()?;
  println!("{root:?}");
  # Ok(())
  #
}

Note: when using the blocking client inside a Tokio runtime, call it via tokio::task::spawn_blocking or a dedicated thread pool.

📜 Changelog

See CHANGELOG.md for release notes.

📃 License

This project is licensed under the MIT License.

Commit count: 56

cargo fmt