diff --git a/src/errors.rs b/src/errors.rs index 44b55de..1cf1228 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -59,6 +59,9 @@ pub enum ApiError { #[error("Not Found Repo: {0}")] NotFoundRepo(anyhow::Error), + + #[error("Bad Playbook Request: {0}")] + BadPlaybookRequest(String), } impl IntoResponse for ApiError { @@ -76,6 +79,7 @@ impl IntoResponse for ApiError { Self::FailedToSynchronize(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), Self::BadPlaybook(e) => (StatusCode::BAD_REQUEST, e.to_string()), Self::NotFoundRepo(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), + Self::BadPlaybookRequest(e) => (StatusCode::BAD_REQUEST, e.to_string()), }; error!("{} - {}", status, message); diff --git a/src/requests/playbook.rs b/src/requests/playbook.rs index 2828966..2b10d49 100644 --- a/src/requests/playbook.rs +++ b/src/requests/playbook.rs @@ -17,6 +17,18 @@ use utoipa::ToSchema; #[derive(Debug, Serialize, Deserialize, ToSchema)] pub struct CreatePlaybookRequest { + /// Source code repository the partner should be cloned from. + /// e.g. https://github.com/amphitheatre-app/amphitheatre.git. pub repo: String, - pub reference: Option, + /// Git branch the partner should be cloned from. eg. master or main + #[serde(skip_serializing_if = "Option::is_none")] + pub branch: Option, + /// Git tag the partner should be cloned from. eg. v1.0 + #[serde(skip_serializing_if = "Option::is_none")] + pub tag: Option, + /// A commit hash like rev = "4c59b707", or a named reference exposed by + /// the remote repository such as rev = "refs/pull/493/head". What references + /// are available varies by where the repo is hosted. + #[serde(skip_serializing_if = "Option::is_none")] + pub rev: Option, } diff --git a/src/services/folder.rs b/src/services/folder.rs index b9dea82..cb1dfa9 100644 --- a/src/services/folder.rs +++ b/src/services/folder.rs @@ -31,7 +31,7 @@ impl FolderService { ctx.github_client .contents() - .list(&utils::repo(&source.repo)?, &path.unwrap_or_default(), &source.branch.unwrap_or_default()) + .list(&utils::repo(&source.repo)?, &path.unwrap_or_default(), &source.reference().unwrap()) .map_err(|e| ApiError::NotFoundContent(e.to_string())) } @@ -41,11 +41,7 @@ impl FolderService { ctx.github_client .git() - .get_tree( - &utils::repo(&source.repo)?, - &source.branch.unwrap_or_default(), - Option::from(recursive.is_some()), - ) + .get_tree(&utils::repo(&source.repo)?, &source.reference().unwrap(), Option::from(recursive.is_some())) .map_err(|e| ApiError::NotFoundFolder(e.to_string()))? .ok_or(ApiError::NotFoundFolder("The folder is none".to_string())) } diff --git a/src/services/playbook.rs b/src/services/playbook.rs index 978321a..19a3e25 100644 --- a/src/services/playbook.rs +++ b/src/services/playbook.rs @@ -33,15 +33,19 @@ impl PlaybookService { let repo = repo(&req.repo)?; let repository = ctx.github_client.repositories().find(&repo).map_err(ApiError::NotFoundRepo)?; let description = repository.and_then(|r| r.description).unwrap_or_default(); - let preface = Preface { - name: req.repo.clone(), - repository: Some(GitReference { - repo: req.repo.clone(), - branch: req.reference.clone(), - ..GitReference::default() - }), - ..Preface::default() + let repository = GitReference { + repo: req.repo.clone(), + branch: req.branch.clone(), + tag: req.tag.clone(), + rev: req.rev.clone(), + ..GitReference::default() }; + if repository.reference().is_none() { + return Err(ApiError::BadPlaybookRequest( + "branch tag rev All three fields cannot be empty, as long as one of them has a value".to_string(), + )); + } + let preface = Preface { name: req.repo.clone(), repository: Some(repository), ..Preface::default() }; let payload = PlaybookPayload { title: repo, description, preface }; ctx.client.playbooks().create(payload).map_err(ApiError::FailedToCreatePlaybook)