From 5b86be0fbc94a3728fb5c7a1964648021e85c7de Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Thu, 12 Jun 2025 08:09:29 +0200 Subject: [PATCH] chore: add README file --- README.md | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..0331b19 --- /dev/null +++ b/README.md @@ -0,0 +1,161 @@ +# `radicle-job` + +A crate for all† your automated job needs on the [Radicle +Network](https://radicle.xyz). + +†: _well maybe almost all._ + +## Overview + +`radicle-job` provides a collaborative framework for managing automated tasks +across the Radicle peer-to-peer network. Multiple nodes can pick up and execute +jobs (like CI/CD pipelines) for any given Git commit, with results synchronized +across the network using Radicle's Collaborative Objects (COBs). + +### Key Features + +- **Decentralized Execution**: Any node in the network can pick up and run jobs +- **Collaborative Tracking**: Multiple nodes can contribute runs for the same + job +- **Rich Status Reporting**: Track job lifecycle from start to completion with + success/failure reasons +- **External Log Integration**: Link to external logging services via URLs +- **Git Integration**: Jobs are tied to specific Git commits using OIDs + +## Key Concepts + +- **Job**: Represents an automated task for a specific Git commit that can be + executed by multiple nodes +- **Run**: A single execution attempt of a job by a particular node, identified + by a UUID +- **Status**: The current state of a run (`Started`, `Finished(Succeeded)`, + `Finished(Failed)`) +- **COB (Collaborative Object)**: The underlying Radicle primitive that enables + decentralized synchronization of job data + +## Installation + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +radicle-job = "0.1" +radicle >= "0.15" # Required for core Radicle functionality +``` + +This crate is designed to work seamlessly with the +[`radicle`](https://crates.io/crates/radicle) ecosystem. + +## Quick Start + +### Creating and Managing Jobs + +```rust +use radicle_job::{Jobs, Reason}; +use radicle::git::Oid; +use url::Url; +use uuid::Uuid; + +// Open the jobs store for a repository +let mut jobs = Jobs::open(&repo)?; + +// Create a new job for a specific commit +let commit_oid = /* your commit OID */; +let mut job = jobs.create(commit_oid, &signer)?; + +// Node starts a run +let run_id = Uuid::new_v4(); +let log_url = Url::parse("https://ci.example.com/logs/run-123")?; +job.run(run_id, log_url, &signer)?; + +// Node reports completion +job.finish(run_id, Reason::Succeeded, &signer)?; +``` + +### Querying Job Status + +```rust +// Get all runs that are currently in progress +let started_runs = job.started(); + +// Get successful runs from all nodes +let successful_runs = job.succeeded(); + +// Get the latest run from a specific node +if let Some((uuid, run)) = job.latest_of(&node_id) { + println!("Latest run: {} - Status: {:?}", uuid, run.status()); + println!("Logs available at: {}", run.log()); +} + +// Partition runs by status +let all_nodes_status = job.partition(); +for (node_id, (started, succeeded, failed)) in all_nodes_status { + println!("Node {}: {} started, {} succeeded, {} failed", + node_id, started.len(), succeeded.len(), failed.len()); +} +``` + +## Use Cases + +### Continuous Integration + +The primary use case is distributed CI execution: + +1. A developer creates a patch +2. The job is broadcast to the network +3. Available CI nodes pick up the job and execute tests +4. Results are reported back with logs and status +5. The developer can see which nodes ran CI and their results + +### Future Possibilities + +- **Continuous Deployment**: Automated deployment pipelines +- **Code Analysis**: Static analysis, security scanning, performance + benchmarking +- **Marketplace**: Nodes could offer specialized compute resources for different + job types + +## API Overview + +### Core Types + +- **`Jobs`**: The main store for managing jobs in a repository +- **`Job`**: A read-only view of a job and its runs across all nodes +- **`JobMut`**: A mutable job handle for adding runs and updating status +- **`Run`**: Represents a single execution attempt with status and log URL +- **`Runs`**: A collection of runs with insertion-order iteration + +### Key Methods + +- **`Jobs::create()`**: Create a new job for a commit +- **`Jobs::get()`** / **`Jobs::get_mut()`**: Retrieve existing jobs +- **`JobMut::run()`**: Start a new run +- **`JobMut::finish()`**: Mark a run as completed +- **`Job::latest()`**: Get the most recent run + +## Collaborative Nature + +Jobs in `radicle-job` are inherently collaborative: + +- **Multiple Executors**: Many nodes can run the same job independently +- **Decentralized Results**: Each node reports its own results without requiring + coordination +- **Automatic Synchronization**: The Radicle protocol handles data + synchronization across nodes +- **No Consensus Required**: This crate doesn't enforce consensus on results — + that's left to higher-level applications + +This design enables resilient, distributed job execution where no single point +of failure can prevent job completion. + +## License + +This project is licensed under the [MIT License](LICENSE-MIT) or [Apache License +2.0](LICENSE-APACHE) at your option. + +## Related Projects + +- [`radicle`](https://crates.io/crates/radicle) - Core Radicle protocol + implementation +- [`radicle-ci-broker`](https://crates.io/crates/radicle-ci-broker) - Radicle + library for brokering CI events