use crate::report::STICKY_MARKER;
use crate::secret::Secret;
#[derive(Debug, Clone)]
pub struct GithubContext {
pub repo: String,
pub pr: u64,
pub token: Secret,
pub api_base: Option<String>,
}
impl GithubContext {
pub fn api_base(&self) -> &str {
self.api_base.as_deref().unwrap_or("https://api.github.com")
}
}
pub fn default_headers(token: &Secret) -> Vec<(&'static str, String)> {
vec![
("Authorization", format!("Bearer {}", token.reveal())),
("Accept", "application/vnd.github+json".to_string()),
("X-GitHub-Api-Version", "2022-11-28".to_string()),
("User-Agent", format!("aatxe/{}", env!("CARGO_PKG_VERSION"))),
]
}
pub fn list_comments_url(ctx: &GithubContext, page: u32) -> String {
format!(
"{}/repos/{}/issues/{}/comments?per_page=100&page={}",
ctx.api_base(),
ctx.repo,
ctx.pr,
page,
)
}
pub fn patch_comment_url(ctx: &GithubContext, comment_id: u64) -> String {
format!(
"{}/repos/{}/issues/comments/{}",
ctx.api_base(),
ctx.repo,
comment_id,
)
}
pub fn create_comment_url(ctx: &GithubContext) -> String {
format!(
"{}/repos/{}/issues/{}/comments",
ctx.api_base(),
ctx.repo,
ctx.pr,
)
}
pub fn validate_sticky(body: &str) -> Result<(), &'static str> {
if body.contains(STICKY_MARKER) {
Ok(())
} else {
Err("comment body is missing the sticky marker; render with crate::render_markdown")
}
}
#[derive(Debug, Clone, Default)]
pub struct DetectedContext {
pub repo: Option<String>,
pub pr: Option<u64>,
pub token: Option<Secret>,
}
pub fn detect_context<F: Fn(&str) -> Option<String>>(get: F) -> DetectedContext {
let token = get("GITHUB_TOKEN")
.or_else(|| get("GH_TOKEN"))
.map(Secret::new);
let repo = get("GITHUB_REPOSITORY");
let pr = detect_pr_number(&get);
DetectedContext { repo, pr, token }
}
fn detect_pr_number<F: Fn(&str) -> Option<String>>(get: &F) -> Option<u64> {
if let Some(v) = get("AATXE_PR") {
if let Ok(n) = v.parse::<u64>() {
if n > 0 {
return Some(n);
}
}
}
if let Some(reff) = get("GITHUB_REF") {
if let Some(rest) = reff.strip_prefix("refs/pull/") {
if let Some(slash) = rest.find('/') {
if let Ok(n) = rest[..slash].parse::<u64>() {
return Some(n);
}
}
}
}
if let Some(name) = get("GITHUB_REF_NAME") {
if let Some((num, suffix)) = name.split_once('/') {
if matches!(suffix, "merge" | "head") {
if let Ok(n) = num.parse::<u64>() {
return Some(n);
}
}
}
}
None
}