feat: with proper semver releaser

This commit is contained in:
2023-04-07 15:25:02 +02:00
parent fc1ec96eab
commit 03cd8ba20f
3 changed files with 391 additions and 10 deletions

View File

@@ -1,14 +1,17 @@
use reqwest::Client;
use semver::Version;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
#[derive(serde::Deserialize, serde::Serialize)]
pub struct GitCommit {
commit: GitCommitDetails,
pub commit: GitCommitDetails,
pub sha: String,
}
#[derive(serde::Deserialize, serde::Serialize)]
pub struct GitCommitDetails {
message: String,
pub message: String,
}
pub async fn get_pull_request_commits(
@@ -47,6 +50,226 @@ pub async fn get_pull_request_commits(
Ok(commit_titles)
}
#[derive(Serialize, Deserialize, Debug)]
pub struct ReleaseRequest {
pub tag_name: String,
pub target_commitish: String,
pub name: String,
pub body: String,
pub draft: bool,
pub prerelease: bool,
}
#[derive(Deserialize, Debug)]
pub struct ReleaseResponse {
pub id: u64,
pub url: String,
// Add other fields as needed
}
pub async fn create_gitea_release(
base_url: &str,
owner: &str,
repo: &str,
access_token: &str,
release_request: &ReleaseRequest,
) -> eyre::Result<ReleaseResponse> {
let client = Client::new();
let releases_url = format!("{}/api/v1/repos/{}/{}/releases", base_url, owner, repo);
let response = client
.post(&releases_url)
.bearer_auth(access_token)
.json(release_request)
.send()
.await?;
if !response.status().is_success() {
eyre::bail!("failed to handle request: {}", response.text().await?);
}
let response = response.json::<ReleaseResponse>().await?;
Ok(response)
}
#[derive(Deserialize, Debug, Clone)]
pub struct Release {
pub id: u64,
pub tag_name: String,
pub draft: bool,
pub prerelease: bool, // Add other fields as needed
pub target_commitish: String,
pub name: String,
pub body: String,
}
pub async fn get_newest_release(
base_url: &str,
owner: &str,
repo: &str,
personal_access_token: &str,
) -> eyre::Result<Release> {
let client = Client::new();
let releases_url = format!("{}/api/v1/repos/{}/{}/releases", base_url, owner, repo);
let response = client
.get(&releases_url)
.bearer_auth(personal_access_token)
.send()
.await?;
if !response.status().is_success() {
eyre::bail!("failed to handle request: {}", response.text().await?);
}
let response = response.json::<Vec<Release>>().await?;
match response.first() {
Some(release) => Ok(release.clone()),
None => Err(eyre::anyhow!("No releases found")),
}
}
pub async fn is_newest_release_draft(
gitea_base_url: &str,
owner: &str,
repo: &str,
personal_access_token: &str,
) -> eyre::Result<(bool, Release)> {
let release = get_newest_release(gitea_base_url, owner, repo, personal_access_token).await?;
Ok((release.draft, release))
}
#[derive(Serialize, Debug)]
pub struct UpdateReleaseRequest {
pub tag_name: Option<String>,
pub target_commitish: Option<String>,
pub name: Option<String>,
pub body: Option<String>,
pub draft: Option<bool>,
pub prerelease: Option<bool>,
}
pub async fn modify_release(
base_url: &str,
owner: &str,
repo: &str,
token: &str,
release_id: u64,
update_request: &UpdateReleaseRequest,
) -> eyre::Result<Release> {
tracing::info!(
base_url = base_url,
owner = owner,
repo = repo,
release_id = release_id,
"modifying release"
);
let client = Client::new();
let release_url = format!(
"{}/api/v1/repos/{}/{}/releases/{}",
base_url, owner, repo, release_id
);
let response = client
.patch(&release_url)
.bearer_auth(token)
.json(&update_request)
.send()
.await?;
if !response.status().is_success() {
eyre::bail!("failed to handle request: {}", response.text().await?);
}
let response = response.json::<Release>().await?;
Ok(response)
}
#[derive(Deserialize, Debug)]
pub struct Commit {
pub sha: String,
}
#[derive(Deserialize, Debug)]
pub struct Tag {
pub name: String,
pub commit: Commit, // Add other fields as needed
}
pub async fn get_highest_semver_from_tags(
base_url: &str,
owner: &str,
repo: &str,
token: &str,
) -> eyre::Result<(Version, Tag)> {
let client = Client::new();
let tags_url = format!("{}/api/v1/repos/{}/{}/tags", base_url, owner, repo);
let response = client.get(&tags_url).bearer_auth(token).send().await?;
if !response.status().is_success() {
eyre::bail!("failed to handle request: {}", response.text().await?);
}
let response = response.json::<Vec<Tag>>().await?;
let highest_version = response
.into_iter()
.filter_map(|tag| {
Version::parse(&tag.name.replace("v", ""))
.and_then(|v| Ok((v, tag)))
.ok()
})
.max_by(|(x, _), (y, _)| x.cmp(y));
match highest_version {
Some(version) => Ok(version),
None => Err(eyre::anyhow!("No valid SemVer tags found",)),
}
}
pub async fn get_commits_from_commit_to_newest(
base_url: &str,
owner: &str,
repo: &str,
token: &str,
branch: &str,
start_commit_sha: &str,
) -> eyre::Result<Vec<GitCommit>> {
let client = Client::new();
let commits_url = format!(
"{}/api/v1/repos/{}/{}/commits?sha={}",
base_url, owner, repo, branch
);
let response = client.get(&commits_url).bearer_auth(token).send().await?;
if !response.status().is_success() {
eyre::bail!("failed to handle request: {}", response.text().await?);
}
//tracing::info!(request = response.text().await?, "test");
let mut response = response.json::<Vec<GitCommit>>().await?;
//let mut response: Vec<GitCommit> = Vec::new();
let index_of_start_commit = response
.iter()
.position(|commit| commit.sha == start_commit_sha);
match index_of_start_commit {
Some(index) => {
response.truncate(index);
Ok(response)
}
None => Err(eyre::anyhow!("Start commit not found",)),
}
}
#[cfg(test)]
mod tests {
use tracing_test::traced_test;