302 lines
7.4 KiB
Rust
302 lines
7.4 KiB
Rust
use reqwest::Client;
|
|
use semver::Version;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(serde::Deserialize, serde::Serialize)]
|
|
pub struct GitCommit {
|
|
pub commit: GitCommitDetails,
|
|
pub sha: String,
|
|
}
|
|
|
|
#[derive(serde::Deserialize, serde::Serialize)]
|
|
pub struct GitCommitDetails {
|
|
pub message: String,
|
|
}
|
|
|
|
pub async fn get_pull_request_commits(
|
|
base_url: &str,
|
|
owner: &str,
|
|
repo: &str,
|
|
pull_request_id: u32,
|
|
access_token: &str,
|
|
) -> eyre::Result<Vec<String>> {
|
|
let client = Client::new();
|
|
|
|
let api_url = format!(
|
|
"{}/api/v1/repos/{}/{}/pulls/{}/commits",
|
|
base_url, owner, repo, pull_request_id
|
|
);
|
|
|
|
let response = client
|
|
.get(&api_url)
|
|
.bearer_auth(access_token)
|
|
.send()
|
|
.await?;
|
|
|
|
let commits: Vec<GitCommit> = response.json().await?;
|
|
|
|
let mut commit_titles = Vec::new();
|
|
|
|
tracing::debug!(
|
|
commits = serde_json::to_string(&commits)?,
|
|
"fetched commits"
|
|
);
|
|
|
|
for entry in commits {
|
|
commit_titles.push(entry.commit.message);
|
|
}
|
|
|
|
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;
|
|
|
|
use super::*;
|
|
|
|
#[tokio::test]
|
|
#[traced_test]
|
|
async fn test_get_pull_request_commits() {
|
|
dotenv::dotenv().unwrap();
|
|
|
|
let base_url = "https://git.front.kjuulh.io";
|
|
let owner = "kjuulh";
|
|
let repo = "test-repo";
|
|
let pull_request_id = 3;
|
|
let access_token = &std::env::var("GITEA_ACCESS_TOKEN").unwrap();
|
|
|
|
let commits =
|
|
get_pull_request_commits(base_url, owner, repo, pull_request_id, access_token)
|
|
.await
|
|
.unwrap();
|
|
|
|
assert!(
|
|
!commits.is_empty(),
|
|
"Expected at least one commit in the pull request"
|
|
);
|
|
|
|
// You can add more assertions here to check the contents of the commits vector
|
|
}
|
|
}
|