4 releases (2 breaking)
new 0.5.1 | Mar 22, 2025 |
---|---|
0.5.0 | Mar 22, 2025 |
0.4.1 | Mar 22, 2025 |
0.3.2 | Mar 8, 2025 |
#127 in HTTP client
136 downloads per month
70KB
704 lines
bitbucket-server-rs
A Rust client library for interacting with the Bitbucket Data Center REST API. This library provides a type-safe, ergonomic interface for Bitbucket Server (on-premise Bitbucket Data Center) operations, making it ideal for automation tools, CI/CD integrations, and Rust applications that need to interact with Bitbucket.
NOTE
At the moment this repo is used for learning purposes, so use it at your own risk. However, I do plan to use it in a real project in the near future, so I will be happy to accept contributions if you find it useful.
Features
- Type-safe API: Strongly typed interfaces for Bitbucket Server REST API endpoints
- Async/Await Support: Built on tokio and reqwest for modern asynchronous workflows
- Error Handling: Comprehensive error types for better error management
- Builder Pattern: Fluent API design for constructing requests
- JSON Serialization/Deserialization: Automatic handling of JSON payloads
Currently Supported APIs
- Build Status: Get and post build statuses for commits
- Pull Request Changes: Retrieve changes in pull requests
- Pull Request Creation: Create new pull requests
Installation
Add this to your Cargo.toml
:
[dependencies]
bitbucket-server-rs = "0.4.1"
tokio = { version = "1.0", features = ["full"] } # For async runtime
Usage
Creating a Client
use bitbucket_server_rs::client::new;
// Create a new client with base URL and API token
let client = new(
"https://bitbucket-server/rest", // Required: Base URL of your Bitbucket server
"YOUR_API_TOKEN" // Required: API token for authentication
);
Getting Build Status
use bitbucket_server_rs::Error;
use bitbucket_server_rs::client::{new, ApiRequest, ApiResponse};
use bitbucket_server_rs::api::build_status_get::BuildStatus;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = new(
"https://bitbucket-server/rest",
"YOUR_API_TOKEN"
);
// Get build status for a specific commit
let response = client
.api()
.build_status_get(
"PROJECT_KEY", // Required: Project key
"COMMIT_ID", // Required: Commit hash
"REPOSITORY_SLUG" // Required: Repository slug
)
.key("build-123") // Optional: Filter by build key
.build()?
.send()
.await?;
// Handle the response
match response {
Some(build_status) => {
println!("Build state: {:?}", build_status.state);
println!("Build URL: {}", build_status.url);
// Access other fields as needed
}
None => println!("No build status found")
}
Ok(())
}
Posting Build Status
use bitbucket_server_rs::client::new;
use bitbucket_server_rs::api::build_status::BuildStatusState;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = new(
"https://bitbucket-server/rest",
"YOUR_API_TOKEN"
);
// Post a build status for a commit
let response = client
.api()
.build_status_post(
"PROJECT_KEY", // Required: Project key
"COMMIT_ID", // Required: Commit hash
"REPOSITORY_SLUG" // Required: Repository slug
)
.key("build-123") // Required: Unique identifier for this build status
.state(BuildStatusState::Successful) // Required: Build state (Successful/Failed/InProgress)
.url("https://ci.example.com/build/123") // Required: URL to build details
.description("Build passed successfully") // Optional: Description of the build status
.name("CI Build") // Optional: Display name for this build
.build()?
.send()
.await?;
println!("Build status posted successfully");
Ok(())
}
Getting Pull Request Changes
use bitbucket_server_rs::client::new;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = new(
"https://bitbucket-server/rest",
"YOUR_API_TOKEN"
);
// Get changes for a pull request
let response = client
.api()
.pull_request_changes_get(
"PROJECT_KEY", // Required: Project key
"REPOSITORY_SLUG", // Required: Repository slug
123 // Required: Pull request ID
)
.start(0) // Optional: Starting position of the page (default: 0)
.limit(100) // Optional: Maximum number of changes to return (default: 100)
.build()?
.send()
.await?;
// Handle the response
if let Some(changes) = response {
println!("Found {} changes", changes.values.len());
for change in changes.values {
println!("Change: {:?}", change.path);
}
}
Ok(())
}
Creating a Pull Request
use bitbucket_server_rs::client::new;
use bitbucket_server_rs::api::pull_request_post::{
PullRequestPostPayload, RefInfo, RepositoryInfo, ProjectInfo, Reviewer, User
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = new(
"https://bitbucket-server/rest",
"YOUR_API_TOKEN"
);
// Create repository info (reused for both from and to refs)
let repository_info = RepositoryInfo {
slug: "my-repo".to_string(),
project: ProjectInfo {
key: "PROJECT_KEY".to_string(),
},
};
// Create pull request payload
let pull_request = PullRequestPostPayload {
title: "Add new feature".to_string(), // Required: PR title
description: Some("Implements the new feature".to_string()), // Optional: PR description
from_ref: RefInfo {
id: "refs/heads/feature-branch".to_string(), // Required: Source branch
repository: repository_info.clone(),
},
to_ref: RefInfo {
id: "refs/heads/main".to_string(), // Required: Target branch
repository: repository_info,
},
reviewers: Some(vec![Reviewer { // Optional: PR reviewers
user: User {
name: "reviewer1".to_string(),
},
}]),
};
// Create the pull request
let response = client
.api()
.pull_request_post(
"PROJECT_KEY", // Required: Project key
"my-repo", // Required: Repository slug
&pull_request
)
.send()
.await?;
println!("Pull request created successfully");
Ok(())
}
Custom HTTP Client Configuration
You can customize the HTTP client configuration:
use bitbucket_server_rs::client::{Client, new};
use reqwest::ClientBuilder;
// Create a custom HTTP client
let http_client = ClientBuilder::new()
.timeout(std::time::Duration::from_secs(30)) // Optional: Set custom timeout
.build()
.expect("Failed to build HTTP client");
// Create a new Bitbucket client
let mut client = new("https://bitbucket-server/rest", "API_TOKEN");
// Set the custom HTTP client (optional)
client.with_http_client(http_client);
CI/CD
This project uses GitHub Actions for continuous integration and deployment:
- PR Check: Runs tests and ensures version is bumped on pull requests
- Publish: Automatically publishes to crates.io when changes are merged to main
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature-name
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin feature-name
- Submit a pull request
Please make sure to update tests as appropriate and follow the Rust code style guidelines.
Version Bumping
When making changes, remember to bump the version in Cargo.toml
according
to Semantic Versioning principles:
- MAJOR version for incompatible API changes
- MINOR version for adding functionality in a backwards compatible manner
- PATCH version for backwards compatible bug fixes
The CI workflow will verify that the version has been bumped in pull requests.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
Dependencies
~6–22MB
~232K SLoC