ephemeris_forge_github/api/http/
actions.rs1use ephemeris_forge::{RepoRef, encode};
2use facet::Facet;
3use reqwest::Method;
4
5use crate::api::HttpApi;
6use crate::api::error::ForgeError;
7use crate::api::model::actions::routes::ActionsGroup;
8use crate::api::model::actions::{CacheRetentionResponse, CacheStorageResponse};
9use crate::api::operations::ActionsApi;
10use crate::api::request::{CacheRetentionBody, CacheStorageBody};
11use crate::config::actions::Cache;
12
13const CACHE_UNAVAILABLE_STATUS: u16 = 402;
15const CACHE_RETENTION_ROUTE: &str = "actions/cache/retention-limit";
16const CACHE_STORAGE_ROUTE: &str = "actions/cache/storage-limit";
17
18impl HttpApi {
19 async fn read_actions<R: for<'a> Facet<'a>>(
20 &self,
21 repository: &RepoRef,
22 route: &str,
23 unavailable: Option<u16>,
24 ) -> Result<Option<R>, ForgeError> {
25 match self.optional(&repository.path(route)).await {
26 Err(error) if unavailable.is_some_and(|status| error.status() == Some(status)) => {
27 Ok(None)
28 }
29 result => result,
30 }
31 }
32
33 async fn put_actions(
34 &self,
35 repository: &RepoRef,
36 route: &str,
37 body: String,
38 ) -> Result<(), ForgeError> {
39 self.empty(Method::PUT, &repository.path(route), Some(body))
40 .await
41 }
42}
43
44impl ActionsApi for HttpApi {
45 async fn actions_cache(&self, repository: &RepoRef) -> Result<Option<Cache>, ForgeError> {
46 let retention: Option<CacheRetentionResponse> = self
47 .read_actions(
48 repository,
49 CACHE_RETENTION_ROUTE,
50 Some(CACHE_UNAVAILABLE_STATUS),
51 )
52 .await?;
53 let storage: Option<CacheStorageResponse> = self
54 .read_actions(
55 repository,
56 CACHE_STORAGE_ROUTE,
57 Some(CACHE_UNAVAILABLE_STATUS),
58 )
59 .await?;
60 Ok(retention
61 .zip(storage)
62 .map(|(retention, storage)| Cache::from_responses(retention, storage)))
63 }
64
65 async fn actions_group<G: ActionsGroup>(
66 &self,
67 repository: &RepoRef,
68 ) -> Result<Option<G>, ForgeError> {
69 let wire: Option<G::Wire> = self
70 .read_actions(repository, G::ROUTE, G::UNAVAILABLE_STATUS)
71 .await?;
72 Ok(wire.map(Into::into))
73 }
74
75 async fn set_actions_cache(
76 &self,
77 repository: &RepoRef,
78 group: &Cache,
79 ) -> Result<(), ForgeError> {
80 self.put_actions(
81 repository,
82 CACHE_RETENTION_ROUTE,
83 encode(&CacheRetentionBody {
84 max_cache_retention_days: group.max_cache_retention_days,
85 }),
86 )
87 .await?;
88 self.put_actions(
89 repository,
90 CACHE_STORAGE_ROUTE,
91 encode(&CacheStorageBody {
92 max_cache_size_gb: group.max_cache_size_gb,
93 }),
94 )
95 .await
96 }
97
98 async fn set_actions_group<G: ActionsGroup>(
99 &self,
100 repository: &RepoRef,
101 group: &G,
102 ) -> Result<(), ForgeError> {
103 self.put_actions(repository, G::ROUTE, group.body()).await
104 }
105}