pcu_lib/ops/
make_release.rs

1use crate::{
2    utilities::{ReleaseNotesProvider, ReleaseUnreleased},
3    Client, Error, GitOps,
4};
5use keep_a_changelog::{Changelog, ChangelogParseOptions};
6use octocrate::repos::create_release;
7use octocrate::repos::create_release::RequestMakeLatest;
8
9pub trait MakeRelease {
10    #[allow(async_fn_in_trait)]
11    async fn make_release(&self, prefix: &str, version: &str) -> Result<(), Error>;
12    fn release_unreleased(&mut self, version: &str) -> Result<(), Error>;
13}
14
15impl MakeRelease for Client {
16    fn release_unreleased(&mut self, version: &str) -> Result<(), Error> {
17        let opts = self.changelog_parse_options.clone();
18
19        let mut change_log = Changelog::parse_from_file(self.changelog_as_str(), Some(opts))
20            .map_err(|e| Error::KeepAChangelog(e.to_string()))?;
21
22        let total_releases = change_log.releases().len();
23        log::debug!("total_releases: {:?}", total_releases);
24
25        change_log.release_unreleased(version).unwrap();
26
27        change_log
28            .save_to_file(self.changelog_as_str())
29            .map_err(|e| Error::KeepAChangelog(e.to_string()))?;
30        Ok(())
31    }
32
33    async fn make_release(&self, prefix: &str, version: &str) -> Result<(), Error> {
34        log::debug!("Making release {version}");
35
36        let opts = ChangelogParseOptions::default();
37        let changelog = match Changelog::parse_from_file(self.changelog_as_str(), Some(opts)) {
38            Ok(changelog) => changelog,
39            Err(e) => {
40                log::error!("Error parsing changelog: {e}");
41                return Err(Error::InvalidPath(self.changelog.clone()));
42            }
43        };
44
45        let release_notes = changelog.release_notes(prefix, version)?;
46        log::trace!("Release notes: {:#?}", release_notes);
47
48        let tag = format!("{prefix}{version}");
49        let commit = Self::get_commitish_for_tag(self, &tag).await?;
50        log::trace!("Commit: {:#?}", commit);
51
52        let release_request = create_release::Request {
53            body: Some(release_notes.body.to_string()),
54            discussion_category_name: None,
55            draft: Some(false),
56            generate_release_notes: Some(false),
57            make_latest: Some(RequestMakeLatest::True),
58            name: Some(release_notes.name.to_string()),
59            prerelease: Some(false),
60            tag_name: tag,
61            target_commitish: Some(commit),
62        };
63
64        let release = self
65            .github_rest
66            .repos
67            .create_release(self.owner(), self.repo())
68            .body(&release_request)
69            .send()
70            .await?;
71
72        log::trace!("Release: {:#?}", release);
73
74        Ok(())
75    }
76}