From d4a035e5c586729202502b3385f61e8bcfa034be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFs=20Postula?= Date: Wed, 24 Jul 2024 13:02:17 +0200 Subject: [PATCH] feat: implement repos/{owner}/{repo}/releases/{number} resolves #663 --- src/api/repos/releases.rs | 22 +++++ tests/repos_releases_get_by_id.rs | 88 +++++++++++++++++ tests/repos_releases_get_by_tag.rs | 88 +++++++++++++++++ tests/repos_releases_get_latest.rs | 84 ++++++++++++++++ tests/repos_releases_list_test.rs | 99 +++++++++++++++++++ tests/resources/repos_releases_get_by_id.json | 41 ++++++++ .../resources/repos_releases_get_by_tag.json | 41 ++++++++ .../resources/repos_releases_get_latest.json | 41 ++++++++ tests/resources/repos_releases_list.json | 80 +++++++++++++++ 9 files changed, 584 insertions(+) create mode 100644 tests/repos_releases_get_by_id.rs create mode 100644 tests/repos_releases_get_by_tag.rs create mode 100644 tests/repos_releases_get_latest.rs create mode 100644 tests/repos_releases_list_test.rs create mode 100644 tests/resources/repos_releases_get_by_id.json create mode 100644 tests/resources/repos_releases_get_by_tag.json create mode 100644 tests/resources/repos_releases_get_latest.json create mode 100644 tests/resources/repos_releases_list.json diff --git a/src/api/repos/releases.rs b/src/api/repos/releases.rs index dcf4db79..d9327585 100644 --- a/src/api/repos/releases.rs +++ b/src/api/repos/releases.rs @@ -150,6 +150,28 @@ impl<'octo, 'r> ReleasesHandler<'octo, 'r> { self.parent.crab.get(route, None::<&()>).await } + /// Gets the release using its id. + /// ```no_run + /// # async fn run() -> octocrab::Result<()> { + /// let release = octocrab::instance() + /// .repos("owner", "repo") + /// .releases() + /// .get(3) + /// .await?; + /// # Ok(()) + /// # } + /// ``` + pub async fn get(&self, number: u64) -> Result { + let route = format!( + "/repos/{owner}/{repo}/releases/{number}", + owner = self.parent.owner, + repo = self.parent.repo, + number = number, + ); + + self.parent.crab.get(route, None::<&()>).await + } + /// Generates [`crate::models::repos::ReleaseNotes`] which describe /// a [`crate::models::repos::Release`] /// ```no_run diff --git a/tests/repos_releases_get_by_id.rs b/tests/repos_releases_get_by_id.rs new file mode 100644 index 00000000..f30366d3 --- /dev/null +++ b/tests/repos_releases_get_by_id.rs @@ -0,0 +1,88 @@ +/// Tests API calls related to check runs of a specific commit. +mod mock_error; + +use mock_error::setup_error_handler; +use octocrab::models::repos::Release; +use octocrab::models::ReleaseId; +use octocrab::{Error, Octocrab}; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; +use wiremock::{ + matchers::{method, path}, + Mock, MockServer, ResponseTemplate, +}; + +#[derive(Serialize, Deserialize)] +struct FakePage { + items: Vec, +} + +const OWNER: &str = "XAMPPRocky"; +const REPO: &str = "octocrab"; + +async fn setup_get_api(template: ResponseTemplate, number: u64) -> MockServer { + let mock_server = MockServer::start().await; + + Mock::given(method("GET")) + .and(path(format!( + "/repos/{OWNER}/{REPO}/releases/{number}" + ))) + .respond_with(template) + .mount(&mock_server) + .await; + setup_error_handler( + &mock_server, + &format!("GET on /repos/{OWNER}/{REPO}/releases/{number} was not received"), + ) + .await; + mock_server +} + +fn setup_octocrab(uri: &str) -> Octocrab { + Octocrab::builder().base_uri(uri).unwrap().build().unwrap() +} + +#[tokio::test] +async fn should_return_release_for_repository_by_id() { + let number: u64 = 148681297; + let mocked_response: Release = + serde_json::from_str(include_str!("resources/repos_releases_get_by_id.json")).unwrap(); + let template = ResponseTemplate::new(200).set_body_json(&mocked_response); + let mock_server = setup_get_api(template, number).await; + let client = setup_octocrab(&mock_server.uri()); + let result = client.repos(OWNER, REPO).releases().get(number).await; + + assert!( + result.is_ok(), + "expected successful result, got error: {:#?}", + result + ); + + let release = result.unwrap(); + + + + assert_eq!(ReleaseId(number), release.id); + assert_eq!("v0.37.0", release.tag_name); +} + +#[tokio::test] +async fn should_fail_when_no_releases_found() { + let mocked_response = json!({ + "documentation_url": json!("rtm"), + "errors": Value::Null, + "message": json!("Its gone") + }); + + let template = ResponseTemplate::new(404).set_body_json(&mocked_response); + let mock_server = setup_get_api(template, 404).await; + let client = setup_octocrab(&mock_server.uri()); + let result = client.repos(OWNER, REPO).releases().get(404).await; + + match result.unwrap_err() { + Error::GitHub { source, .. } => { + assert_eq!("Its gone", source.message) + } + other => panic!("Unexpected error: {:?}", other), + } +} diff --git a/tests/repos_releases_get_by_tag.rs b/tests/repos_releases_get_by_tag.rs new file mode 100644 index 00000000..66ba5be7 --- /dev/null +++ b/tests/repos_releases_get_by_tag.rs @@ -0,0 +1,88 @@ +/// Tests API calls related to check runs of a specific commit. +mod mock_error; + +use mock_error::setup_error_handler; +use octocrab::models::repos::Release; +use octocrab::models::ReleaseId; +use octocrab::{Error, Octocrab}; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; +use wiremock::{ + matchers::{method, path}, + Mock, MockServer, ResponseTemplate, +}; + +#[derive(Serialize, Deserialize)] +struct FakePage { + items: Vec, +} + +const OWNER: &str = "XAMPPRocky"; +const REPO: &str = "octocrab"; + +async fn setup_get_api(template: ResponseTemplate, tag: &str) -> MockServer { + let mock_server = MockServer::start().await; + + Mock::given(method("GET")) + .and(path(format!("/repos/{OWNER}/{REPO}/releases/tags/{tag}"))) + .respond_with(template) + .mount(&mock_server) + .await; + setup_error_handler( + &mock_server, + &format!("GET on /repos/{OWNER}/{REPO}/releases/{tag} was not received"), + ) + .await; + mock_server +} + +fn setup_octocrab(uri: &str) -> Octocrab { + Octocrab::builder().base_uri(uri).unwrap().build().unwrap() +} + +#[tokio::test] +async fn should_return_release_for_repository_by_tag() { + let tag: String = "v0.37.0".to_string(); + let mocked_response: Release = + serde_json::from_str(include_str!("resources/repos_releases_get_by_tag.json")).unwrap(); + let template = ResponseTemplate::new(200).set_body_json(&mocked_response); + let mock_server = setup_get_api(template, &tag).await; + let client = setup_octocrab(&mock_server.uri()); + let result = client.repos(OWNER, REPO).releases().get_by_tag(&tag).await; + + assert!( + result.is_ok(), + "expected successful result, got error: {:#?}", + result + ); + + let release = result.unwrap(); + + assert_eq!(ReleaseId(148681297), release.id); + assert_eq!(tag, release.tag_name); +} + +#[tokio::test] +async fn should_fail_when_no_releases_found() { + let mocked_response = json!({ + "documentation_url": json!("rtm"), + "errors": Value::Null, + "message": json!("Its gone") + }); + + let template = ResponseTemplate::new(404).set_body_json(&mocked_response); + let mock_server = setup_get_api(template, "v0.37.0").await; + let client = setup_octocrab(&mock_server.uri()); + let result = client + .repos(OWNER, REPO) + .releases() + .get_by_tag("v0.37.0") + .await; + + match result.unwrap_err() { + Error::GitHub { source, .. } => { + assert_eq!("Its gone", source.message) + } + other => panic!("Unexpected error: {:?}", other), + } +} diff --git a/tests/repos_releases_get_latest.rs b/tests/repos_releases_get_latest.rs new file mode 100644 index 00000000..d276cca0 --- /dev/null +++ b/tests/repos_releases_get_latest.rs @@ -0,0 +1,84 @@ +/// Tests API calls related to check runs of a specific commit. +mod mock_error; + +use mock_error::setup_error_handler; +use octocrab::models::repos::Release; +use octocrab::models::ReleaseId; +use octocrab::{Error, Octocrab}; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; +use wiremock::{ + matchers::{method, path}, + Mock, MockServer, ResponseTemplate, +}; + +#[derive(Serialize, Deserialize)] +struct FakePage { + items: Vec, +} + +const OWNER: &str = "XAMPPRocky"; +const REPO: &str = "octocrab"; + +async fn setup_get_api(template: ResponseTemplate) -> MockServer { + let mock_server = MockServer::start().await; + + Mock::given(method("GET")) + .and(path(format!("/repos/{OWNER}/{REPO}/releases/latest"))) + .respond_with(template) + .mount(&mock_server) + .await; + setup_error_handler( + &mock_server, + &format!("GET on /repos/{OWNER}/{REPO}/releases/latest was not received"), + ) + .await; + mock_server +} + +fn setup_octocrab(uri: &str) -> Octocrab { + Octocrab::builder().base_uri(uri).unwrap().build().unwrap() +} + +#[tokio::test] +async fn should_return_latest_release_for_repository() { + let number: u64 = 150372594; + let mocked_response: Release = + serde_json::from_str(include_str!("resources/repos_releases_get_latest.json")).unwrap(); + let template = ResponseTemplate::new(200).set_body_json(&mocked_response); + let mock_server = setup_get_api(template).await; + let client = setup_octocrab(&mock_server.uri()); + let result = client.repos(OWNER, REPO).releases().get_latest().await; + + assert!( + result.is_ok(), + "expected successful result, got error: {:#?}", + result + ); + + let release = result.unwrap(); + + assert_eq!(ReleaseId(number), release.id); + assert_eq!("v0.38.0", release.tag_name); +} + +#[tokio::test] +async fn should_fail_when_no_releases_found() { + let mocked_response = json!({ + "documentation_url": json!("rtm"), + "errors": Value::Null, + "message": json!("Its gone") + }); + + let template = ResponseTemplate::new(404).set_body_json(&mocked_response); + let mock_server = setup_get_api(template).await; + let client = setup_octocrab(&mock_server.uri()); + let result = client.repos(OWNER, REPO).releases().get_latest().await; + + match result.unwrap_err() { + Error::GitHub { source, .. } => { + assert_eq!("Its gone", source.message) + } + other => panic!("Unexpected error: {:?}", other), + } +} diff --git a/tests/repos_releases_list_test.rs b/tests/repos_releases_list_test.rs new file mode 100644 index 00000000..6242cf76 --- /dev/null +++ b/tests/repos_releases_list_test.rs @@ -0,0 +1,99 @@ +/// Tests API calls related to check runs of a specific commit. +mod mock_error; + +use mock_error::setup_error_handler; +use octocrab::models::repos::Release; +use octocrab::models::ReleaseId; +use octocrab::{Error, Octocrab}; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; +use wiremock::{ + matchers::{method, path}, + Mock, MockServer, ResponseTemplate, +}; + +#[derive(Serialize, Deserialize)] +struct FakePage { + items: Vec, +} + +const OWNER: &str = "XAMPPRocky"; +const REPO: &str = "octocrab"; + +async fn setup_get_api(template: ResponseTemplate) -> MockServer { + let mock_server = MockServer::start().await; + + Mock::given(method("GET")) + .and(path(format!( + "/repos/{OWNER}/{REPO}/releases" + ))) + .respond_with(template) + .mount(&mock_server) + .await; + setup_error_handler( + &mock_server, + &format!("GET on /repos/{OWNER}/{REPO}/releases was not received"), + ) + .await; + mock_server +} + +fn setup_octocrab(uri: &str) -> Octocrab { + Octocrab::builder().base_uri(uri).unwrap().build().unwrap() +} + +#[tokio::test] +async fn should_return_releases_for_repository() { + let mocked_response: Vec = + serde_json::from_str(include_str!("resources/repos_releases_list.json")).unwrap(); + let template = ResponseTemplate::new(200).set_body_json(&mocked_response); + let mock_server = setup_get_api(template).await; + let client = setup_octocrab(&mock_server.uri()); + let result = client.repos(OWNER, REPO).releases().list().send().await; + + assert!( + result.is_ok(), + "expected successful result, got error: {:#?}", + result + ); + + let response = result.unwrap(); + let items = response.items; + + assert_eq!(items.len(), 2); + + { + let item = &items[0]; + + assert_eq!(ReleaseId(150372594), item.id); + assert_eq!("v0.38.0", item.tag_name); + } + + { + let item = &items[1]; + + assert_eq!(ReleaseId(148681297), item.id); + assert_eq!("v0.37.0", item.tag_name); + } +} + +#[tokio::test] +async fn should_fail_when_no_releases_found() { + let mocked_response = json!({ + "documentation_url": json!("rtm"), + "errors": Value::Null, + "message": json!("Its gone") + }); + + let template = ResponseTemplate::new(404).set_body_json(&mocked_response); + let mock_server = setup_get_api(template).await; + let client = setup_octocrab(&mock_server.uri()); + let result = client.repos(OWNER, REPO).releases().list().send().await; + + match result.unwrap_err() { + Error::GitHub { source, .. } => { + assert_eq!("Its gone", source.message) + } + other => panic!("Unexpected error: {:?}", other), + } +} diff --git a/tests/resources/repos_releases_get_by_id.json b/tests/resources/repos_releases_get_by_id.json new file mode 100644 index 00000000..690b2937 --- /dev/null +++ b/tests/resources/repos_releases_get_by_id.json @@ -0,0 +1,41 @@ +{ + "url": "https://api.github.com/repos/XAMPPRocky/octocrab/releases/148681297", + "assets_url": "https://api.github.com/repos/XAMPPRocky/octocrab/releases/148681297/assets", + "upload_url": "https://uploads.github.com/repos/XAMPPRocky/octocrab/releases/148681297/assets{?name,label}", + "html_url": "https://github.com/XAMPPRocky/octocrab/releases/tag/v0.37.0", + "id": 148681297, + "author": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "node_id": "RE_kwDOD4Ga3s4I3LJR", + "tag_name": "v0.37.0", + "target_commitish": "main", + "name": "v0.37.0", + "draft": false, + "prerelease": false, + "created_at": "2024-03-27T13:57:58Z", + "published_at": "2024-03-27T13:57:59Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/XAMPPRocky/octocrab/tarball/v0.37.0", + "zipball_url": "https://api.github.com/repos/XAMPPRocky/octocrab/zipball/v0.37.0", + "body": "### Fixed\n- [**breaking**] Change `Rate::reset` to `u64` ([#615](https://github.com/XAMPPRocky/octocrab/pull/615))\n\n### Other\n- Update graphql_client requirement from 0.13.0 to 0.14.0 ([#617](https://github.com/XAMPPRocky/octocrab/pull/617))\n- Added basic support for getting user profiles ([#616](https://github.com/XAMPPRocky/octocrab/pull/616))\n- Update manual github app authentication example ([#610](https://github.com/XAMPPRocky/octocrab/pull/610))" +} diff --git a/tests/resources/repos_releases_get_by_tag.json b/tests/resources/repos_releases_get_by_tag.json new file mode 100644 index 00000000..690b2937 --- /dev/null +++ b/tests/resources/repos_releases_get_by_tag.json @@ -0,0 +1,41 @@ +{ + "url": "https://api.github.com/repos/XAMPPRocky/octocrab/releases/148681297", + "assets_url": "https://api.github.com/repos/XAMPPRocky/octocrab/releases/148681297/assets", + "upload_url": "https://uploads.github.com/repos/XAMPPRocky/octocrab/releases/148681297/assets{?name,label}", + "html_url": "https://github.com/XAMPPRocky/octocrab/releases/tag/v0.37.0", + "id": 148681297, + "author": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "node_id": "RE_kwDOD4Ga3s4I3LJR", + "tag_name": "v0.37.0", + "target_commitish": "main", + "name": "v0.37.0", + "draft": false, + "prerelease": false, + "created_at": "2024-03-27T13:57:58Z", + "published_at": "2024-03-27T13:57:59Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/XAMPPRocky/octocrab/tarball/v0.37.0", + "zipball_url": "https://api.github.com/repos/XAMPPRocky/octocrab/zipball/v0.37.0", + "body": "### Fixed\n- [**breaking**] Change `Rate::reset` to `u64` ([#615](https://github.com/XAMPPRocky/octocrab/pull/615))\n\n### Other\n- Update graphql_client requirement from 0.13.0 to 0.14.0 ([#617](https://github.com/XAMPPRocky/octocrab/pull/617))\n- Added basic support for getting user profiles ([#616](https://github.com/XAMPPRocky/octocrab/pull/616))\n- Update manual github app authentication example ([#610](https://github.com/XAMPPRocky/octocrab/pull/610))" +} diff --git a/tests/resources/repos_releases_get_latest.json b/tests/resources/repos_releases_get_latest.json new file mode 100644 index 00000000..e0111881 --- /dev/null +++ b/tests/resources/repos_releases_get_latest.json @@ -0,0 +1,41 @@ +{ + "url": "https://api.github.com/repos/XAMPPRocky/octocrab/releases/150372594", + "assets_url": "https://api.github.com/repos/XAMPPRocky/octocrab/releases/150372594/assets", + "upload_url": "https://uploads.github.com/repos/XAMPPRocky/octocrab/releases/150372594/assets{?name,label}", + "html_url": "https://github.com/XAMPPRocky/octocrab/releases/tag/v0.38.0", + "id": 150372594, + "author": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "node_id": "RE_kwDOD4Ga3s4I9oDy", + "tag_name": "v0.38.0", + "target_commitish": "main", + "name": "v0.38.0", + "draft": false, + "prerelease": false, + "created_at": "2024-04-09T10:50:07Z", + "published_at": "2024-04-09T10:50:08Z", + "assets": [ + + ], + "tarball_url": "https://api.github.com/repos/XAMPPRocky/octocrab/tarball/v0.38.0", + "zipball_url": "https://api.github.com/repos/XAMPPRocky/octocrab/zipball/v0.38.0", + "body": "### Added\n- Add `generate_release_notes`: ([#588](https://github.com/XAMPPRocky/octocrab/pull/588))\n\n### Other\n- Unify diff entry models ([#624](https://github.com/XAMPPRocky/octocrab/pull/624))\n- Added tests for .delete_thread_subscriptions() ([#620](https://github.com/XAMPPRocky/octocrab/pull/620))\n- Adding tests, and fixing missing error code. ([#619](https://github.com/XAMPPRocky/octocrab/pull/619))" +} diff --git a/tests/resources/repos_releases_list.json b/tests/resources/repos_releases_list.json new file mode 100644 index 00000000..029566f8 --- /dev/null +++ b/tests/resources/repos_releases_list.json @@ -0,0 +1,80 @@ +[ + { + "url": "https://api.github.com/repos/XAMPPRocky/octocrab/releases/150372594", + "assets_url": "https://api.github.com/repos/XAMPPRocky/octocrab/releases/150372594/assets", + "upload_url": "https://uploads.github.com/repos/XAMPPRocky/octocrab/releases/150372594/assets{?name,label}", + "html_url": "https://github.com/XAMPPRocky/octocrab/releases/tag/v0.38.0", + "id": 150372594, + "author": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "node_id": "RE_kwDOD4Ga3s4I9oDy", + "tag_name": "v0.38.0", + "target_commitish": "main", + "name": "v0.38.0", + "draft": false, + "prerelease": false, + "created_at": "2024-04-09T10:50:07Z", + "published_at": "2024-04-09T10:50:08Z", + "assets": [], + "tarball_url": "https://api.github.com/repos/XAMPPRocky/octocrab/tarball/v0.38.0", + "zipball_url": "https://api.github.com/repos/XAMPPRocky/octocrab/zipball/v0.38.0", + "body": "### Added\n- Add `generate_release_notes`: ([#588](https://github.com/XAMPPRocky/octocrab/pull/588))\n\n### Other\n- Unify diff entry models ([#624](https://github.com/XAMPPRocky/octocrab/pull/624))\n- Added tests for .delete_thread_subscriptions() ([#620](https://github.com/XAMPPRocky/octocrab/pull/620))\n- Adding tests, and fixing missing error code. ([#619](https://github.com/XAMPPRocky/octocrab/pull/619))" + }, + { + "url": "https://api.github.com/repos/XAMPPRocky/octocrab/releases/148681297", + "assets_url": "https://api.github.com/repos/XAMPPRocky/octocrab/releases/148681297/assets", + "upload_url": "https://uploads.github.com/repos/XAMPPRocky/octocrab/releases/148681297/assets{?name,label}", + "html_url": "https://github.com/XAMPPRocky/octocrab/releases/tag/v0.37.0", + "id": 148681297, + "author": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "node_id": "RE_kwDOD4Ga3s4I3LJR", + "tag_name": "v0.37.0", + "target_commitish": "main", + "name": "v0.37.0", + "draft": false, + "prerelease": false, + "created_at": "2024-03-27T13:57:58Z", + "published_at": "2024-03-27T13:57:59Z", + "assets": [], + "tarball_url": "https://api.github.com/repos/XAMPPRocky/octocrab/tarball/v0.37.0", + "zipball_url": "https://api.github.com/repos/XAMPPRocky/octocrab/zipball/v0.37.0", + "body": "### Fixed\n- [**breaking**] Change `Rate::reset` to `u64` ([#615](https://github.com/XAMPPRocky/octocrab/pull/615))\n\n### Other\n- Update graphql_client requirement from 0.13.0 to 0.14.0 ([#617](https://github.com/XAMPPRocky/octocrab/pull/617))\n- Added basic support for getting user profiles ([#616](https://github.com/XAMPPRocky/octocrab/pull/616))\n- Update manual github app authentication example ([#610](https://github.com/XAMPPRocky/octocrab/pull/610))" + } +]