mirror of
https://seed.radicle.dev/rad:z2UcCU1LgMshWvXj6hXSDDrwB8q8M.git
synced 2026-10-18 19:30:30 +08:00
chore: add README file
This commit is contained in:
@@ -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<R>`**: 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
|
||||||
Reference in New Issue
Block a user