Files
releaser/src/main.rs
2023-04-07 15:25:34 +02:00

199 lines
7.6 KiB
Rust

mod gitea;
mod semantic;
mod validate_pr;
use clap::Command;
use tracing_subscriber::{filter::LevelFilter, EnvFilter};
use self::gitea::{get_highest_semver_from_tags, ReleaseRequest, UpdateReleaseRequest};
const VERSION: &'static str = "<dev>";
#[tokio::main]
async fn main() -> eyre::Result<()> {
if let Err(e) = dotenv::dotenv() {
tracing::debug!(error = e.to_string(), "could not load.env")
}
color_eyre::install().unwrap();
let matches = clap::Command::new("releaser")
.version(VERSION)
.author("kjuulh <contact@kjuulh.io>")
.about("A CLI app for releasing software and managing versions")
.arg(
clap::Arg::new("quiet")
.long("quiet")
.short('q')
.action(clap::ArgAction::SetTrue),
)
.subcommand(Command::new("release").about("Release the software"))
.subcommand(
Command::new("validate").about("Validate the semantic versioning of the software"),
)
.subcommand(
Command::new("validate:pr")
.about("Validate the semantic versioning of the software")
.arg(clap::Arg::new("owner").long("owner").required(true))
.arg(clap::Arg::new("repo").long("repo").required(true))
.arg(
clap::Arg::new("pull_request_id")
.long("pull-request-id")
.required(true)
.value_parser(clap::value_parser!(u32).range(0..)),
)
.arg(
clap::Arg::new("current_version")
.long("current-version")
.required(true),
),
)
.subcommand(
Command::new("bump")
.about("Bump the semantic versioning in git tags")
.arg(clap::Arg::new("owner").long("owner").required(true))
.arg(clap::Arg::new("repo").long("repo").required(true))
.arg(clap::Arg::new("branch").long("branch").required(true)),
)
.subcommand(
Command::new("release:gitea")
.about("Create a release on gitea")
.arg(clap::Arg::new("owner").long("owner").required(true))
.arg(clap::Arg::new("repo").long("repo").required(true))
.arg(clap::Arg::new("version").long("version").required(true))
.arg(clap::Arg::new("branch").long("branch").required(true))
.arg(
clap::Arg::new("generate-changelog")
.long("generate-changelog")
.action(clap::ArgAction::SetTrue),
),
)
.get_matches();
let quiet = matches.get_one::<bool>("quiet");
match quiet {
Some(true) => {}
_ => {
tracing_subscriber::fmt()
.pretty()
.with_env_filter(
EnvFilter::from_default_env().add_directive(LevelFilter::INFO.into()),
)
.init();
}
}
let base_url = &std::env::var("GITEA_BASE_URL").unwrap();
let token = &std::env::var("GITEA_ACCESS_TOKEN").unwrap();
match matches.subcommand() {
Some(("release", _sub_matches)) => {}
Some(("validate", _sub_matches)) => {}
Some(("validate:pr", sub_matches)) => {
let owner = sub_matches.get_one::<String>("owner").unwrap();
let repo = sub_matches.get_one::<String>("repo").unwrap();
let pull_request_id = sub_matches.get_one::<u32>("pull_request_id").unwrap();
let current_version = sub_matches.get_one::<String>("current_version").unwrap();
match validate_pr::validate_pr(&owner, &repo, *pull_request_id, &current_version)
.await?
{
Some(version) => {
tracing::info!(version = version, "bumping version");
print!("{}\n", version)
}
None => tracing::info!(version = current_version, "no version bump required!"),
}
}
Some(("bump", sub_matches)) => {
let owner = sub_matches.get_one::<String>("owner").unwrap();
let repo = sub_matches.get_one::<String>("repo").unwrap();
let branch = sub_matches.get_one::<String>("branch").unwrap();
let default_version = "0.0.0";
let _version = match get_highest_semver_from_tags(base_url, owner, repo, token).await {
Ok((version, tag)) => {
tracing::debug!(version = version.to_string(), "got tag from repo");
match validate_pr::validate_commits(
&owner,
&repo,
&tag.commit.sha,
branch,
&version.to_string(),
)
.await?
{
Some(version) => {
tracing::info!(version = version, "bumping version");
print!("{}\n", version)
}
None => {
tracing::info!(version = default_version, "no version bump required!")
}
}
version.to_string()
}
_ => default_version.to_string(),
};
}
Some(("release:gitea", sub_matches)) => {
let default_generate_changelog = false;
let owner = sub_matches.get_one::<String>("owner").unwrap();
let repo = sub_matches.get_one::<String>("repo").unwrap();
let version = sub_matches.get_one::<String>("version").unwrap();
let branch = sub_matches.get_one::<String>("branch").unwrap();
let _generate_changelog = sub_matches
.get_one::<bool>("generate-changelog")
.unwrap_or(&default_generate_changelog);
match crate::gitea::is_newest_release_draft(base_url, owner, repo, token).await {
Ok((true, release)) => {
let _resp = crate::gitea::modify_release(
base_url,
owner,
repo,
token,
release.id,
&UpdateReleaseRequest {
body: None,
draft: Some(release.draft),
tag_name: Some(version.clone()),
name: Some(version.clone()),
prerelease: None,
target_commitish: Some(branch.clone()),
},
)
.await?;
tracing::info!("updated release")
}
_ => {
let resp = crate::gitea::create_gitea_release(
base_url,
owner,
repo,
token,
&ReleaseRequest {
tag_name: version.clone(),
target_commitish: branch.clone(),
name: version.clone(),
body: "".into(),
draft: true,
prerelease: false,
},
)
.await?;
tracing::info!(url = resp.url, "created release")
}
}
}
_ => unreachable!(),
}
Ok(())
}