use async_trait::async_trait;
use crate::ci::error::{CiError, Result};
use crate::ci::model::{
Capabilities, CiRun, DagSource, JobId, LogChunk, LogMode, PrComment, PullRequest, RunDetail,
RunExtras, RunId,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ProviderKind {
GitHub,
GitLab,
Forgejo,
}
pub fn capabilities_for(kind: ProviderKind) -> Capabilities {
match kind {
ProviderKind::GitHub => Capabilities {
dag: DagSource::ConfigFile,
logs: LogMode::Dump,
resolve_threads: true,
},
ProviderKind::GitLab => Capabilities {
dag: DagSource::RunApi,
logs: LogMode::Poll,
resolve_threads: true,
},
ProviderKind::Forgejo => Capabilities {
dag: DagSource::None,
logs: LogMode::None,
resolve_threads: false,
},
}
}
#[async_trait]
pub trait ForgeProvider: Send + Sync {
fn kind(&self) -> ProviderKind;
fn capabilities(&self) -> Capabilities {
capabilities_for(self.kind())
}
async fn list_runs(&self, limit: usize) -> Result<Vec<CiRun>>;
async fn run_detail(&self, run: &RunId) -> Result<RunDetail>;
async fn job_log(&self, run: &RunId, job: &JobId, offset: u64) -> Result<LogChunk>;
async fn run_extras(&self, run: &RunId) -> Result<RunExtras>;
async fn current_pr(&self) -> Result<Option<PullRequest>>;
async fn list_prs(&self) -> Result<Vec<PullRequest>>;
async fn pr_comments(&self, _number: u64) -> Result<Vec<PrComment>> {
Ok(Vec::new())
}
async fn post_pr_comment(&self, _new: &NewPrComment) -> Result<PrComment> {
Err(CiError::Unsupported("posting PR comments"))
}
async fn reply_pr_comment(
&self,
_number: u64,
_remote_id: &str,
_body: &str,
) -> Result<PrComment> {
Err(CiError::Unsupported("replying to PR comments"))
}
async fn submit_pr_review(&self, _review: &NewPrReview) -> Result<()> {
Err(CiError::Unsupported("submitting PR reviews"))
}
async fn resolve_pr_thread(
&self,
_number: u64,
_thread_id: &str,
_resolved: bool,
) -> Result<()> {
Err(CiError::Unsupported("resolving PR threads"))
}
async fn update_pr_comment(&self, _number: u64, _remote_id: &str, _body: &str) -> Result<()> {
Err(CiError::Unsupported("editing PR comments"))
}
async fn delete_pr_comment(&self, _number: u64, _remote_id: &str) -> Result<()> {
Err(CiError::Unsupported("deleting PR comments"))
}
async fn pr(&self, _number: u64) -> Result<PullRequest> {
Err(CiError::Unsupported("PR lookup"))
}
async fn create_pr(&self, _new: &NewPullRequest) -> Result<PullRequest> {
Err(CiError::Unsupported("opening a pull request"))
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NewPullRequest {
pub base: String,
pub head: String,
pub title: String,
pub body: String,
pub draft: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReviewVerdict {
Approve,
RequestChanges,
Comment,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NewPrReview {
pub number: u64,
pub head_oid: String,
pub verdict: ReviewVerdict,
pub body: String,
pub comments: Vec<NewPrComment>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NewPrComment {
pub number: u64,
pub head_oid: String,
pub path: String,
pub line: u32,
pub start_line: Option<u32>,
pub new_side: bool,
pub counterpart: Option<u32>,
pub body: String,
}