use miette::Diagnostic;
use tracing::info;
use super::initialize_state;
use crate::{
app_config, config,
integrations::{
ApiRequestError, CreateReleaseInput, CreateReleaseResponse, git, handle_response,
},
state,
state::RunType,
};
pub(crate) fn create_release(
name: &str,
tag_name: &str,
body: &str,
prerelease: bool,
gitea_state: RunType<state::Gitea>,
gitea_config: &config::Gitea,
) -> Result<state::Gitea, Error> {
let target_commitish = git::get_head_commit_sha().ok();
let gitea_release = CreateReleaseInput::new(
tag_name,
name,
body,
prerelease,
false,
target_commitish.as_deref(),
);
let gitea_state = match gitea_state {
RunType::DryRun(state) => {
gitea_release_dry_run(name, gitea_config, &gitea_release);
return Ok(state);
}
RunType::Real(gitea_state) => gitea_state,
};
let (token, agent) = initialize_state(&gitea_config.host, gitea_state)?;
let resp = agent
.post(&gitea_config.get_releases_url())
.query("access_token", &token)
.send_json(gitea_release);
let resp = handle_response(
resp,
gitea_config.host.clone(),
"creating a release".to_string(),
)?;
resp.into_body()
.read_json::<CreateReleaseResponse>()
.map_err(|source| Error::ApiResponse {
source,
activity: "creating a release",
host: gitea_config.host.clone(),
})?;
Ok(state::Gitea::Initialized { token, agent })
}
fn gitea_release_dry_run(name: &str, config: &config::Gitea, gitea_release: &CreateReleaseInput) {
let release_type = if gitea_release.prerelease {
"prerelease"
} else {
"release"
};
let body = gitea_release.body.as_ref().map_or_else(
|| String::from("autogenerated body"),
|body| format!("body:\n{body}"),
);
let target = gitea_release
.target_commitish
.map_or_else(String::new, |sha| format!(" at commit {sha}"));
info!(
"Would create a {release_type} on Gitea [{host}] with name {name} and tag {tag}{target} and {body}",
tag = gitea_release.tag_name,
host = config.host
);
}
#[derive(Debug, Diagnostic, thiserror::Error)]
pub(crate) enum Error {
#[error(transparent)]
#[diagnostic(transparent)]
AppConfig(#[from] app_config::Error),
#[error(transparent)]
#[diagnostic(transparent)]
ApiRequest(#[from] ApiRequestError),
#[error("Trouble decoding the response from Gitea while {activity}: {source}")]
#[diagnostic(
code(gitea::api_response_error),
help(
"Failure to decode a response from the Gitea instance at {host} is probably a bug. Please report it at https://github.com/knope-dev/knope"
)
)]
ApiResponse {
source: ureq::Error,
activity: &'static str,
host: String,
},
}