It's no longer a test agent, it's the release one. We're including the package version (as specified in Cargo.toml).
132 lines
4.7 KiB
Rust
132 lines
4.7 KiB
Rust
use gt_tools::cli::Args;
|
|
use gt_tools::structs::release::{CreateReleaseOption, Release};
|
|
|
|
use clap::Parser;
|
|
|
|
use reqwest::header;
|
|
use reqwest::header::ACCEPT;
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), gt_tools::Error> {
|
|
let args = Args::parse();
|
|
|
|
let mut headers = reqwest::header::HeaderMap::new();
|
|
headers.append(ACCEPT, header::HeaderValue::from_static("application/json"));
|
|
|
|
// Gitea expects to see "token " for token auth.
|
|
if let Ok(token) = std::env::var("RELEASE_KEY_GITEA") {
|
|
let token = format!("token {token}");
|
|
headers.append("Authorization", token.parse().unwrap());
|
|
}
|
|
let client = reqwest::Client::builder()
|
|
.user_agent(format!(
|
|
"gt-tools-agent-{}",
|
|
env!("CARGO_PKG_VERSION")
|
|
))
|
|
.default_headers(headers)
|
|
.build()?;
|
|
|
|
match args.command {
|
|
gt_tools::cli::Commands::ListReleases => {
|
|
let releases =
|
|
gt_tools::api::release::list_releases(&client, &args.gitea_url, &args.repo).await?;
|
|
for release in releases {
|
|
println!("{:?}", release);
|
|
}
|
|
}
|
|
gt_tools::cli::Commands::CreateRelease {
|
|
name,
|
|
body,
|
|
draft,
|
|
prerelease,
|
|
tag_name,
|
|
target_commitish,
|
|
} => {
|
|
let submission = CreateReleaseOption {
|
|
body,
|
|
draft,
|
|
name,
|
|
prerelease,
|
|
tag_name,
|
|
target_commitish,
|
|
};
|
|
gt_tools::api::release::create_release(
|
|
&client,
|
|
&args.gitea_url,
|
|
&args.repo,
|
|
submission,
|
|
)
|
|
.await?;
|
|
}
|
|
gt_tools::cli::Commands::UploadRelease {
|
|
tag_name,
|
|
create,
|
|
files,
|
|
} => {
|
|
println!("Uploading files to a release!");
|
|
println!("Release Tag: {tag_name}");
|
|
println!("Creating?: {create}");
|
|
println!("Files...");
|
|
for file in &files {
|
|
println!("--- {file}");
|
|
}
|
|
// TODO: Pre-create the release, if it doesn't exist.
|
|
|
|
// There's only Gitea APIs to get all releases, or one by-id.
|
|
// Grab all, find the one that matches the input tag.
|
|
// Scream if there are multiple matches.
|
|
let release_candidates =
|
|
gt_tools::api::release::list_releases(&client, &args.gitea_url, &args.repo).await?;
|
|
|
|
if let Some(release) = match_release_by_tag(&tag_name, release_candidates) {
|
|
gt_tools::api::release_attachment::create_release_attachment(
|
|
&client,
|
|
&args.gitea_url,
|
|
&args.repo,
|
|
release.id,
|
|
files,
|
|
)
|
|
.await?;
|
|
} else {
|
|
println!("ERR: Couldn't find a release matching the tag \"{tag_name}\".");
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// Util to scan a release list for a given tag. Returns Some(release) if found,
|
|
// None if not, and crashes the program if multiple are found.
|
|
//
|
|
// The Gitea webpage won't create multiple releases for a given tag, but the
|
|
// API might... And someone could always fiddle with the database directly.
|
|
// Until I find a guarantee of any particular behavior, I'm going to assume it
|
|
// *can* happen and crash when it does. Clearly it isn't supposed to, so I'm
|
|
// not going to meaningfully handle it, only prevent garbage from propagating.
|
|
fn match_release_by_tag(tag: &String, releases: Vec<Release>) -> Option<Release> {
|
|
let mut release: Option<Release> = None;
|
|
for rel in releases {
|
|
if rel.tag_name == *tag {
|
|
// Only store the value if one hasn't been stored already
|
|
if let Some(first_release) = &release {
|
|
// if there was already a match, begin the error diagnostic creation.
|
|
let first_id = first_release.id;
|
|
let second_id = rel.id;
|
|
assert!(
|
|
first_id != second_id,
|
|
"FAILURE: Found the same release ID twice while scanning for duplicate tags. How did we get the same one twice?"
|
|
);
|
|
eprintln!("ERROR: Two releases have been found for the tag \"{tag}\".");
|
|
eprintln!("ERROR: first ID: {first_id}");
|
|
eprintln!("ERROR: second ID: {second_id}");
|
|
panic!("ERROR: Nonsense detected, I'm bailing out!");
|
|
} else {
|
|
// else, store our first (and hopefully only) match
|
|
release = Some(rel);
|
|
}
|
|
}
|
|
}
|
|
return release;
|
|
}
|