use std::time::Duration;
use url::Url;
use vgi_forge::{ForgeError, Result};
pub const DEFAULT_CHECKOUT_ACTION: &str =
"actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1";
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[non_exhaustive]
pub enum JwtIssuer {
#[default]
ClientId,
AppId,
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct GitHubConfig {
pub host: String,
pub api_base: Url,
pub web_base: Url,
pub app_id: u64,
pub client_id: String,
pub app_slug: String,
pub jwt_issuer: JwtIssuer,
pub checkout_action: String,
pub actions_integration_id: Option<u64>,
pub request_timeout: Duration,
pub device_poll_unit: Duration,
pub bridge_checks: bool,
}
impl GitHubConfig {
pub fn github_com(
app_id: u64,
client_id: impl Into<String>,
app_slug: impl Into<String>,
) -> Self {
GitHubConfig {
host: "github.com".into(),
api_base: Url::parse("https://api.github.com").expect("static URL"),
web_base: Url::parse("https://github.com").expect("static URL"),
app_id,
client_id: client_id.into(),
app_slug: app_slug.into(),
jwt_issuer: JwtIssuer::ClientId,
checkout_action: DEFAULT_CHECKOUT_ACTION.into(),
actions_integration_id: None,
request_timeout: Duration::from_secs(30),
device_poll_unit: Duration::from_secs(1),
bridge_checks: false,
}
}
pub fn enterprise(
host: &str,
app_id: u64,
client_id: impl Into<String>,
app_slug: impl Into<String>,
) -> Result<Self> {
let host = host.to_ascii_lowercase();
let web_base = Url::parse(&format!("https://{host}"))
.map_err(|e| ForgeError::Config(format!("GHES host `{host}`: {e}")))?;
let api_base = web_base
.join("api/v3")
.map_err(|e| ForgeError::Config(e.to_string()))?;
let mut cfg = GitHubConfig::github_com(app_id, client_id, app_slug);
cfg.host = host;
cfg.api_base = api_base;
cfg.web_base = web_base;
Ok(cfg)
}
pub fn with_endpoints(mut self, api_base: Url, web_base: Url) -> Self {
self.api_base = api_base;
self.web_base = web_base;
self
}
pub fn with_app_id_issuer(mut self) -> Self {
self.jwt_issuer = JwtIssuer::AppId;
self
}
pub fn with_actions_integration_id(mut self, id: u64) -> Self {
self.actions_integration_id = Some(id);
self
}
pub fn with_bridge_checks(mut self) -> Self {
self.bridge_checks = true;
self
}
}