use zlayer_toolchain::package_index::sign;
use zlayer_types::package_index::PackageIndexConfig;
const REPOSYNC_HMAC_SECRET: Option<&str> = option_env!("ZLAYER_REPOSYNC_HMAC_SECRET");
pub fn report_unfulfilled(distro: &str, manager: &str, name: &str) {
let Some(secret) = REPOSYNC_HMAC_SECRET.filter(|s| !s.is_empty()) else {
return;
};
let (distro, manager, name) = (distro.to_string(), manager.to_string(), name.to_string());
let endpoint = PackageIndexConfig::from_env().linux_request_url();
tokio::spawn(async move {
let payload =
serde_json::json!({ "distro": distro, "manager": manager, "name": name }).to_string();
let signature = sign(secret, payload.as_bytes());
let _ = reqwest::Client::new()
.post(&endpoint)
.header("x-reposync-signature", signature)
.header("content-type", "application/json")
.body(payload)
.send()
.await;
});
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn shared_signer_matches_reposync_reference_vector() {
let sig = sign("test-secret", br#"{"foo":"bar"}"#);
assert_eq!(
sig,
"sha256=9b1abf7d901bda91325d00f6b397fb0dc257937939b27d4dc67848ab9e08f6c0"
);
}
#[test]
fn payload_shape_is_stable() {
let payload = serde_json::json!({
"distro": "debian-12",
"manager": "apt",
"name": "lib\"weird\"-dev",
})
.to_string();
let parsed: serde_json::Value = serde_json::from_str(&payload).expect("valid JSON");
assert_eq!(parsed["distro"], "debian-12");
assert_eq!(parsed["manager"], "apt");
assert_eq!(parsed["name"], "lib\"weird\"-dev");
}
#[test]
fn endpoint_derives_from_index_base() {
assert_eq!(
PackageIndexConfig::default().linux_request_url(),
"https://packages.zlayer.dev/linux/request"
);
}
}