diff --git a/github/Workflow.py b/github/Workflow.py index 2edc7e5cd..f75929308 100644 --- a/github/Workflow.py +++ b/github/Workflow.py @@ -47,6 +47,7 @@ import github.Branch import github.Commit +import github.GithubException as GithubException import github.GithubObject import github.NamedUser import github.Tag @@ -123,12 +124,9 @@ def badge_url(self) -> str: self._completeIfNotSet(self._badge_url) return self._badge_url.value - def create_dispatch( + def _create_dispatch( self, ref: github.Branch.Branch | github.Tag.Tag | github.Commit.Commit | str, inputs: Opt[dict] = NotSet - ) -> bool: - """ - :calls: `POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches `_ - """ + ) -> None: assert ( isinstance(ref, github.Branch.Branch) or isinstance(ref, github.Tag.Tag) @@ -144,10 +142,33 @@ def create_dispatch( ref = ref.name if inputs is NotSet: inputs = {} - status, _, _ = self._requester.requestJson( - "POST", f"{self.url}/dispatches", input={"ref": ref, "inputs": inputs} - ) - return status == 204 + self._requester.requestJsonAndCheck("POST", f"{self.url}/dispatches", input={"ref": ref, "inputs": inputs}) + + def create_dispatch_throw( + self, ref: github.Branch.Branch | github.Tag.Tag | github.Commit.Commit | str, inputs: Opt[dict] = NotSet + ) -> Any: + """ + Call Create Dispatch, throw an exception on error. + + :calls: `POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches `_ + + """ + return self._create_dispatch(ref, inputs) + + def create_dispatch( + self, ref: github.Branch.Branch | github.Tag.Tag | github.Commit.Commit | str, inputs: Opt[dict] = NotSet + ) -> bool: + """ + Call Create Dispatch, return False without details on error. + + :calls: `POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches `_ + + """ + try: + self._create_dispatch(ref, inputs) + except GithubException.GithubException: + return False + return True def get_runs( self, diff --git a/tests/ReplayData/Workflow.testCreateDispatchException.txt b/tests/ReplayData/Workflow.testCreateDispatchException.txt new file mode 100644 index 000000000..6321feec9 --- /dev/null +++ b/tests/ReplayData/Workflow.testCreateDispatchException.txt @@ -0,0 +1,32 @@ +https +GET +api.github.com +None +/repos/test-org/test-repo +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Server', 'GitHub.com'), ('Date', 'Mon, 06 May 2024 19:51:59 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"8039ee84b4eb207b1398275d957b94ee80320c859f018fad7c1f5000605cce41"'), ('Last-Modified', 'Mon, 06 May 2024 19:34:50 GMT'), ('X-OAuth-Scopes', 'repo, workflow'), ('X-Accepted-OAuth-Scopes', 'repo'), ('github-authentication-token-expiration', '2024-05-13 19:47:28 UTC'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '3537'), ('X-RateLimit-Reset', '1715026915'), ('X-RateLimit-Used', '1463'), ('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'), ('X-GitHub-Request-Id', 'E3A5:292E30:123CE55:1DCE5F8:663934DF')] +{"id":787458459,"node_id":"R_kgDOLu-pmw","name":"test-repo","full_name":"test-org/test-repo","private":true,"owner":{"login":"test-org","id":127791185,"node_id":"O_kgDOB53wUQ","avatar_url":"https://avatars.githubusercontent.com/u/127791185?v=4","gravatar_id":"","url":"https://api.github.com/users/test-org","html_url":"https://github.com/test-org","followers_url":"https://api.github.com/users/test-org/followers","following_url":"https://api.github.com/users/test-org/following{/other_user}","gists_url":"https://api.github.com/users/test-org/gists{/gist_id}","starred_url":"https://api.github.com/users/test-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/test-org/subscriptions","organizations_url":"https://api.github.com/users/test-org/orgs","repos_url":"https://api.github.com/users/test-org/repos","events_url":"https://api.github.com/users/test-org/events{/privacy}","received_events_url":"https://api.github.com/users/test-org/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/test-org/test-repo","description":"","fork":false,"url":"https://api.github.com/repos/test-org/test-repo","forks_url":"https://api.github.com/repos/test-org/test-repo/forks","keys_url":"https://api.github.com/repos/test-org/test-repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/test-org/test-repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/test-org/test-repo/teams","hooks_url":"https://api.github.com/repos/test-org/test-repo/hooks","issue_events_url":"https://api.github.com/repos/test-org/test-repo/issues/events{/number}","events_url":"https://api.github.com/repos/test-org/test-repo/events","assignees_url":"https://api.github.com/repos/test-org/test-repo/assignees{/user}","branches_url":"https://api.github.com/repos/test-org/test-repo/branches{/branch}","tags_url":"https://api.github.com/repos/test-org/test-repo/tags","blobs_url":"https://api.github.com/repos/test-org/test-repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/test-org/test-repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/test-org/test-repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/test-org/test-repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/test-org/test-repo/statuses/{sha}","languages_url":"https://api.github.com/repos/test-org/test-repo/languages","stargazers_url":"https://api.github.com/repos/test-org/test-repo/stargazers","contributors_url":"https://api.github.com/repos/test-org/test-repo/contributors","subscribers_url":"https://api.github.com/repos/test-org/test-repo/subscribers","subscription_url":"https://api.github.com/repos/test-org/test-repo/subscription","commits_url":"https://api.github.com/repos/test-org/test-repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/test-org/test-repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/test-org/test-repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/test-org/test-repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/test-org/test-repo/contents/{+path}","compare_url":"https://api.github.com/repos/test-org/test-repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/test-org/test-repo/merges","archive_url":"https://api.github.com/repos/test-org/test-repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/test-org/test-repo/downloads","issues_url":"https://api.github.com/repos/test-org/test-repo/issues{/number}","pulls_url":"https://api.github.com/repos/test-org/test-repo/pulls{/number}","milestones_url":"https://api.github.com/repos/test-org/test-repo/milestones{/number}","notifications_url":"https://api.github.com/repos/test-org/test-repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/test-org/test-repo/labels{/name}","releases_url":"https://api.github.com/repos/test-org/test-repo/releases{/id}","deployments_url":"https://api.github.com/repos/test-org/test-repo/deployments","created_at":"2024-04-16T15:01:55Z","updated_at":"2024-05-06T19:34:50Z","pushed_at":"2024-05-06T19:34:47Z","git_url":"git://github.com/test-org/test-repo.git","ssh_url":"git@github.com:test-org/test-repo.git","clone_url":"https://github.com/test-org/test-repo.git","svn_url":"https://github.com/test-org/test-repo","homepage":null,"size":151,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":2,"license":null,"allow_forking":false,"is_template":false,"web_commit_signoff_required":false,"topics":[],"visibility":"private","forks":0,"open_issues":2,"watchers":0,"default_branch":"main","permissions":{"admin":true,"maintain":true,"push":true,"triage":true,"pull":true},"temp_clone_token":"ABL6CD5QFVJTVVBLN6QCDWTGHE3AW","allow_squash_merge":true,"allow_merge_commit":false,"allow_rebase_merge":false,"allow_auto_merge":false,"delete_branch_on_merge":false,"allow_update_branch":false,"use_squash_pr_title_as_default":false,"squash_merge_commit_message":"COMMIT_MESSAGES","squash_merge_commit_title":"COMMIT_OR_PR_TITLE","merge_commit_message":"PR_TITLE","merge_commit_title":"MERGE_MESSAGE","custom_properties":{},"organization":{"login":"test-org","id":127791185,"node_id":"O_kgDOB53wUQ","avatar_url":"https://avatars.githubusercontent.com/u/127791185?v=4","gravatar_id":"","url":"https://api.github.com/users/test-org","html_url":"https://github.com/test-org","followers_url":"https://api.github.com/users/test-org/followers","following_url":"https://api.github.com/users/test-org/following{/other_user}","gists_url":"https://api.github.com/users/test-org/gists{/gist_id}","starred_url":"https://api.github.com/users/test-org/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/test-org/subscriptions","organizations_url":"https://api.github.com/users/test-org/orgs","repos_url":"https://api.github.com/users/test-org/repos","events_url":"https://api.github.com/users/test-org/events{/privacy}","received_events_url":"https://api.github.com/users/test-org/received_events","type":"Organization","site_admin":false},"security_and_analysis":{"advanced_security":{"status":"enabled"},"secret_scanning":{"status":"enabled"},"secret_scanning_push_protection":{"status":"enabled"},"dependabot_security_updates":{"status":"enabled"},"secret_scanning_validity_checks":{"status":"enabled"}},"network_count":0,"subscribers_count":1} + +https +GET +api.github.com +None +/repos/test-org/test-repo/actions/workflows/workflow-with-params.yaml +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'} +None +200 +[('Server', 'GitHub.com'), ('Date', 'Mon, 06 May 2024 19:51:59 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding, Accept, X-Requested-With'), ('ETag', 'W/"5cc7d3a55ef0d203fad9ca46895cac5068a14e366a07923cc382cbdd6aca9fe9"'), ('X-OAuth-Scopes', 'repo, workflow'), ('X-Accepted-OAuth-Scopes', ''), ('github-authentication-token-expiration', '2024-05-13 19:47:28 UTC'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '3536'), ('X-RateLimit-Reset', '1715026915'), ('X-RateLimit-Used', '1464'), ('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'), ('X-GitHub-Request-Id', 'E3A6:67ECE:12E64E4:1EEF523:663934DF')] +{"id":96985305,"node_id":"W_kwDOLu-pm84Fx-DZ","name":"Release","path":".github/workflows/workflow-with-params.yaml","state":"active","created_at":"2024-05-06T15:34:47.000-04:00","updated_at":"2024-05-06T15:34:47.000-04:00","url":"https://api.github.com/repos/test-org/test-repo/actions/workflows/96985305","html_url":"https://github.com/test-org/test-repo/blob/main/.github/workflows/workflow-with-params.yaml","badge_url":"https://github.com/test-org/test-repo/workflows/Release/badge.svg"} + +https +POST +api.github.com +None +/repos/test-org/test-repo/actions/workflows/96985305/dispatches +{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python', 'Content-Type': 'application/json'} +{"ref": "main", "inputs": {}} +422 +[('Server', 'GitHub.com'), ('Date', 'Mon, 06 May 2024 19:51:59 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Content-Length', '165'), ('X-OAuth-Scopes', 'repo, workflow'), ('X-Accepted-OAuth-Scopes', ''), ('github-authentication-token-expiration', '2024-05-13 19:47:28 UTC'), ('X-GitHub-Media-Type', 'github.v3; format=json'), ('x-github-api-version-selected', '2022-11-28'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '3535'), ('X-RateLimit-Reset', '1715026915'), ('X-RateLimit-Used', '1465'), ('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'"), ('Vary', 'Accept-Encoding, Accept, X-Requested-With'), ('X-GitHub-Request-Id', 'E3A7:3C06C6:2683B81:4131A81:663934DF')] +{"message":"Required input 'mandatory-parameter' not provided","documentation_url":"https://docs.github.com/rest/actions/workflows#create-a-workflow-dispatch-event"} diff --git a/tests/Workflow.py b/tests/Workflow.py index 8378ee105..ae9f39a05 100644 --- a/tests/Workflow.py +++ b/tests/Workflow.py @@ -37,6 +37,8 @@ from datetime import datetime, timezone +from github import GithubException + from . import Framework @@ -129,3 +131,10 @@ def testCreateDispatchWithString(self): def testCreateDispatchForNonTriggerEnabled(self): workflow = self.g.get_repo("wrecker/PyGithub").get_workflow("check.yml") self.assertFalse(workflow.create_dispatch("main")) + + def testCreateDispatchException(self): + workflow = self.g.get_repo("test-org/test-repo").get_workflow("workflow-with-params.yaml") + with self.assertRaises(GithubException) as raisedexp: + workflow.create_dispatch_throw("main") + self.assertEqual(raisedexp.exception.status, 422) + self.assertEqual(raisedexp.exception.data["message"], "Required input 'mandatory-parameter' not provided")