nimbus_cli/updater/
taskcluster.rs
1use serde::de::DeserializeOwned;
6use std::time::Duration;
7use update_informer::{
8 http_client::{GenericHttpClient, HeaderMap, HttpClient},
9 Check, Package, Registry, Result,
10};
11
12#[derive(serde::Deserialize)]
13struct Response {
14 version: String,
15}
16
17struct TaskClusterRegistry;
18
19impl Registry for TaskClusterRegistry {
20 const NAME: &'static str = "taskcluster";
21
22 fn get_latest_version<T: HttpClient>(
23 http_client: GenericHttpClient<T>,
24 pkg: &Package,
25 ) -> Result<Option<String>> {
26 let name = pkg.to_string();
27 let url = format!("https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/project.application-services.v2.{name}.latest/artifacts/public%2Fbuild%2F{name}.json");
28 let resp = http_client.get::<Response>(&url)?;
29 Ok(Some(resp.version))
30 }
31}
32
33#[allow(dead_code)]
34pub struct ReqwestGunzippingHttpClient;
35
36impl HttpClient for ReqwestGunzippingHttpClient {
37 fn get<T: DeserializeOwned>(url: &str, timeout: Duration, headers: HeaderMap) -> Result<T> {
38 let mut req = reqwest::blocking::Client::builder()
39 .timeout(timeout)
40 .gzip(true)
43 .build()?
44 .get(url);
45
46 for (key, value) in headers {
47 req = req.header(key, value);
48 }
49
50 let json = req.send()?.json()?;
51
52 Ok(json)
53 }
54}
55
56pub(crate) fn check_taskcluster_for_update<F>(message: F)
59where
60 F: Fn(&str, &str),
61{
62 let name = env!("CARGO_PKG_NAME");
63 let version = env!("CARGO_PKG_VERSION");
64 let interval = Duration::from_secs(60 * 60);
65
66 #[cfg(not(test))]
67 let informer = update_informer::new(TaskClusterRegistry, name, version)
68 .http_client(ReqwestGunzippingHttpClient)
69 .interval(interval);
70
71 #[cfg(test)]
72 let informer =
73 update_informer::fake(TaskClusterRegistry, name, version, "1.0.0").interval(interval);
74
75 if let Ok(Some(new_version)) = informer.check_version() {
76 message(&format!("v{version}"), &new_version.to_string());
77 }
78}