From 68d4a5d42dc3f7e2e4cf9676465207a2a7818deb Mon Sep 17 00:00:00 2001 From: Matt Ball Date: Sun, 18 Aug 2024 18:25:59 -0600 Subject: [PATCH 01/17] Add release notes template to main branch --- .github/test_release_notes.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .github/test_release_notes.yml diff --git a/.github/test_release_notes.yml b/.github/test_release_notes.yml new file mode 100644 index 0000000000..ba0b1cdf01 --- /dev/null +++ b/.github/test_release_notes.yml @@ -0,0 +1,8 @@ +# This file is needed for generating release notes for the Repository::testGenerateReleaseNotesWithAllArguments test +# See https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes + +changelog: + categories: + - title: Features + labels: + - '*' From 1a6e8bc419385086ca0b903f7855b4a80c02f483 Mon Sep 17 00:00:00 2001 From: Matt Ball Date: Sun, 18 Aug 2024 18:52:07 -0600 Subject: [PATCH 02/17] add support for generate_release_notes --- github/GeneratedReleaseNotes.py | 43 +++++++++++++++++++ github/Repository.py | 41 ++++++++++++++++++ pyproject.toml | 2 +- .../Repository.testGenerateReleaseNotes.txt | 10 +++++ ...stGenerateReleaseNotesWithAllArguments.txt | 21 +++++++++ tests/Repository.py | 28 ++++++++++++ 6 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 github/GeneratedReleaseNotes.py create mode 100644 tests/ReplayData/Repository.testGenerateReleaseNotes.txt create mode 100644 tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt diff --git a/github/GeneratedReleaseNotes.py b/github/GeneratedReleaseNotes.py new file mode 100644 index 0000000000..f46779b584 --- /dev/null +++ b/github/GeneratedReleaseNotes.py @@ -0,0 +1,43 @@ +""" +Representation of the generated release notes returned by the release/generate-notes REST API endpoint. +""" + +from typing import Any, Dict + +from github.GithubObject import ( + Attribute, + CompletableGithubObject, + NotSet, +) + + +# New file named github/GeneratedReleaseNotes.py +class GeneratedReleaseNotes(CompletableGithubObject): + """ + This class represents the release notes generated by the release/generate-notes REST API endpoint. + + The reference can be found here: + https://docs.github.com/en/rest/releases/releases#generate-release-notes-content-for-a-release + + """ + + def _initAttributes(self) -> None: + self._name: Attribute[str] = NotSet + self._body: Attribute[str] = NotSet + + def __repr__(self) -> str: + return self.get__repr__({"name": self._name.value, "body": self._body.value}) + + @property + def name(self) -> str: + return self._name.value + + @property + def body(self) -> str: + return self._body.value + + def _useAttributes(self, attributes: Dict[str, Any]) -> None: + if "body" in attributes: + self._body = self._makeStringAttribute(attributes["body"]) + if "name" in attributes: + self._title = self._makeStringAttribute(attributes["name"]) diff --git a/github/Repository.py b/github/Repository.py index 3d6231b7d1..046e026c65 100644 --- a/github/Repository.py +++ b/github/Repository.py @@ -231,6 +231,7 @@ import github.WorkflowRun from github import Consts from github.Environment import Environment +from github.GeneratedReleaseNotes import GeneratedReleaseNotes from github.GithubObject import ( Attribute, CompletableGithubObject, @@ -1331,6 +1332,46 @@ def create_git_release( headers, data = self._requester.requestJsonAndCheck("POST", f"{self.url}/releases", input=post_parameters) return github.GitRelease.GitRelease(self._requester, headers, data, completed=True) + def generate_release_notes( + self, + tag_name: str, + previous_tag_name: Opt[str] = NotSet, + target_commitish: Opt[str] = NotSet, + configuration_file_path: Opt[str] = NotSet, + ) -> GeneratedReleaseNotes: + """ + :calls: `POST /repos/{owner}/{repo}/releases/generate-notes ` + :param tag_name: The tag name for the release. This can be an existing tag or a new one. + :param previous_tag_name: The name of the previous tag to use as the starting point for the release notes. Use to manually specify the range for the set of changes considered as part this release. + :param target_commitish: Specifies the commitish value that will be the target for the release's tag. Required if the supplied tag_name does not reference an existing tag. Ignored if the tag_name already exists. + :param configuration_file_path: Specifies a path to a file in the repository containing configuration settings used for generating the release notes. If unspecified, the configuration file located in the repository at '.github/release.yml' or '.github/release.yaml' will be used. If that is not present, the default configuration will be used. + :rytpe: :class:`GeneratedReleaseNotes` + """ + assert isinstance(tag_name, str), tag_name + assert isinstance(previous_tag_name, str) or is_optional(previous_tag_name, str), previous_tag_name + assert isinstance(target_commitish, str) or is_optional(target_commitish, str), target_commitish + assert isinstance(configuration_file_path, str) or is_optional( + configuration_file_path, str + ), configuration_file_path + + post_parameters = { + "tag_name": tag_name, + } + if is_defined(previous_tag_name): + post_parameters["previous_tag_name"] = str(previous_tag_name) + + if is_defined(target_commitish): + post_parameters["target_commitish"] = str(target_commitish) + + if is_defined(configuration_file_path): + post_parameters["configuration_file_path"] = str(configuration_file_path) + + headers, data = self._requester.requestJsonAndCheck( + "POST", f"{self.url}/releases/generate-notes", input=post_parameters + ) + + return GeneratedReleaseNotes(self._requester, headers, data, completed=True) + def create_git_tag( self, tag: str, diff --git a/pyproject.toml b/pyproject.toml index d4479c6f58..f9b275fd3f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,7 +83,7 @@ quiet-level = 3 # https://github.com/codespell-project/codespell/issues/2839#issuecomment-1731601603 # also adding links until they ignored by its: nature # https://github.com/codespell-project/codespell/issues/2243#issuecomment-1732019960 -ignore-words-list = "bloaded,nto,pullrequest,pullrequests,thi,tim,wan,Wan,chang,chang,manuel" +ignore-words-list = "bloaded,nto,pullrequest,pullrequests,thi,tim,wan,Wan,chang,chang,manuel,commitish" [tool.ruff] line-length = 120 diff --git a/tests/ReplayData/Repository.testGenerateReleaseNotes.txt b/tests/ReplayData/Repository.testGenerateReleaseNotes.txt new file mode 100644 index 0000000000..9c509d67ea --- /dev/null +++ b/tests/ReplayData/Repository.testGenerateReleaseNotes.txt @@ -0,0 +1,10 @@ +https +POST +api.github.com +None +/repos/jacquev6/PyGithub/releases/generate-notes +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"tag_name": "vX.Y.Z-by-PyGithub-acctest"} +200 +[('Date', 'Sun, 18 Aug 2024 23:56:45 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"f05115701836368bcab805d829f1453234af1eea7b25bf97c3effa382838f562"'), ('X-OAuth-Scopes', 'repo'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-11-14 21:03:22 UTC'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4982'), ('X-RateLimit-Reset', '1724025644'), ('X-RateLimit-Used', '18'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('Transfer-Encoding', 'chunked'), ('X-GitHub-Request-Id', '86EA:313F29:56B6E84:A55D123:66C28A3C'), ('Server', 'github.com')] +{"name":"vX.Y.Z-by-PyGithub-acctest","body":"**Full Changelog**: https://github.com/jacquev6/PyGithub/commits/vX.Y.Z-by-PyGithub-acctest"} diff --git a/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt b/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt new file mode 100644 index 0000000000..7f9d7a00cd --- /dev/null +++ b/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt @@ -0,0 +1,21 @@ +https +POST +api.github.com +None +/repos/jacquev6/PyGithub/releases +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"tag_name": "vX.Y.Z-by-PyGithub-acctest-previous", "draft": false, "prerelease": false, "generate_release_notes": false, "name": "vX.Y.Z: PyGithub acctest", "body": "This release is created by PyGithub"} +201 +[('Date', 'Mon, 19 Aug 2024 00:34:07 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1900'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With'), ('ETag', '"060006433f9b7748cbf7198d4f0d820482591704be702c1169dd21489da95c5d"'), ('X-OAuth-Scopes', 'repo'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-11-14 21:03:22 UTC'), ('Location', 'https://api.github.com/repos/jacquev6/PyGithub/releases/170779796'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4965'), ('X-RateLimit-Reset', '1724029435'), ('X-RateLimit-Used', '35'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-GitHub-Request-Id', 'D6C0:2B9908:1D4A719:37A4849:66C292FE'), ('Server', 'github.com')] +{"url":"https://api.github.com/repos/jacquev6/PyGithub/releases/170779796","assets_url":"https://api.github.com/repos/jacquev6/PyGithub/releases/170779796/assets","upload_url":"https://uploads.github.com/repos/jacquev6/PyGithub/releases/170779796/assets{?name,label}","html_url":"https://github.com/jacquev6/PyGithub/releases/tag/vX.Y.Z-by-PyGithub-acctest-previous","id":170779796,"author":{"login":"jacquev6","id":96152357,"node_id":"U_kgDOBbsrJQ","avatar_url":"https://avatars.githubusercontent.com/u/96152357?v=4","gravatar_id":"","url":"https://api.github.com/users/jacquev6","html_url":"https://github.com/jacquev6","followers_url":"https://api.github.com/users/jacquev6/followers","following_url":"https://api.github.com/users/jacquev6/following{/other_user}","gists_url":"https://api.github.com/users/jacquev6/gists{/gist_id}","starred_url":"https://api.github.com/users/jacquev6/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacquev6/subscriptions","organizations_url":"https://api.github.com/users/jacquev6/orgs","repos_url":"https://api.github.com/users/jacquev6/repos","events_url":"https://api.github.com/users/jacquev6/events{/privacy}","received_events_url":"https://api.github.com/users/jacquev6/received_events","type":"User","site_admin":false},"node_id":"RE_kwDOMlKsTM4KLeSU","tag_name":"vX.Y.Z-by-PyGithub-acctest-previous","target_commitish":"main","name":"vX.Y.Z: PyGithub acctest","draft":false,"prerelease":false,"created_at":"2024-08-19T00:25:59Z","published_at":"2024-08-19T00:34:06Z","assets":[],"tarball_url":"https://api.github.com/repos/jacquev6/PyGithub/tarball/vX.Y.Z-by-PyGithub-acctest-previous","zipball_url":"https://api.github.com/repos/jacquev6/PyGithub/zipball/vX.Y.Z-by-PyGithub-acctest-previous","body":"This release is created by PyGithub"} + +https +POST +api.github.com +None +/repos/jacquev6/PyGithub/releases/generate-notes +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"tag_name": "vX.Y.Z-by-PyGithub-acctest", "previous_tag_name": "vX.Y.Z-by-PyGithub-acctest-previous", "target_commitish": "main", "configuration_file_path": ".github/test_release_notes.yml"} +200 +[('Date', 'Mon, 19 Aug 2024 00:34:07 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"9cdecc62d8152adc4ab619d18dd9f194f4f76d5dba91ba53c92c9def3856f620"'), ('X-OAuth-Scopes', 'repo'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-11-14 21:03:22 UTC'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4964'), ('X-RateLimit-Reset', '1724029435'), ('X-RateLimit-Used', '36'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('Transfer-Encoding', 'chunked'), ('X-GitHub-Request-Id', 'D6C4:4388A:1BF3BE3:3510B09:66C292FF'), ('Server', 'github.com')] +{"name":"vX.Y.Z-by-PyGithub-acctest","body":"\n\n\n\n**Full Changelog**: https://github.com/jacquev6/PyGithub/compare/vX.Y.Z-by-PyGithub-acctest-previous...vX.Y.Z-by-PyGithub-acctest"} diff --git a/tests/Repository.py b/tests/Repository.py index 99aff82eba..b5c2aa8fda 100644 --- a/tests/Repository.py +++ b/tests/Repository.py @@ -436,6 +436,34 @@ def testCreateGitReleaseWithAllArguments(self): tag = [tag for tag in self.repo.get_tags() if tag.name == "vX.Y.Z-by-PyGithub-acctest2"].pop() self.assertEqual(tag.commit.sha, "da9a285fd8b782461e56cba39ae8d2fa41ca7cdc") + def testGenerateReleaseNotes(self): + notes = self.repo.generate_release_notes("vX.Y.Z-by-PyGithub-acctest") + self.assertEqual(notes.name, None) + self.assertEqual( + notes.body, "**Full Changelog**: https://github.com/jacquev6/PyGithub/commits/vX.Y.Z-by-PyGithub-acctest" + ) + self.assertEqual( + repr(notes), + 'GeneratedReleaseNotes(name=None, body="**Full Changelog**: https://github.com/jacquev6/PyGithub/commits/vX.Y.Z-by-PyGithub-acctest")', + ) + + def testGenerateReleaseNotesWithAllArguments(self): + self.repo.create_git_release( + tag="vX.Y.Z-by-PyGithub-acctest-previous", + name="vX.Y.Z: PyGithub acctest", + message="This release is created by PyGithub", + ) + notes = self.repo.generate_release_notes( + tag_name="vX.Y.Z-by-PyGithub-acctest", + previous_tag_name="vX.Y.Z-by-PyGithub-acctest-previous", + target_commitish="main", + configuration_file_path=".github/test_release_notes.yml", + ) + self.assertEqual(notes.name, None) + self.assertIn( + "Release notes generated using configuration in .github/test_release_notes.yml at main", notes.body + ) + def testCreateGitTag(self): tag = self.repo.create_git_tag( "TaggedByPyGithub", From 4c5739a0d1ffe3121ea86598d2ef80a75894d660 Mon Sep 17 00:00:00 2001 From: Matt Ball <96152357+mball-agathos@users.noreply.github.com> Date: Sun, 9 Feb 2025 16:31:26 -0700 Subject: [PATCH 03/17] Update github/Repository.py from reviewer suggestion Co-authored-by: Enrico Minack --- github/Repository.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/github/Repository.py b/github/Repository.py index 65812caa35..0924aa02f8 100644 --- a/github/Repository.py +++ b/github/Repository.py @@ -1539,17 +1539,12 @@ def generate_release_notes( configuration_file_path, str ), configuration_file_path - post_parameters = { + post_parameters = NotSet.remove_unset_items({ "tag_name": tag_name, - } - if is_defined(previous_tag_name): - post_parameters["previous_tag_name"] = str(previous_tag_name) - - if is_defined(target_commitish): - post_parameters["target_commitish"] = str(target_commitish) - - if is_defined(configuration_file_path): - post_parameters["configuration_file_path"] = str(configuration_file_path) + "previous_tag_name": previous_tag_name, + "target_commitish": target_commitish, + "configuration_file_path": configuration_file_path, + }) headers, data = self._requester.requestJsonAndCheck( "POST", f"{self.url}/releases/generate-notes", input=post_parameters From 7684e44f099d54687f8b62aaee312ba2ad650565 Mon Sep 17 00:00:00 2001 From: Matt Ball Date: Sun, 9 Feb 2025 16:32:06 -0700 Subject: [PATCH 04/17] Add description to test_release_notes.yml --- .github/test_release_notes.yml | 8 -------- tests/test_release_notes.yml | 13 +++++++++++++ 2 files changed, 13 insertions(+), 8 deletions(-) delete mode 100644 .github/test_release_notes.yml create mode 100644 tests/test_release_notes.yml diff --git a/.github/test_release_notes.yml b/.github/test_release_notes.yml deleted file mode 100644 index ba0b1cdf01..0000000000 --- a/.github/test_release_notes.yml +++ /dev/null @@ -1,8 +0,0 @@ -# This file is needed for generating release notes for the Repository::testGenerateReleaseNotesWithAllArguments test -# See https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes - -changelog: - categories: - - title: Features - labels: - - '*' diff --git a/tests/test_release_notes.yml b/tests/test_release_notes.yml new file mode 100644 index 0000000000..cf33e804ef --- /dev/null +++ b/tests/test_release_notes.yml @@ -0,0 +1,13 @@ +# This file is needed for generating release notes for the Repository::testGenerateReleaseNotesWithAllArguments test +# See https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes + +# This is used to generate the ReplayData as used by Repository::testGenerateReleaseNotesWithAllArguments. +# If you need to regenerate this ReplayData files, you will need to copy this yaml file +# into the `.github` directory on the main branch of your forked repository. +# The GitHub API expects to see this file in the `.github` directory when generating release notes. + +changelog: + categories: + - title: Features + labels: + - '*' From a22537442a138521fe667048b55628d3c231d160 Mon Sep 17 00:00:00 2001 From: Matt Ball Date: Sun, 9 Feb 2025 21:32:30 -0700 Subject: [PATCH 05/17] rename jacquev6 to PyGithub --- .../ReplayData/Repository.testGenerateReleaseNotes.txt | 4 ++-- ...sitory.testGenerateReleaseNotesWithAllArguments.txt | 10 +++++----- tests/Repository.py | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/ReplayData/Repository.testGenerateReleaseNotes.txt b/tests/ReplayData/Repository.testGenerateReleaseNotes.txt index 9c509d67ea..9f20c31258 100644 --- a/tests/ReplayData/Repository.testGenerateReleaseNotes.txt +++ b/tests/ReplayData/Repository.testGenerateReleaseNotes.txt @@ -2,9 +2,9 @@ https POST api.github.com None -/repos/jacquev6/PyGithub/releases/generate-notes +/repos/PyGithub/PyGithub/releases/generate-notes {'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} {"tag_name": "vX.Y.Z-by-PyGithub-acctest"} 200 [('Date', 'Sun, 18 Aug 2024 23:56:45 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"f05115701836368bcab805d829f1453234af1eea7b25bf97c3effa382838f562"'), ('X-OAuth-Scopes', 'repo'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-11-14 21:03:22 UTC'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4982'), ('X-RateLimit-Reset', '1724025644'), ('X-RateLimit-Used', '18'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('Transfer-Encoding', 'chunked'), ('X-GitHub-Request-Id', '86EA:313F29:56B6E84:A55D123:66C28A3C'), ('Server', 'github.com')] -{"name":"vX.Y.Z-by-PyGithub-acctest","body":"**Full Changelog**: https://github.com/jacquev6/PyGithub/commits/vX.Y.Z-by-PyGithub-acctest"} +{"name":"vX.Y.Z-by-PyGithub-acctest","body":"**Full Changelog**: https://github.com/PyGithub/PyGithub/commits/vX.Y.Z-by-PyGithub-acctest"} diff --git a/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt b/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt index 7f9d7a00cd..60e1975899 100644 --- a/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt +++ b/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt @@ -2,20 +2,20 @@ https POST api.github.com None -/repos/jacquev6/PyGithub/releases +/repos/PyGithub/PyGithub/releases {'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} {"tag_name": "vX.Y.Z-by-PyGithub-acctest-previous", "draft": false, "prerelease": false, "generate_release_notes": false, "name": "vX.Y.Z: PyGithub acctest", "body": "This release is created by PyGithub"} 201 -[('Date', 'Mon, 19 Aug 2024 00:34:07 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1900'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With'), ('ETag', '"060006433f9b7748cbf7198d4f0d820482591704be702c1169dd21489da95c5d"'), ('X-OAuth-Scopes', 'repo'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-11-14 21:03:22 UTC'), ('Location', 'https://api.github.com/repos/jacquev6/PyGithub/releases/170779796'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4965'), ('X-RateLimit-Reset', '1724029435'), ('X-RateLimit-Used', '35'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-GitHub-Request-Id', 'D6C0:2B9908:1D4A719:37A4849:66C292FE'), ('Server', 'github.com')] -{"url":"https://api.github.com/repos/jacquev6/PyGithub/releases/170779796","assets_url":"https://api.github.com/repos/jacquev6/PyGithub/releases/170779796/assets","upload_url":"https://uploads.github.com/repos/jacquev6/PyGithub/releases/170779796/assets{?name,label}","html_url":"https://github.com/jacquev6/PyGithub/releases/tag/vX.Y.Z-by-PyGithub-acctest-previous","id":170779796,"author":{"login":"jacquev6","id":96152357,"node_id":"U_kgDOBbsrJQ","avatar_url":"https://avatars.githubusercontent.com/u/96152357?v=4","gravatar_id":"","url":"https://api.github.com/users/jacquev6","html_url":"https://github.com/jacquev6","followers_url":"https://api.github.com/users/jacquev6/followers","following_url":"https://api.github.com/users/jacquev6/following{/other_user}","gists_url":"https://api.github.com/users/jacquev6/gists{/gist_id}","starred_url":"https://api.github.com/users/jacquev6/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacquev6/subscriptions","organizations_url":"https://api.github.com/users/jacquev6/orgs","repos_url":"https://api.github.com/users/jacquev6/repos","events_url":"https://api.github.com/users/jacquev6/events{/privacy}","received_events_url":"https://api.github.com/users/jacquev6/received_events","type":"User","site_admin":false},"node_id":"RE_kwDOMlKsTM4KLeSU","tag_name":"vX.Y.Z-by-PyGithub-acctest-previous","target_commitish":"main","name":"vX.Y.Z: PyGithub acctest","draft":false,"prerelease":false,"created_at":"2024-08-19T00:25:59Z","published_at":"2024-08-19T00:34:06Z","assets":[],"tarball_url":"https://api.github.com/repos/jacquev6/PyGithub/tarball/vX.Y.Z-by-PyGithub-acctest-previous","zipball_url":"https://api.github.com/repos/jacquev6/PyGithub/zipball/vX.Y.Z-by-PyGithub-acctest-previous","body":"This release is created by PyGithub"} +[('Date', 'Mon, 19 Aug 2024 00:34:07 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1900'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With'), ('ETag', '"060006433f9b7748cbf7198d4f0d820482591704be702c1169dd21489da95c5d"'), ('X-OAuth-Scopes', 'repo'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-11-14 21:03:22 UTC'), ('Location', 'https://api.github.com/repos/PyGithub/PyGithub/releases/170779796'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4965'), ('X-RateLimit-Reset', '1724029435'), ('X-RateLimit-Used', '35'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-GitHub-Request-Id', 'D6C0:2B9908:1D4A719:37A4849:66C292FE'), ('Server', 'github.com')] +{"url":"https://api.github.com/repos/PyGithub/PyGithub/releases/170779796","assets_url":"https://api.github.com/repos/PyGithub/PyGithub/releases/170779796/assets","upload_url":"https://uploads.github.com/repos/PyGithub/PyGithub/releases/170779796/assets{?name,label}","html_url":"https://github.com/PyGithub/PyGithub/releases/tag/vX.Y.Z-by-PyGithub-acctest-previous","id":170779796,"author":{"login":"PyGithub","id":96152357,"node_id":"U_kgDOBbsrJQ","avatar_url":"https://avatars.githubusercontent.com/u/96152357?v=4","gravatar_id":"","url":"https://api.github.com/users/PyGithub","html_url":"https://github.com/PyGithub","followers_url":"https://api.github.com/users/PyGithub/followers","following_url":"https://api.github.com/users/PyGithub/following{/other_user}","gists_url":"https://api.github.com/users/PyGithub/gists{/gist_id}","starred_url":"https://api.github.com/users/PyGithub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PyGithub/subscriptions","organizations_url":"https://api.github.com/users/PyGithub/orgs","repos_url":"https://api.github.com/users/PyGithub/repos","events_url":"https://api.github.com/users/PyGithub/events{/privacy}","received_events_url":"https://api.github.com/users/PyGithub/received_events","type":"User","site_admin":false},"node_id":"RE_kwDOMlKsTM4KLeSU","tag_name":"vX.Y.Z-by-PyGithub-acctest-previous","target_commitish":"main","name":"vX.Y.Z: PyGithub acctest","draft":false,"prerelease":false,"created_at":"2024-08-19T00:25:59Z","published_at":"2024-08-19T00:34:06Z","assets":[],"tarball_url":"https://api.github.com/repos/PyGithub/PyGithub/tarball/vX.Y.Z-by-PyGithub-acctest-previous","zipball_url":"https://api.github.com/repos/PyGithub/PyGithub/zipball/vX.Y.Z-by-PyGithub-acctest-previous","body":"This release is created by PyGithub"} https POST api.github.com None -/repos/jacquev6/PyGithub/releases/generate-notes +/repos/PyGithub/PyGithub/releases/generate-notes {'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} {"tag_name": "vX.Y.Z-by-PyGithub-acctest", "previous_tag_name": "vX.Y.Z-by-PyGithub-acctest-previous", "target_commitish": "main", "configuration_file_path": ".github/test_release_notes.yml"} 200 [('Date', 'Mon, 19 Aug 2024 00:34:07 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"9cdecc62d8152adc4ab619d18dd9f194f4f76d5dba91ba53c92c9def3856f620"'), ('X-OAuth-Scopes', 'repo'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-11-14 21:03:22 UTC'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4964'), ('X-RateLimit-Reset', '1724029435'), ('X-RateLimit-Used', '36'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('Transfer-Encoding', 'chunked'), ('X-GitHub-Request-Id', 'D6C4:4388A:1BF3BE3:3510B09:66C292FF'), ('Server', 'github.com')] -{"name":"vX.Y.Z-by-PyGithub-acctest","body":"\n\n\n\n**Full Changelog**: https://github.com/jacquev6/PyGithub/compare/vX.Y.Z-by-PyGithub-acctest-previous...vX.Y.Z-by-PyGithub-acctest"} +{"name":"vX.Y.Z-by-PyGithub-acctest","body":"\n\n\n\n**Full Changelog**: https://github.com/PyGithub/PyGithub/compare/vX.Y.Z-by-PyGithub-acctest-previous...vX.Y.Z-by-PyGithub-acctest"} diff --git a/tests/Repository.py b/tests/Repository.py index 7c0d45ccc5..53168359fb 100644 --- a/tests/Repository.py +++ b/tests/Repository.py @@ -534,11 +534,11 @@ def testGenerateReleaseNotes(self): notes = self.repo.generate_release_notes("vX.Y.Z-by-PyGithub-acctest") self.assertEqual(notes.name, None) self.assertEqual( - notes.body, "**Full Changelog**: https://github.com/jacquev6/PyGithub/commits/vX.Y.Z-by-PyGithub-acctest" + notes.body, "**Full Changelog**: https://github.com/PyGithub/PyGithub/commits/vX.Y.Z-by-PyGithub-acctest" ) self.assertEqual( repr(notes), - 'GeneratedReleaseNotes(name=None, body="**Full Changelog**: https://github.com/jacquev6/PyGithub/commits/vX.Y.Z-by-PyGithub-acctest")', + 'GeneratedReleaseNotes(name=None, body="**Full Changelog**: https://github.com/PyGithub/PyGithub/commits/vX.Y.Z-by-PyGithub-acctest")', ) def testGenerateReleaseNotesWithAllArguments(self): @@ -551,7 +551,7 @@ def testGenerateReleaseNotesWithAllArguments(self): tag_name="vX.Y.Z-by-PyGithub-acctest", previous_tag_name="vX.Y.Z-by-PyGithub-acctest-previous", target_commitish="main", - configuration_file_path=".github/test_release_notes.yml", + configuration_file_path="tests/test_release_notes.yml", ) self.assertEqual(notes.name, None) self.assertIn( From 88ea15d9ee56df8391a40a7b0dcb007eb7a57739 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Wed, 13 Aug 2025 18:25:39 +0200 Subject: [PATCH 06/17] Fix test replay data authentication --- tests/ReplayData/Repository.testGenerateReleaseNotes.txt | 2 +- .../Repository.testGenerateReleaseNotesWithAllArguments.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ReplayData/Repository.testGenerateReleaseNotes.txt b/tests/ReplayData/Repository.testGenerateReleaseNotes.txt index 9f20c31258..71c53ad1b6 100644 --- a/tests/ReplayData/Repository.testGenerateReleaseNotes.txt +++ b/tests/ReplayData/Repository.testGenerateReleaseNotes.txt @@ -3,7 +3,7 @@ POST api.github.com None /repos/PyGithub/PyGithub/releases/generate-notes -{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} {"tag_name": "vX.Y.Z-by-PyGithub-acctest"} 200 [('Date', 'Sun, 18 Aug 2024 23:56:45 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"f05115701836368bcab805d829f1453234af1eea7b25bf97c3effa382838f562"'), ('X-OAuth-Scopes', 'repo'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-11-14 21:03:22 UTC'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4982'), ('X-RateLimit-Reset', '1724025644'), ('X-RateLimit-Used', '18'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('Transfer-Encoding', 'chunked'), ('X-GitHub-Request-Id', '86EA:313F29:56B6E84:A55D123:66C28A3C'), ('Server', 'github.com')] diff --git a/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt b/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt index 60e1975899..282889d9e2 100644 --- a/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt +++ b/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt @@ -3,7 +3,7 @@ POST api.github.com None /repos/PyGithub/PyGithub/releases -{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} {"tag_name": "vX.Y.Z-by-PyGithub-acctest-previous", "draft": false, "prerelease": false, "generate_release_notes": false, "name": "vX.Y.Z: PyGithub acctest", "body": "This release is created by PyGithub"} 201 [('Date', 'Mon, 19 Aug 2024 00:34:07 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1900'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With'), ('ETag', '"060006433f9b7748cbf7198d4f0d820482591704be702c1169dd21489da95c5d"'), ('X-OAuth-Scopes', 'repo'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-11-14 21:03:22 UTC'), ('Location', 'https://api.github.com/repos/PyGithub/PyGithub/releases/170779796'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4965'), ('X-RateLimit-Reset', '1724029435'), ('X-RateLimit-Used', '35'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-GitHub-Request-Id', 'D6C0:2B9908:1D4A719:37A4849:66C292FE'), ('Server', 'github.com')] @@ -14,7 +14,7 @@ POST api.github.com None /repos/PyGithub/PyGithub/releases/generate-notes -{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} {"tag_name": "vX.Y.Z-by-PyGithub-acctest", "previous_tag_name": "vX.Y.Z-by-PyGithub-acctest-previous", "target_commitish": "main", "configuration_file_path": ".github/test_release_notes.yml"} 200 [('Date', 'Mon, 19 Aug 2024 00:34:07 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"9cdecc62d8152adc4ab619d18dd9f194f4f76d5dba91ba53c92c9def3856f620"'), ('X-OAuth-Scopes', 'repo'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-11-14 21:03:22 UTC'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4964'), ('X-RateLimit-Reset', '1724029435'), ('X-RateLimit-Used', '36'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('Transfer-Encoding', 'chunked'), ('X-GitHub-Request-Id', 'D6C4:4388A:1BF3BE3:3510B09:66C292FF'), ('Server', 'github.com')] From 3167fd77d5cdc2a3835bc277f655bc719eafb156 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Wed, 13 Aug 2025 18:32:29 +0200 Subject: [PATCH 07/17] Add "make_latest" to test replay data required by main branch changes --- .../Repository.testGenerateReleaseNotesWithAllArguments.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt b/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt index 282889d9e2..d12362f3e7 100644 --- a/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt +++ b/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt @@ -4,7 +4,7 @@ api.github.com None /repos/PyGithub/PyGithub/releases {'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} -{"tag_name": "vX.Y.Z-by-PyGithub-acctest-previous", "draft": false, "prerelease": false, "generate_release_notes": false, "name": "vX.Y.Z: PyGithub acctest", "body": "This release is created by PyGithub"} +{"tag_name": "vX.Y.Z-by-PyGithub-acctest-previous", "draft": false, "prerelease": false, "generate_release_notes": false, "name": "vX.Y.Z: PyGithub acctest", "body": "This release is created by PyGithub", "make_latest": "true"} 201 [('Date', 'Mon, 19 Aug 2024 00:34:07 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '1900'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With'), ('ETag', '"060006433f9b7748cbf7198d4f0d820482591704be702c1169dd21489da95c5d"'), ('X-OAuth-Scopes', 'repo'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-11-14 21:03:22 UTC'), ('Location', 'https://api.github.com/repos/PyGithub/PyGithub/releases/170779796'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4965'), ('X-RateLimit-Reset', '1724029435'), ('X-RateLimit-Used', '35'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('X-GitHub-Request-Id', 'D6C0:2B9908:1D4A719:37A4849:66C292FE'), ('Server', 'github.com')] {"url":"https://api.github.com/repos/PyGithub/PyGithub/releases/170779796","assets_url":"https://api.github.com/repos/PyGithub/PyGithub/releases/170779796/assets","upload_url":"https://uploads.github.com/repos/PyGithub/PyGithub/releases/170779796/assets{?name,label}","html_url":"https://github.com/PyGithub/PyGithub/releases/tag/vX.Y.Z-by-PyGithub-acctest-previous","id":170779796,"author":{"login":"PyGithub","id":96152357,"node_id":"U_kgDOBbsrJQ","avatar_url":"https://avatars.githubusercontent.com/u/96152357?v=4","gravatar_id":"","url":"https://api.github.com/users/PyGithub","html_url":"https://github.com/PyGithub","followers_url":"https://api.github.com/users/PyGithub/followers","following_url":"https://api.github.com/users/PyGithub/following{/other_user}","gists_url":"https://api.github.com/users/PyGithub/gists{/gist_id}","starred_url":"https://api.github.com/users/PyGithub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PyGithub/subscriptions","organizations_url":"https://api.github.com/users/PyGithub/orgs","repos_url":"https://api.github.com/users/PyGithub/repos","events_url":"https://api.github.com/users/PyGithub/events{/privacy}","received_events_url":"https://api.github.com/users/PyGithub/received_events","type":"User","site_admin":false},"node_id":"RE_kwDOMlKsTM4KLeSU","tag_name":"vX.Y.Z-by-PyGithub-acctest-previous","target_commitish":"main","name":"vX.Y.Z: PyGithub acctest","draft":false,"prerelease":false,"created_at":"2024-08-19T00:25:59Z","published_at":"2024-08-19T00:34:06Z","assets":[],"tarball_url":"https://api.github.com/repos/PyGithub/PyGithub/tarball/vX.Y.Z-by-PyGithub-acctest-previous","zipball_url":"https://api.github.com/repos/PyGithub/PyGithub/zipball/vX.Y.Z-by-PyGithub-acctest-previous","body":"This release is created by PyGithub"} From 5ca73204a2cc5849e2979a1aed9693a808321986 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Wed, 13 Aug 2025 20:55:05 +0200 Subject: [PATCH 08/17] Fix path to config file in test replay data --- .../Repository.testGenerateReleaseNotesWithAllArguments.txt | 4 ++-- tests/Repository.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt b/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt index d12362f3e7..405365135a 100644 --- a/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt +++ b/tests/ReplayData/Repository.testGenerateReleaseNotesWithAllArguments.txt @@ -15,7 +15,7 @@ api.github.com None /repos/PyGithub/PyGithub/releases/generate-notes {'Authorization': 'token private_token_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} -{"tag_name": "vX.Y.Z-by-PyGithub-acctest", "previous_tag_name": "vX.Y.Z-by-PyGithub-acctest-previous", "target_commitish": "main", "configuration_file_path": ".github/test_release_notes.yml"} +{"tag_name": "vX.Y.Z-by-PyGithub-acctest", "previous_tag_name": "vX.Y.Z-by-PyGithub-acctest-previous", "target_commitish": "main", "configuration_file_path": "tests/test_release_notes.yml"} 200 [('Date', 'Mon, 19 Aug 2024 00:34:07 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"9cdecc62d8152adc4ab619d18dd9f194f4f76d5dba91ba53c92c9def3856f620"'), ('X-OAuth-Scopes', 'repo'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-11-14 21:03:22 UTC'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4964'), ('X-RateLimit-Reset', '1724029435'), ('X-RateLimit-Used', '36'), ('X-RateLimit-Resource', 'core'), ('Access-Control-Expose-Headers', 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset'), ('Access-Control-Allow-Origin', '*'), ('Strict-Transport-Security', 'max-age=31536000; includeSubdomains; preload'), ('X-Frame-Options', 'deny'), ('X-Content-Type-Options', 'nosniff'), ('X-XSS-Protection', '0'), ('Referrer-Policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('Content-Security-Policy', "default-src 'none'"), ('Content-Encoding', 'gzip'), ('Transfer-Encoding', 'chunked'), ('X-GitHub-Request-Id', 'D6C4:4388A:1BF3BE3:3510B09:66C292FF'), ('Server', 'github.com')] -{"name":"vX.Y.Z-by-PyGithub-acctest","body":"\n\n\n\n**Full Changelog**: https://github.com/PyGithub/PyGithub/compare/vX.Y.Z-by-PyGithub-acctest-previous...vX.Y.Z-by-PyGithub-acctest"} +{"name":"vX.Y.Z-by-PyGithub-acctest","body":"\n\n\n\n**Full Changelog**: https://github.com/PyGithub/PyGithub/compare/vX.Y.Z-by-PyGithub-acctest-previous...vX.Y.Z-by-PyGithub-acctest"} diff --git a/tests/Repository.py b/tests/Repository.py index bee6607910..fff781b30e 100644 --- a/tests/Repository.py +++ b/tests/Repository.py @@ -562,7 +562,7 @@ def testGenerateReleaseNotesWithAllArguments(self): ) self.assertEqual(notes.name, None) self.assertIn( - "Release notes generated using configuration in .github/test_release_notes.yml at main", notes.body + "Release notes generated using configuration in tests/test_release_notes.yml at main", notes.body ) def testCreateGitTag(self): From 9ff1ccaacf2858af1b82cb1cba92720b5c6cb79a Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 14 Aug 2025 06:41:38 +0200 Subject: [PATCH 09/17] Add OpenAPI schema --- github/GeneratedReleaseNotes.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/github/GeneratedReleaseNotes.py b/github/GeneratedReleaseNotes.py index f46779b584..b9a8767425 100644 --- a/github/GeneratedReleaseNotes.py +++ b/github/GeneratedReleaseNotes.py @@ -19,6 +19,9 @@ class GeneratedReleaseNotes(CompletableGithubObject): The reference can be found here: https://docs.github.com/en/rest/releases/releases#generate-release-notes-content-for-a-release + The OpenAPI schema can be found at + - /components/schemas/release-notes-content + """ def _initAttributes(self) -> None: From 5f2b306be67cefce8db9ff0c65c70b57e3bc2f97 Mon Sep 17 00:00:00 2001 From: Matt Ball Date: Thu, 14 Aug 2025 07:58:02 -0600 Subject: [PATCH 10/17] Run black to reformat files --- github/Repository.py | 14 ++++++++------ tests/Repository.py | 4 +--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/github/Repository.py b/github/Repository.py index 2815b9ff22..896b52b5d8 100644 --- a/github/Repository.py +++ b/github/Repository.py @@ -1572,12 +1572,14 @@ def generate_release_notes( configuration_file_path, str ), configuration_file_path - post_parameters = NotSet.remove_unset_items({ - "tag_name": tag_name, - "previous_tag_name": previous_tag_name, - "target_commitish": target_commitish, - "configuration_file_path": configuration_file_path, - }) + post_parameters = NotSet.remove_unset_items( + { + "tag_name": tag_name, + "previous_tag_name": previous_tag_name, + "target_commitish": target_commitish, + "configuration_file_path": configuration_file_path, + } + ) headers, data = self._requester.requestJsonAndCheck( "POST", f"{self.url}/releases/generate-notes", input=post_parameters diff --git a/tests/Repository.py b/tests/Repository.py index fff781b30e..58728c500c 100644 --- a/tests/Repository.py +++ b/tests/Repository.py @@ -561,9 +561,7 @@ def testGenerateReleaseNotesWithAllArguments(self): configuration_file_path="tests/test_release_notes.yml", ) self.assertEqual(notes.name, None) - self.assertIn( - "Release notes generated using configuration in tests/test_release_notes.yml at main", notes.body - ) + self.assertIn("Release notes generated using configuration in tests/test_release_notes.yml at main", notes.body) def testCreateGitTag(self): tag = self.repo.create_git_tag( From 84257d7011b4d76de85ba0ab5a17d58d4ad5bcf8 Mon Sep 17 00:00:00 2001 From: Matt Ball Date: Wed, 27 Aug 2025 16:48:49 -0600 Subject: [PATCH 11/17] Fix attribute ordering in GeneratedReleaseNotes.py --- github/GeneratedReleaseNotes.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/github/GeneratedReleaseNotes.py b/github/GeneratedReleaseNotes.py index b9a8767425..cf7c6a43d3 100644 --- a/github/GeneratedReleaseNotes.py +++ b/github/GeneratedReleaseNotes.py @@ -25,20 +25,20 @@ class GeneratedReleaseNotes(CompletableGithubObject): """ def _initAttributes(self) -> None: - self._name: Attribute[str] = NotSet self._body: Attribute[str] = NotSet + self._name: Attribute[str] = NotSet def __repr__(self) -> str: return self.get__repr__({"name": self._name.value, "body": self._body.value}) - @property - def name(self) -> str: - return self._name.value - @property def body(self) -> str: return self._body.value + @property + def name(self) -> str: + return self._name.value + def _useAttributes(self, attributes: Dict[str, Any]) -> None: if "body" in attributes: self._body = self._makeStringAttribute(attributes["body"]) From be2cc7e202a30bfacb69c3e53157eed2ea866024 Mon Sep 17 00:00:00 2001 From: Matt Ball Date: Wed, 27 Aug 2025 18:06:44 -0600 Subject: [PATCH 12/17] Fix typo in _useAttributes method of GeneratedReleaseNotes --- github/GeneratedReleaseNotes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/GeneratedReleaseNotes.py b/github/GeneratedReleaseNotes.py index cf7c6a43d3..52951a4ad0 100644 --- a/github/GeneratedReleaseNotes.py +++ b/github/GeneratedReleaseNotes.py @@ -43,4 +43,4 @@ def _useAttributes(self, attributes: Dict[str, Any]) -> None: if "body" in attributes: self._body = self._makeStringAttribute(attributes["body"]) if "name" in attributes: - self._title = self._makeStringAttribute(attributes["name"]) + self._name = self._makeStringAttribute(attributes["name"]) From e9e068dc998d4026b91b658c2fd6f3fa10ce22f9 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 28 Aug 2025 20:34:11 +0200 Subject: [PATCH 13/17] Fix assertions --- tests/Repository.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Repository.py b/tests/Repository.py index ccfd3f2b60..56f166cff6 100644 --- a/tests/Repository.py +++ b/tests/Repository.py @@ -539,13 +539,13 @@ def testCreateGitReleaseWithAllArguments(self): def testGenerateReleaseNotes(self): notes = self.repo.generate_release_notes("vX.Y.Z-by-PyGithub-acctest") - self.assertEqual(notes.name, None) + self.assertEqual(notes.name, "vX.Y.Z-by-PyGithub-acctest") self.assertEqual( notes.body, "**Full Changelog**: https://github.com/PyGithub/PyGithub/commits/vX.Y.Z-by-PyGithub-acctest" ) self.assertEqual( repr(notes), - 'GeneratedReleaseNotes(name=None, body="**Full Changelog**: https://github.com/PyGithub/PyGithub/commits/vX.Y.Z-by-PyGithub-acctest")', + 'GeneratedReleaseNotes(name="vX.Y.Z-by-PyGithub-acctest", body="**Full Changelog**: https://github.com/PyGithub/PyGithub/commits/vX.Y.Z-by-PyGithub-acctest")', ) def testGenerateReleaseNotesWithAllArguments(self): @@ -560,7 +560,7 @@ def testGenerateReleaseNotesWithAllArguments(self): target_commitish="main", configuration_file_path="tests/test_release_notes.yml", ) - self.assertEqual(notes.name, None) + self.assertEqual(notes.name, "vX.Y.Z-by-PyGithub-acctest") self.assertIn("Release notes generated using configuration in tests/test_release_notes.yml at main", notes.body) def testCreateGitTag(self): From 7c65abf6911ee564c2f8ec45585408e4e748d4e1 Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 28 Aug 2025 20:43:56 +0200 Subject: [PATCH 14/17] Minor cleanup, no functional change --- github/GeneratedReleaseNotes.py | 10 ++++------ github/Repository.py | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/github/GeneratedReleaseNotes.py b/github/GeneratedReleaseNotes.py index 52951a4ad0..0db53e732a 100644 --- a/github/GeneratedReleaseNotes.py +++ b/github/GeneratedReleaseNotes.py @@ -1,6 +1,4 @@ -""" -Representation of the generated release notes returned by the release/generate-notes REST API endpoint. -""" +from __future__ import annotations from typing import Any, Dict @@ -11,8 +9,7 @@ ) -# New file named github/GeneratedReleaseNotes.py -class GeneratedReleaseNotes(CompletableGithubObject): +class GeneratedReleaseNotes(NonCompletableGithubObject): """ This class represents the release notes generated by the release/generate-notes REST API endpoint. @@ -20,7 +17,8 @@ class GeneratedReleaseNotes(CompletableGithubObject): https://docs.github.com/en/rest/releases/releases#generate-release-notes-content-for-a-release The OpenAPI schema can be found at - - /components/schemas/release-notes-content + + - /components/schemas/release-notes-content """ diff --git a/github/Repository.py b/github/Repository.py index 6ed4c0dd58..88f60f546e 100644 --- a/github/Repository.py +++ b/github/Repository.py @@ -1585,7 +1585,7 @@ def generate_release_notes( "POST", f"{self.url}/releases/generate-notes", input=post_parameters ) - return GeneratedReleaseNotes(self._requester, headers, data, completed=True) + return GeneratedReleaseNotes(self._requester, headers, data) def create_git_tag( self, From 30b203c349fe9f61d3a616452fea82d50bc8613d Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 28 Aug 2025 20:48:48 +0200 Subject: [PATCH 15/17] Fix import and linting --- github/GeneratedReleaseNotes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/github/GeneratedReleaseNotes.py b/github/GeneratedReleaseNotes.py index 0db53e732a..73a044ce10 100644 --- a/github/GeneratedReleaseNotes.py +++ b/github/GeneratedReleaseNotes.py @@ -1,10 +1,10 @@ from __future__ import annotations -from typing import Any, Dict +from typing import Any from github.GithubObject import ( Attribute, - CompletableGithubObject, + NonCompletableGithubObject, NotSet, ) @@ -37,7 +37,7 @@ def body(self) -> str: def name(self) -> str: return self._name.value - def _useAttributes(self, attributes: Dict[str, Any]) -> None: + def _useAttributes(self, attributes: dict[str, Any]) -> None: if "body" in attributes: self._body = self._makeStringAttribute(attributes["body"]) if "name" in attributes: From 78c2a2cc6bf94a6c945ce1f989147ff91ddbfe0d Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 28 Aug 2025 21:01:46 +0200 Subject: [PATCH 16/17] Fix schema annotation --- github/GeneratedReleaseNotes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/GeneratedReleaseNotes.py b/github/GeneratedReleaseNotes.py index 73a044ce10..9d8a313a6d 100644 --- a/github/GeneratedReleaseNotes.py +++ b/github/GeneratedReleaseNotes.py @@ -18,7 +18,7 @@ class GeneratedReleaseNotes(NonCompletableGithubObject): The OpenAPI schema can be found at - - /components/schemas/release-notes-content + - /components/schemas/release-notes-content """ From c6b083516626a09abbb0c7d7b03c1d1dd028d40e Mon Sep 17 00:00:00 2001 From: Enrico Minack Date: Thu, 28 Aug 2025 21:14:05 +0200 Subject: [PATCH 17/17] Revert empty line before schema annotation --- github/GeneratedReleaseNotes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/github/GeneratedReleaseNotes.py b/github/GeneratedReleaseNotes.py index 9d8a313a6d..f821990c6f 100644 --- a/github/GeneratedReleaseNotes.py +++ b/github/GeneratedReleaseNotes.py @@ -17,7 +17,6 @@ class GeneratedReleaseNotes(NonCompletableGithubObject): https://docs.github.com/en/rest/releases/releases#generate-release-notes-content-for-a-release The OpenAPI schema can be found at - - /components/schemas/release-notes-content """