ephemeris_forge_forgejo/
release.rs1use ephemeris_forge::RepoRef;
4use ephemeris_release::{
5 ForgeProposal, ForgeRelease as ReleaseForge, ForgeTags, RemoteAsset, RemoteRelease,
6};
7use reqwest::Method;
8
9use crate::api::{ForgeError, HttpApi};
10
11#[derive(Debug)]
13pub struct Release {
14 api: HttpApi,
15 repository: RepoRef,
16}
17
18impl Release {
19 #[must_use]
21 pub const fn new(api: HttpApi, repository: RepoRef) -> Self {
22 Self { api, repository }
23 }
24}
25
26impl ForgeProposal for Release {
27 type Error = ForgeError;
28
29 async fn proposal_body(&self, head: &str, _base: &str) -> Result<Option<String>, Self::Error> {
30 Ok(self
31 .api
32 .open_pull_request(&self.repository, head)
33 .await?
34 .and_then(|pull| pull.body))
35 }
36
37 async fn ensure_proposal(
38 &self,
39 head: &str,
40 base: &str,
41 title: &str,
42 body: &str,
43 ) -> Result<(), Self::Error> {
44 self.api
45 .ensure_pull_request(&self.repository, head, base, title, body)
46 .await
47 }
48}
49
50impl ForgeTags for Release {
51 type Error = ForgeError;
52
53 async fn tag_commit(&self, tag: &str) -> Result<Option<String>, Self::Error> {
54 self.api.tag_commit(&self.repository, tag).await
55 }
56}
57
58impl ReleaseForge for Release {
59 type Error = ForgeError;
60
61 async fn delete_asset(&self, release_id: u64, asset_id: u64) -> Result<(), Self::Error> {
62 self.api
63 .delete_asset(&self.repository, release_id, asset_id)
64 .await
65 }
66
67 async fn release_by_tag(&self, tag: &str) -> Result<Option<RemoteRelease>, Self::Error> {
68 let release = self.api.release_by_tag(&self.repository, tag).await?;
69 Ok(release.map(|release| RemoteRelease {
70 id: release.id,
71 draft: release.draft,
72 }))
73 }
74
75 async fn create_draft(
76 &self,
77 tag: &str,
78 target_commit: &str,
79 title: &str,
80 notes: &str,
81 ) -> Result<u64, Self::Error> {
82 self.api
83 .create_draft_release(&self.repository, tag, target_commit, title, notes)
84 .await
85 }
86
87 async fn assets(&self, release_id: u64) -> Result<Vec<RemoteAsset>, Self::Error> {
88 Ok(self
89 .api
90 .release_assets(&self.repository, release_id)
91 .await?
92 .into_iter()
93 .map(|asset| RemoteAsset {
94 id: asset.id,
95 name: asset.name,
96 size: asset.size,
97 sha256: asset.digest,
98 download_url: asset.browser_download_url,
99 })
100 .collect())
101 }
102
103 async fn upload(
104 &self,
105 release_id: u64,
106 filename: &str,
107 bytes: &[u8],
108 ) -> Result<(), Self::Error> {
109 self.api
110 .upload_asset(&self.repository, release_id, filename, bytes.to_vec())
111 .await
112 }
113
114 async fn asset_bytes(&self, asset: &RemoteAsset) -> Result<Vec<u8>, Self::Error> {
115 Ok(self
116 .api
117 .http
118 .bytes(Method::GET, &asset.download_url, None)
119 .await?)
120 }
121
122 async fn publish(&self, release_id: u64) -> Result<(), Self::Error> {
123 self.api.publish_release(&self.repository, release_id).await
124 }
125}