ghapi 2.0.5__tar.gz → 2.0.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {ghapi-2.0.5/ghapi.egg-info → ghapi-2.0.6}/PKG-INFO +3 -2
  2. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/__init__.py +1 -1
  3. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/_modidx.py +19 -1
  4. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/core.py +133 -4
  5. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/gh_spec.py +375 -37
  6. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/skill.py +8 -1
  7. {ghapi-2.0.5 → ghapi-2.0.6/ghapi.egg-info}/PKG-INFO +3 -2
  8. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi.egg-info/requires.txt +4 -1
  9. {ghapi-2.0.5 → ghapi-2.0.6}/pyproject.toml +1 -1
  10. {ghapi-2.0.5 → ghapi-2.0.6}/CONTRIBUTING.md +0 -0
  11. {ghapi-2.0.5 → ghapi-2.0.6}/LICENSE +0 -0
  12. {ghapi-2.0.5 → ghapi-2.0.6}/MANIFEST.in +0 -0
  13. {ghapi-2.0.5 → ghapi-2.0.6}/README.md +0 -0
  14. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/actions.py +0 -0
  15. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/all.py +0 -0
  16. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/auth.py +0 -0
  17. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/build_lib.py +0 -0
  18. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/cli.py +0 -0
  19. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/event.py +0 -0
  20. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/graphql.py +0 -0
  21. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/page.py +0 -0
  22. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/py.typed +0 -0
  23. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi/templates.py +0 -0
  24. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi.egg-info/SOURCES.txt +0 -0
  25. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi.egg-info/dependency_links.txt +0 -0
  26. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi.egg-info/entry_points.txt +0 -0
  27. {ghapi-2.0.5 → ghapi-2.0.6}/ghapi.egg-info/top_level.txt +0 -0
  28. {ghapi-2.0.5 → ghapi-2.0.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ghapi
3
- Version: 2.0.5
3
+ Version: 2.0.6
4
4
  Summary: A python client for the GitHub API
5
5
  Author-email: Jeremy Howard <info@fast.ai>
6
6
  License: Apache-2.0
@@ -16,7 +16,8 @@ Requires-Python: >=3.10
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: fastcore>=2.1.16
19
- Requires-Dist: fastspec>=0.1.2
19
+ Requires-Dist: fastspec>=0.1.5
20
+ Requires-Dist: tomli; python_version < "3.11"
20
21
  Provides-Extra: dev
21
22
  Requires-Dist: fastgit; extra == "dev"
22
23
  Requires-Dist: matplotlib; extra == "dev"
@@ -4,4 +4,4 @@ Modules:
4
4
 
5
5
  - `ghapi.skill`: GitHub REST API access via `GhApi`, plus local git operations via `fastgit.Git`. Use this for day-to-day GitHub work: reading/creating issues and PRs, checking CI status, managing releases/branches/gists, and repo-local git operations -- all from Python, no shelling out to `gh`/`git` needed."""
6
6
 
7
- __version__ = "2.0.5"
7
+ __version__ = "2.0.6"
@@ -42,7 +42,11 @@ d = { 'settings': { 'branch': 'main',
42
42
  'ghapi.cli.ghapi': ('cli.html#ghapi', 'ghapi/cli.py'),
43
43
  'ghapi.cli.ghpath': ('cli.html#ghpath', 'ghapi/cli.py'),
44
44
  'ghapi.cli.ghraw': ('cli.html#ghraw', 'ghapi/cli.py')},
45
- 'ghapi.core': { 'ghapi.core.GhApi': ('core.html#ghapi', 'ghapi/core.py'),
45
+ 'ghapi.core': { 'ghapi.core.CheckRun': ('core.html#checkrun', 'ghapi/core.py'),
46
+ 'ghapi.core.CheckRun.__repr__': ('core.html#checkrun.__repr__', 'ghapi/core.py'),
47
+ 'ghapi.core.CommitStatus': ('core.html#commitstatus', 'ghapi/core.py'),
48
+ 'ghapi.core.CommitStatus.__repr__': ('core.html#commitstatus.__repr__', 'ghapi/core.py'),
49
+ 'ghapi.core.GhApi': ('core.html#ghapi', 'ghapi/core.py'),
46
50
  'ghapi.core.GhApi.__call__': ('core.html#ghapi.__call__', 'ghapi/core.py'),
47
51
  'ghapi.core.GhApi.__getitem__': ('core.html#ghapi.__getitem__', 'ghapi/core.py'),
48
52
  'ghapi.core.GhApi.__init__': ('core.html#ghapi.__init__', 'ghapi/core.py'),
@@ -59,6 +63,8 @@ d = { 'settings': { 'branch': 'main',
59
63
  'ghapi.core.GhApi.recv_hdrs': ('core.html#ghapi.recv_hdrs', 'ghapi/core.py'),
60
64
  'ghapi.core.GhApi.update_gist': ('core.html#ghapi.update_gist', 'ghapi/core.py'),
61
65
  'ghapi.core.GhApi.upload_file': ('core.html#ghapi.upload_file', 'ghapi/core.py'),
66
+ 'ghapi.core.GhRows': ('core.html#ghrows', 'ghapi/core.py'),
67
+ 'ghapi.core.GhRows.__repr__': ('core.html#ghrows.__repr__', 'ghapi/core.py'),
62
68
  'ghapi.core.GhSyncTransport': ('core.html#ghsynctransport', 'ghapi/core.py'),
63
69
  'ghapi.core.GhSyncTransport.request': ('core.html#ghsynctransport.request', 'ghapi/core.py'),
64
70
  'ghapi.core.GhTransport': ('core.html#ghtransport', 'ghapi/core.py'),
@@ -72,14 +78,19 @@ d = { 'settings': { 'branch': 'main',
72
78
  'ghapi.core._IssueInfo': ('core.html#_issueinfo', 'ghapi/core.py'),
73
79
  'ghapi.core._IssueInfo._repr_markdown_': ('core.html#_issueinfo._repr_markdown_', 'ghapi/core.py'),
74
80
  'ghapi.core._LiveDefaults': ('core.html#_livedefaults', 'ghapi/core.py'),
81
+ 'ghapi.core._LiveDefaults.__contains__': ('core.html#_livedefaults.__contains__', 'ghapi/core.py'),
82
+ 'ghapi.core._LiveDefaults.get': ('core.html#_livedefaults.get', 'ghapi/core.py'),
75
83
  'ghapi.core._LiveDefaults.items': ('core.html#_livedefaults.items', 'ghapi/core.py'),
84
+ 'ghapi.core._dur': ('core.html#_dur', 'ghapi/core.py'),
76
85
  'ghapi.core._filter_diff': ('core.html#_filter_diff', 'ghapi/core.py'),
77
86
  'ghapi.core._find_matches': ('core.html#_find_matches', 'ghapi/core.py'),
78
87
  'ghapi.core._fmt_replies': ('core.html#_fmt_replies', 'ghapi/core.py'),
79
88
  'ghapi.core._include': ('core.html#_include', 'ghapi/core.py'),
89
+ 'ghapi.core._listed': ('core.html#_listed', 'ghapi/core.py'),
80
90
  'ghapi.core._parse_tmpl': ('core.html#_parse_tmpl', 'ghapi/core.py'),
81
91
  'ghapi.core._reduce_ctx': ('core.html#_reduce_ctx', 'ghapi/core.py'),
82
92
  'ghapi.core._run_subp': ('core.html#_run_subp', 'ghapi/core.py'),
93
+ 'ghapi.core._transdeps': ('core.html#_transdeps', 'ghapi/core.py'),
83
94
  'ghapi.core.call_gh': ('core.html#call_gh', 'ghapi/core.py'),
84
95
  'ghapi.core.check_status': ('core.html#check_status', 'ghapi/core.py'),
85
96
  'ghapi.core.commit_tree': ('core.html#commit_tree', 'ghapi/core.py'),
@@ -92,7 +103,13 @@ d = { 'settings': { 'branch': 'main',
92
103
  'ghapi.core.delete_file': ('core.html#delete_file', 'ghapi/core.py'),
93
104
  'ghapi.core.delete_release': ('core.html#delete_release', 'ghapi/core.py'),
94
105
  'ghapi.core.delete_tag': ('core.html#delete_tag', 'ghapi/core.py'),
106
+ 'ghapi.core.dep_closure': ('core.html#dep_closure', 'ghapi/core.py'),
107
+ 'ghapi.core.dep_dependents': ('core.html#dep_dependents', 'ghapi/core.py'),
108
+ 'ghapi.core.dep_graph': ('core.html#dep_graph', 'ghapi/core.py'),
109
+ 'ghapi.core.dep_key': ('core.html#dep_key', 'ghapi/core.py'),
110
+ 'ghapi.core.dep_order': ('core.html#dep_order', 'ghapi/core.py'),
95
111
  'ghapi.core.enable_pages': ('core.html#enable_pages', 'ghapi/core.py'),
112
+ 'ghapi.core.failed_step_log': ('core.html#failed_step_log', 'ghapi/core.py'),
96
113
  'ghapi.core.get_branch': ('core.html#get_branch', 'ghapi/core.py'),
97
114
  'ghapi.core.get_content': ('core.html#get_content', 'ghapi/core.py'),
98
115
  'ghapi.core.gh2date': ('core.html#gh2date', 'ghapi/core.py'),
@@ -102,6 +119,7 @@ d = { 'settings': { 'branch': 'main',
102
119
  'ghapi.core.list_branches': ('core.html#list_branches', 'ghapi/core.py'),
103
120
  'ghapi.core.list_files': ('core.html#list_files', 'ghapi/core.py'),
104
121
  'ghapi.core.list_tags': ('core.html#list_tags', 'ghapi/core.py'),
122
+ 'ghapi.core.local_dep_graph': ('core.html#local_dep_graph', 'ghapi/core.py'),
105
123
  'ghapi.core.pr_file_diff': ('core.html#pr_file_diff', 'ghapi/core.py'),
106
124
  'ghapi.core.pr_status': ('core.html#pr_status', 'ghapi/core.py'),
107
125
  'ghapi.core.print_summary': ('core.html#print_summary', 'ghapi/core.py'),
@@ -9,8 +9,9 @@ __all__ = ['GH_HOST', 'pspec', 'img_md_pat', 'EMPTY_TREE_SHA', 'GhTransport', 'G
9
9
  'GhApi', 'call_gh', 'date2gh', 'gh2date', 'delete_release', 'create_release', 'list_tags', 'list_branches',
10
10
  'create_branch_empty', 'delete_tag', 'delete_branch', 'get_branch', 'commit_tree', 'list_files',
11
11
  'get_content', 'create_or_update_file', 'create_file', 'delete_file', 'update_contents', 'enable_pages',
12
- 'read_issue', 'read_pr', 'pr_file_diff', 'issue_template', 'issue_body', 'check_status', 'pr_status',
13
- 'APIError']
12
+ 'read_issue', 'read_pr', 'pr_file_diff', 'issue_template', 'issue_body', 'CheckRun', 'CommitStatus',
13
+ 'GhRows', 'check_status', 'pr_status', 'failed_step_log', 'dep_key', 'local_dep_graph', 'dep_closure',
14
+ 'dep_order', 'dep_dependents', 'dep_graph', 'APIError']
14
15
 
15
16
  # %% ../nbs/00_core.ipynb #5b5cba7b
16
17
  from contextvars import ContextVar
@@ -27,6 +28,10 @@ from collections import Counter
27
28
  from urllib.parse import quote
28
29
  from datetime import datetime
29
30
  import os, shutil, tempfile, subprocess, fnmatch, html
31
+ import asyncio
32
+
33
+ try: import tomllib
34
+ except ModuleNotFoundError: import tomli as tomllib
30
35
 
31
36
  # %% ../nbs/00_core.ipynb #ed04302a
32
37
  _all_ = ['APIError']
@@ -97,6 +102,8 @@ _gh_override = ContextVar('_gh_override', default={})
97
102
  class _LiveDefaults(dict):
98
103
  "Endpoint defaults, superseded at call time by any active `gh_patch` override"
99
104
  def items(self): return {**self, **_gh_override.get()}.items()
105
+ def __contains__(self, k): return dict.__contains__(self, k) or k in _gh_override.get()
106
+ def get(self, k, default=None): return _gh_override.get().get(k, dict.get(self, k, default))
100
107
 
101
108
  def gh_patch(fn):
102
109
  "`patch` `fn` into `GhApi`, adding `owner`/`repo` params that override the client defaults for this call and its internal calls"
@@ -532,6 +539,22 @@ def issue_body(tmpl, sections):
532
539
  return '\n\n'.join(res)
533
540
 
534
541
  # %% ../nbs/00_core.ipynb #97730eae
542
+ def _dur(r):
543
+ if not (r.get('started_at') and r.get('completed_at')): return ''
544
+ t = lambda s: datetime.fromisoformat(s.replace('Z', '+00:00'))
545
+ secs = int((t(r.completed_at) - t(r.started_at)).total_seconds())
546
+ return f' ({secs//60}m{secs%60:02d}s)' if secs >= 60 else f' ({secs}s)'
547
+
548
+ class CheckRun(AttrDict):
549
+ def __repr__(self): return f'{self.id} {self.name}: {self.conclusion or self.status}{_dur(self)}'
550
+
551
+ class CommitStatus(AttrDict):
552
+ def __repr__(self): return f'{self.context}: {self.state}'
553
+
554
+ class GhRows(L):
555
+ "Result rows whose bare display is one actionable line each"
556
+ def __repr__(self): return '\n'.join(map(repr, self))
557
+
535
558
  class _CheckStatus(AttrDict):
536
559
  def _repr_markdown_(self):
537
560
  runs = self.check_runs
@@ -539,7 +562,7 @@ class _CheckStatus(AttrDict):
539
562
  if any(r.status!='completed' for r in runs): verdict = 'pending'
540
563
  elif all(r.conclusion in ('success','neutral','skipped') for r in runs): verdict = 'success'
541
564
  else: verdict = 'failure'
542
- return '\n'.join([f'**{verdict}**', ''] + [f"- {r.name}: {r.conclusion or r.status}" for r in runs])
565
+ return '\n'.join([f'**{verdict}**', ''] + [f'- {r!r}' for r in runs+self.statuses])
543
566
  __repr__ = _repr_markdown_
544
567
 
545
568
  @gh_patch
@@ -547,9 +570,115 @@ async def check_status(self:GhApi, ref:str):
547
570
  "Combined commit status and check-run results for `ref` (a SHA, branch, or tag)"
548
571
  combined = await self.repos.get_combined_status_for_ref(ref)
549
572
  checks = await self.checks.list_for_ref(ref)
550
- return _CheckStatus(dict2obj(dict(state=combined.state, statuses=combined.statuses, check_runs=checks.check_runs)))
573
+ return _CheckStatus(dict(state=combined.state, statuses=GhRows(CommitStatus(o) for o in combined.statuses),
574
+ check_runs=GhRows(CheckRun(o) for o in checks.check_runs)))
551
575
 
552
576
  @gh_patch
553
577
  async def pr_status(self:GhApi, pull_number:int):
554
578
  "Combined status and check-run results for a PR's head commit"
555
579
  return await self.check_status((await self.pulls.get(pull_number)).head.sha)
580
+
581
+ # %% ../nbs/00_core.ipynb #569864f5
582
+ @gh_patch
583
+ async def failed_step_log(self:GhApi, job_id:int):
584
+ "Log sections of `job_id`'s failed steps, each headed by its step name"
585
+ job = await self.actions.get_job_for_workflow_run(job_id=job_id)
586
+ log = await self.actions.download_job_logs_for_workflow_run(job_id=job_id)
587
+ res = []
588
+ for s in job.steps:
589
+ if s.conclusion!='failure': continue
590
+ seg = [l[29:] for l in log.splitlines() if s.started_at[:-1] <= l[:19] <= s.completed_at[:-1]]
591
+ errs = [i for i,l in enumerate(seg) if l.startswith(r'##[error]')]
592
+ if errs: seg = seg[:errs[-1]+1]
593
+ res.append(f'# {s.name}\n' + '\n'.join(seg))
594
+ return '\n\n'.join(res)
595
+
596
+ # %% ../nbs/00_core.ipynb #751c4e54
597
+ def dep_key(dep):
598
+ "Package key for PEP 508 dependency spec `dep`"
599
+ dep = dep.split(";", 1)[0].strip()
600
+ dep = re.split(r"[\s<>=!~]", dep, maxsplit=1)[0]
601
+ return dep.split("[", 1)[0].casefold()
602
+
603
+ # %% ../nbs/00_core.ipynb #16db589f
604
+ def local_dep_graph(root):
605
+ "Dependency graph `{package: (repo dir, [dep packages])}` for checkouts under `root`"
606
+ res = {}
607
+ for p in sorted(Path(root).expanduser().glob("*/pyproject.toml")):
608
+ proj = tomllib.loads(p.read_text(encoding="utf-8")).get("project", {})
609
+ if not (name := proj.get("name")): continue
610
+ res[name.casefold()] = (p.parent.name, [dep_key(d) for d in proj.get("dependencies", [])])
611
+ return res
612
+
613
+ # %% ../nbs/00_core.ipynb #a7c0113f
614
+ def dep_closure(name, graph):
615
+ "Repo names for `name` and its transitive dependencies within `graph`"
616
+ seen, todo = set(), [name.casefold()]
617
+ while todo:
618
+ if (n := todo.pop()) in seen or n not in graph: continue
619
+ seen.add(n)
620
+ todo += graph[n][1]
621
+ return {graph[n][0] for n in seen}
622
+
623
+ # %% ../nbs/00_core.ipynb #03e6a85e
624
+ def _transdeps(pkg, graph):
625
+ seen, todo = set(), list(graph.get(pkg, ('', []))[1])
626
+ while todo:
627
+ if (n := todo.pop()) in seen or n not in graph: continue
628
+ seen.add(n)
629
+ todo += graph[n][1]
630
+ return seen
631
+
632
+ def _listed(graph, names):
633
+ r2p = {r.casefold(): p for p, (r, _) in graph.items()}
634
+ if names is None: names = sorted(graph[p][0] for p in graph)
635
+ pkgs = {n: r2p.get(k := n.rpartition("/")[2].casefold(), k) for n in names}
636
+ td = {n: _transdeps(p, graph) & set(pkgs.values()) for n, p in pkgs.items()}
637
+ return names, pkgs, td
638
+
639
+ def dep_order(graph, names=None):
640
+ "Order `names` (repo, package, or `owner/name` specs; default all of `graph`) dependency-first, ties most-depended-on first"
641
+ names, pkgs, td = _listed(graph, names)
642
+ ndeps = {n: sum(pkgs[n] in d for d in td.values()) for n in names}
643
+ order, done = [], set()
644
+ while len(order) < len(names):
645
+ ready = sorted((n for n in names if n not in order and td[n] <= done), key=lambda n: -ndeps[n])
646
+ if not ready: raise ValueError(f"dependency cycle among {sorted(set(names) - set(order))}")
647
+ order += ready
648
+ done |= {pkgs[n] for n in ready}
649
+ return order
650
+
651
+ # %% ../nbs/00_core.ipynb #cf2ccf6d
652
+ def dep_dependents(graph, names=None):
653
+ "For each of `names` (default all of `graph`), the listed names that transitively depend on it, most-depended-on first"
654
+ names, pkgs, td = _listed(graph, names)
655
+ res = {n: [m for m in names if pkgs[n] in td[m]] for n in names}
656
+ return dict(sorted(res.items(), key=lambda kv: -len(kv[1])))
657
+
658
+ # %% ../nbs/00_core.ipynb #64709ee0
659
+ @gh_patch
660
+ async def dep_graph(self:GhApi, *repos, graph=None):
661
+ "Dependency graph for `repos` and their transitive same-owner deps, fetched from GitHub pyprojects; seed with `graph` to skip fetching known members"
662
+ graph = dict(graph or {})
663
+ seen = {r.casefold() for r, _ in graph.values()}
664
+ async def _fetch(spec):
665
+ owner, _, name = spec.rpartition("/")
666
+ try: res = await self.repos.get_content(repo=name, path="pyproject.toml", **(dict(owner=owner) if owner else {}))
667
+ except APIError: return spec, None
668
+ return spec, tomllib.loads(base64.b64decode(res.content).decode()).get("project", {})
669
+ todo, listed = [r for r in repos if r.rpartition("/")[2].casefold() not in seen], True
670
+ while todo:
671
+ todo = list(dict.fromkeys(todo))
672
+ seen |= {t.rpartition("/")[2].casefold() for t in todo}
673
+ results = await asyncio.gather(*map(_fetch, todo))
674
+ todo = []
675
+ for spec, proj in results:
676
+ owner, _, name = spec.rpartition("/")
677
+ if proj is None:
678
+ if listed: graph[name.casefold()] = (name, [])
679
+ continue
680
+ deps = [dep_key(d) for d in proj.get("dependencies", [])]
681
+ graph[(proj.get("name") or name).casefold()] = (name, deps)
682
+ todo += [f"{owner}/{d}" if owner else d for d in deps if d not in graph and d not in seen]
683
+ listed = False
684
+ return graph
@@ -67,15 +67,16 @@ spec = {'base_url': 'https://api.github.com',
67
67
  'verb': 'POST',
68
68
  'summary': 'Start a task',
69
69
  'route_params': ['owner', 'repo'],
70
- 'body_params': ['prompt', 'model', 'create_pull_request', 'base_ref', 'head_ref'],
70
+ 'body_params': ['prompt', 'model', 'custom_agent', 'create_pull_request', 'base_ref', 'head_ref'],
71
71
  'request_content_type': 'application/json',
72
72
  'required_params': ['owner', 'prompt', 'repo'],
73
- 'param_types': {'owner': 'str', 'repo': 'str', 'prompt': 'str', 'model': 'str', 'create_pull_request': 'bool', 'base_ref': 'str', 'head_ref': 'str'},
73
+ 'param_types': {'owner': 'str', 'repo': 'str', 'prompt': 'str', 'model': 'str', 'custom_agent': 'str', 'create_pull_request': 'bool', 'base_ref': 'str', 'head_ref': 'str'},
74
74
  'param_defaults': {'create_pull_request': False},
75
75
  'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
76
76
  'repo': 'The name of the repository. The name is not case sensitive.',
77
77
  'prompt': "The user's prompt for the agent",
78
78
  'model': "The model to use for this task. The allowed models may change over time and depend on the user's GitHub Copilot plan and organization policies. Currently supported values: `claude-sonnet-4.6`, `claude-opus-4.6`, `gpt-5.2-codex`, `gpt-5.3-codex`, `gpt-5.4`, `claude-sonnet-4.5`, `claude-opus-4.5`",
79
+ 'custom_agent': "Optional identifier for a custom agent to use for this task. Use the custom agent's filename without the extension - for example, for a `.github/agents/performance-optimizer.agent.md` custom agent, use `performance-optimizer`.",
79
80
  'create_pull_request': 'Whether to create a PR.',
80
81
  'base_ref': 'Base ref for new branch/PR',
81
82
  'head_ref': 'Head ref for existing branch/PR. If provided with `base_ref`, the agent looks up open PR context for `head_ref` targeting `base_ref` and commits to `head_ref` instead of creating a new branch.'},
@@ -216,7 +217,7 @@ spec = {'base_url': 'https://api.github.com',
216
217
  'request_content_type': 'application/json',
217
218
  'required_params': ['installation_id'],
218
219
  'param_types': {'installation_id': 'int', 'repositories': 'list', 'repository_ids': 'list', 'permissions': 'dict'},
219
- 'param_docs': {'installation_id': 'The unique identifier of the installation.', 'repositories': 'List of repository names that the token should have access to', 'repository_ids': 'List of repository IDs that the token should have access to', 'permissions': 'The permissions granted to the user access token.'},
220
+ 'param_docs': {'installation_id': 'The unique identifier of the installation.', 'repositories': 'List of repository names that the token should have access to', 'repository_ids': 'List of repository IDs that the token should have access to', 'permissions': 'The permissions granted to the fine-grained access token.'},
220
221
  'docs_url': 'https://docs.github.com/rest/apps/apps#create-an-installation-access-token-for-an-app'},
221
222
  {'group': 'apps',
222
223
  'name': 'suspend_installation',
@@ -302,24 +303,24 @@ spec = {'base_url': 'https://api.github.com',
302
303
  'target_id': 'The ID of the user or organization to scope the user access token to. **Required** unless `target` is specified.',
303
304
  'repositories': 'The list of repository names to scope the user access token to. `repositories` may not be specified if `repository_ids` is specified.',
304
305
  'repository_ids': 'The list of repository IDs to scope the user access token to. `repository_ids` may not be specified if `repositories` is specified.',
305
- 'permissions': 'The permissions granted to the user access token.'},
306
+ 'permissions': 'The permissions granted to the fine-grained access token.'},
306
307
  'docs_url': 'https://docs.github.com/rest/apps/apps#create-a-scoped-access-token'},
307
308
  {'group': 'apps', 'name': 'get_by_slug', 'path': '/apps/{app_slug}', 'verb': 'GET', 'summary': 'Get an app', 'route_params': ['app_slug'], 'required_params': ['app_slug'], 'param_types': {'app_slug': 'str'}, 'docs_url': 'https://docs.github.com/rest/apps/apps#get-an-app'},
308
309
  {'group': 'classroom',
309
310
  'name': 'get_an_assignment',
310
311
  'path': '/assignments/{assignment_id}',
311
312
  'verb': 'GET',
312
- 'summary': 'Get an assignment',
313
+ 'summary': 'Closing down - Get an assignment',
313
314
  'route_params': ['assignment_id'],
314
315
  'required_params': ['assignment_id'],
315
316
  'param_types': {'assignment_id': 'int'},
316
317
  'param_docs': {'assignment_id': 'The unique identifier of the classroom assignment.'},
317
- 'docs_url': 'https://docs.github.com/rest/classroom/classroom#get-an-assignment'},
318
+ 'docs_url': 'https://docs.github.com/rest/classroom/classroom#closing-down---get-an-assignment'},
318
319
  {'group': 'classroom',
319
320
  'name': 'list_accepted_assignments_for_an_assignment',
320
321
  'path': '/assignments/{assignment_id}/accepted_assignments',
321
322
  'verb': 'GET',
322
- 'summary': 'List accepted assignments for an assignment',
323
+ 'summary': 'Closing down - List accepted assignments for an assignment',
323
324
  'route_params': ['assignment_id'],
324
325
  'query_params': ['page', 'per_page'],
325
326
  'required_params': ['assignment_id'],
@@ -328,43 +329,43 @@ spec = {'base_url': 'https://api.github.com',
328
329
  'param_docs': {'assignment_id': 'The unique identifier of the classroom assignment.',
329
330
  'page': 'The page number of the results to fetch. For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."',
330
331
  'per_page': 'The number of results per page (max 100). For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."'},
331
- 'docs_url': 'https://docs.github.com/rest/classroom/classroom#list-accepted-assignments-for-an-assignment'},
332
+ 'docs_url': 'https://docs.github.com/rest/classroom/classroom#closing-down---list-accepted-assignments-for-an-assignment'},
332
333
  {'group': 'classroom',
333
334
  'name': 'get_assignment_grades',
334
335
  'path': '/assignments/{assignment_id}/grades',
335
336
  'verb': 'GET',
336
- 'summary': 'Get assignment grades',
337
+ 'summary': 'Closing down - Get assignment grades',
337
338
  'route_params': ['assignment_id'],
338
339
  'required_params': ['assignment_id'],
339
340
  'param_types': {'assignment_id': 'int'},
340
341
  'param_docs': {'assignment_id': 'The unique identifier of the classroom assignment.'},
341
- 'docs_url': 'https://docs.github.com/rest/classroom/classroom#get-assignment-grades'},
342
+ 'docs_url': 'https://docs.github.com/rest/classroom/classroom#closing-down---get-assignment-grades'},
342
343
  {'group': 'classroom',
343
344
  'name': 'list_classrooms',
344
345
  'path': '/classrooms',
345
346
  'verb': 'GET',
346
- 'summary': 'List classrooms',
347
+ 'summary': 'Closing down - List classrooms',
347
348
  'query_params': ['page', 'per_page'],
348
349
  'param_types': {'page': 'int', 'per_page': 'int'},
349
350
  'param_defaults': {'page': 1, 'per_page': 30},
350
351
  'param_docs': {'page': 'The page number of the results to fetch. For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."',
351
352
  'per_page': 'The number of results per page (max 100). For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."'},
352
- 'docs_url': 'https://docs.github.com/rest/classroom/classroom#list-classrooms'},
353
+ 'docs_url': 'https://docs.github.com/rest/classroom/classroom#closing-down---list-classrooms'},
353
354
  {'group': 'classroom',
354
355
  'name': 'get_a_classroom',
355
356
  'path': '/classrooms/{classroom_id}',
356
357
  'verb': 'GET',
357
- 'summary': 'Get a classroom',
358
+ 'summary': 'Closing down - Get a classroom',
358
359
  'route_params': ['classroom_id'],
359
360
  'required_params': ['classroom_id'],
360
361
  'param_types': {'classroom_id': 'int'},
361
362
  'param_docs': {'classroom_id': 'The unique identifier of the classroom.'},
362
- 'docs_url': 'https://docs.github.com/rest/classroom/classroom#get-a-classroom'},
363
+ 'docs_url': 'https://docs.github.com/rest/classroom/classroom#closing-down---get-a-classroom'},
363
364
  {'group': 'classroom',
364
365
  'name': 'list_assignments_for_a_classroom',
365
366
  'path': '/classrooms/{classroom_id}/assignments',
366
367
  'verb': 'GET',
367
- 'summary': 'List assignments for a classroom',
368
+ 'summary': 'Closing down - List assignments for a classroom',
368
369
  'route_params': ['classroom_id'],
369
370
  'query_params': ['page', 'per_page'],
370
371
  'required_params': ['classroom_id'],
@@ -373,7 +374,7 @@ spec = {'base_url': 'https://api.github.com',
373
374
  'param_docs': {'classroom_id': 'The unique identifier of the classroom.',
374
375
  'page': 'The page number of the results to fetch. For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."',
375
376
  'per_page': 'The number of results per page (max 100). For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."'},
376
- 'docs_url': 'https://docs.github.com/rest/classroom/classroom#list-assignments-for-a-classroom'},
377
+ 'docs_url': 'https://docs.github.com/rest/classroom/classroom#closing-down---list-assignments-for-a-classroom'},
377
378
  {'group': 'codes_of_conduct', 'name': 'get_all_codes_of_conduct', 'path': '/codes_of_conduct', 'verb': 'GET', 'summary': 'Get all codes of conduct', 'docs_url': 'https://docs.github.com/rest/codes-of-conduct/codes-of-conduct#get-all-codes-of-conduct'},
378
379
  {'group': 'codes_of_conduct', 'name': 'get_conduct_code', 'path': '/codes_of_conduct/{key}', 'verb': 'GET', 'summary': 'Get a code of conduct', 'route_params': ['key'], 'required_params': ['key'], 'param_types': {'key': 'str'}, 'docs_url': 'https://docs.github.com/rest/codes-of-conduct/codes-of-conduct#get-a-code-of-conduct'},
379
380
  {'group': 'credentials',
@@ -756,6 +757,17 @@ spec = {'base_url': 'https://api.github.com',
756
757
  'param_types': {'enterprise': 'str'},
757
758
  'param_docs': {'enterprise': 'The slug version of the enterprise name.'},
758
759
  'docs_url': 'https://docs.github.com/rest/copilot/copilot-usage-metrics#get-copilot-enterprise-usage-metrics'},
760
+ {'group': 'copilot',
761
+ 'name': 'copilot_enterprise_repos_one_day_report',
762
+ 'path': '/enterprises/{enterprise}/copilot/metrics/reports/repos-1-day',
763
+ 'verb': 'GET',
764
+ 'summary': 'Get Copilot enterprise repository report for a specific day',
765
+ 'route_params': ['enterprise'],
766
+ 'query_params': ['day'],
767
+ 'required_params': ['day', 'enterprise'],
768
+ 'param_types': {'enterprise': 'str', 'day': 'str'},
769
+ 'param_docs': {'enterprise': 'The slug version of the enterprise name.', 'day': 'The day to request data for, in `YYYY-MM-DD` format.'},
770
+ 'docs_url': 'https://docs.github.com/rest/copilot/copilot-usage-metrics#get-copilot-enterprise-repository-report-for-a-specific-day'},
759
771
  {'group': 'copilot',
760
772
  'name': 'copilot_enterprise_user_teams_one_day_report',
761
773
  'path': '/enterprises/{enterprise}/copilot/metrics/reports/user-teams-1-day',
@@ -3185,18 +3197,42 @@ spec = {'base_url': 'https://api.github.com',
3185
3197
  'verb': 'POST',
3186
3198
  'summary': 'Set cluster deployment records',
3187
3199
  'route_params': ['org', 'cluster'],
3188
- 'body_params': ['logical_environment', 'physical_environment', 'deployments', 'return_records'],
3200
+ 'body_params': ['logical_environment', 'physical_environment', 'deployments', 'partial_success', 'return_records'],
3189
3201
  'request_content_type': 'application/json',
3190
3202
  'required_params': ['cluster', 'deployments', 'logical_environment', 'org'],
3191
- 'param_types': {'org': 'str', 'cluster': 'str', 'logical_environment': 'str', 'physical_environment': 'str', 'deployments': 'list', 'return_records': 'bool'},
3192
- 'param_defaults': {'return_records': True},
3203
+ 'param_types': {'org': 'str', 'cluster': 'str', 'logical_environment': 'str', 'physical_environment': 'str', 'deployments': 'list', 'partial_success': 'bool', 'return_records': 'bool'},
3204
+ 'param_defaults': {'partial_success': False, 'return_records': True},
3193
3205
  'param_docs': {'org': 'The organization name. The name is not case sensitive.',
3194
3206
  'cluster': 'The cluster name.',
3195
3207
  'logical_environment': 'The stage of the deployment.',
3196
3208
  'physical_environment': 'The physical region of the deployment.',
3197
3209
  'deployments': 'The list of deployments to record.',
3210
+ 'partial_success': 'When enabled, deployments associated with repositories the actor can write to are processed while deployments associated with repositories that cannot be resolved or written to by the actor are skipped and reported in the `errors` array. When false (the default), the endpoint returns an error if any targeted '
3211
+ 'repository cannot be resolved, the actor lacks write access, or no matching attestation can be found.',
3198
3212
  'return_records': 'If true, the endpoint will return the set records in the response body'},
3199
3213
  'docs_url': 'https://docs.github.com/rest/orgs/artifact-metadata#set-cluster-deployment-records'},
3214
+ {'group': 'orgs',
3215
+ 'name': 'create_cluster_deployment_records_job',
3216
+ 'path': '/orgs/{org}/artifacts/metadata/deployment-record/cluster/{cluster}/jobs',
3217
+ 'verb': 'POST',
3218
+ 'summary': 'Create a cluster deployment records job',
3219
+ 'route_params': ['org', 'cluster'],
3220
+ 'body_params': ['logical_environment', 'physical_environment', 'deployments'],
3221
+ 'request_content_type': 'application/json',
3222
+ 'required_params': ['cluster', 'deployments', 'logical_environment', 'org'],
3223
+ 'param_types': {'org': 'str', 'cluster': 'str', 'logical_environment': 'str', 'physical_environment': 'str', 'deployments': 'list'},
3224
+ 'param_docs': {'org': 'The organization name. The name is not case sensitive.', 'cluster': 'The cluster name.', 'logical_environment': 'The stage of the deployment.', 'physical_environment': 'The physical region of the deployment.', 'deployments': 'The list of deployments to record.'},
3225
+ 'docs_url': 'https://docs.github.com/rest/orgs/artifact-metadata#create-a-cluster-deployment-records-job'},
3226
+ {'group': 'orgs',
3227
+ 'name': 'get_cluster_deployment_records_job',
3228
+ 'path': '/orgs/{org}/artifacts/metadata/deployment-record/cluster/{cluster}/jobs/{job_id}',
3229
+ 'verb': 'GET',
3230
+ 'summary': 'Get cluster deployment records job status',
3231
+ 'route_params': ['org', 'cluster', 'job_id'],
3232
+ 'required_params': ['cluster', 'job_id', 'org'],
3233
+ 'param_types': {'org': 'str', 'cluster': 'str', 'job_id': 'int'},
3234
+ 'param_docs': {'org': 'The organization name. The name is not case sensitive.', 'cluster': 'The cluster name.', 'job_id': 'The ID of the job.'},
3235
+ 'docs_url': 'https://docs.github.com/rest/orgs/artifact-metadata#get-cluster-deployment-records-job-status'},
3200
3236
  {'group': 'orgs',
3201
3237
  'name': 'create_artifact_storage_record',
3202
3238
  'path': '/orgs/{org}/artifacts/metadata/storage-record',
@@ -4309,6 +4345,17 @@ spec = {'base_url': 'https://api.github.com',
4309
4345
  'param_types': {'org': 'str'},
4310
4346
  'param_docs': {'org': 'The organization name. The name is not case sensitive.'},
4311
4347
  'docs_url': 'https://docs.github.com/rest/copilot/copilot-usage-metrics#get-copilot-organization-usage-metrics'},
4348
+ {'group': 'copilot',
4349
+ 'name': 'copilot_organization_repos_one_day_report',
4350
+ 'path': '/orgs/{org}/copilot/metrics/reports/repos-1-day',
4351
+ 'verb': 'GET',
4352
+ 'summary': 'Get Copilot organization repository report for a specific day',
4353
+ 'route_params': ['org'],
4354
+ 'query_params': ['day'],
4355
+ 'required_params': ['day', 'org'],
4356
+ 'param_types': {'org': 'str', 'day': 'str'},
4357
+ 'param_docs': {'org': 'The organization name. The name is not case sensitive.', 'day': 'The day to request data for, in `YYYY-MM-DD` format.'},
4358
+ 'docs_url': 'https://docs.github.com/rest/copilot/copilot-usage-metrics#get-copilot-organization-repository-report-for-a-specific-day'},
4312
4359
  {'group': 'copilot',
4313
4360
  'name': 'copilot_organization_user_teams_one_day_report',
4314
4361
  'path': '/orgs/{org}/copilot/metrics/reports/user-teams-1-day',
@@ -4921,6 +4968,28 @@ spec = {'base_url': 'https://api.github.com',
4921
4968
  'param_types': {'org': 'str'},
4922
4969
  'param_docs': {'org': 'The organization name. The name is not case sensitive.'},
4923
4970
  'docs_url': 'https://docs.github.com/rest/interactions/orgs#remove-interaction-restrictions-for-an-organization'},
4971
+ {'group': 'interactions',
4972
+ 'name': 'get_pull_request_creation_cap_for_org',
4973
+ 'path': '/orgs/{org}/interaction-limits/pulls/creation-cap',
4974
+ 'verb': 'GET',
4975
+ 'summary': 'Get pull request creation cap for an org',
4976
+ 'route_params': ['org'],
4977
+ 'required_params': ['org'],
4978
+ 'param_types': {'org': 'str'},
4979
+ 'param_docs': {'org': 'The organization name. The name is not case sensitive.'},
4980
+ 'docs_url': 'https://docs.github.com/rest/interactions/orgs#get-pull-request-creation-cap-for-an-org'},
4981
+ {'group': 'interactions',
4982
+ 'name': 'update_pull_request_creation_cap_for_org',
4983
+ 'path': '/orgs/{org}/interaction-limits/pulls/creation-cap',
4984
+ 'verb': 'PATCH',
4985
+ 'summary': 'Update pull request creation cap for an org',
4986
+ 'route_params': ['org'],
4987
+ 'body_params': ['enabled', 'max_open_pull_requests'],
4988
+ 'request_content_type': 'application/json',
4989
+ 'required_params': ['enabled', 'org'],
4990
+ 'param_types': {'org': 'str', 'enabled': 'bool', 'max_open_pull_requests': 'int'},
4991
+ 'param_docs': {'org': 'The organization name. The name is not case sensitive.', 'enabled': 'Whether the pull request creation cap is enabled', 'max_open_pull_requests': 'The maximum number of open pull requests a user can have at one time'},
4992
+ 'docs_url': 'https://docs.github.com/rest/interactions/orgs#update-pull-request-creation-cap-for-an-org'},
4924
4993
  {'group': 'orgs',
4925
4994
  'name': 'list_pending_invitations',
4926
4995
  'path': '/orgs/{org}/invitations',
@@ -6546,6 +6615,70 @@ spec = {'base_url': 'https://api.github.com',
6546
6615
  'owner_email_hash': 'Filters alerts to only those whose attached `owner_email` metadata field matches the provided value. The value must be the lowercase hex-encoded SHA-256 hash of the email address to match (for example, the SHA-256 of `user@example.com`). Only alerts that have an `owner_email` metadata value whose SHA-256 hash '
6547
6616
  'equals this parameter are returned.'},
6548
6617
  'docs_url': 'https://docs.github.com/rest/secret-scanning/secret-scanning#list-secret-scanning-alerts-for-an-organization'},
6618
+ {'group': 'secret_scanning',
6619
+ 'name': 'list_org_custom_patterns',
6620
+ 'path': '/orgs/{org}/secret-scanning/custom-patterns',
6621
+ 'verb': 'GET',
6622
+ 'summary': 'List organization custom patterns',
6623
+ 'route_params': ['org'],
6624
+ 'query_params': ['state', 'push_protection', 'sort', 'direction', 'page', 'per_page'],
6625
+ 'required_params': ['org'],
6626
+ 'param_types': {'org': 'str', 'state': 'str', 'push_protection': 'str', 'sort': 'str', 'direction': 'str', 'page': 'int', 'per_page': 'int'},
6627
+ 'param_defaults': {'sort': 'created', 'direction': 'desc', 'page': 1, 'per_page': 30},
6628
+ 'param_docs': {'org': 'The organization name. The name is not case sensitive.',
6629
+ 'state': 'Filter custom patterns by state. When absent, returns patterns in all states.',
6630
+ 'push_protection': 'Filter custom patterns by whether push protection is enabled. When absent, returns patterns regardless of push protection status.',
6631
+ 'sort': 'The property to sort the results by.',
6632
+ 'direction': 'The direction to sort the results by.',
6633
+ 'page': 'The page number of the results to fetch. For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."',
6634
+ 'per_page': 'The number of results per page (max 100). For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."'},
6635
+ 'docs_url': 'https://docs.github.com/rest/secret-scanning/custom-patterns#list-organization-custom-patterns'},
6636
+ {'group': 'secret_scanning',
6637
+ 'name': 'bulk_create_org_custom_patterns',
6638
+ 'path': '/orgs/{org}/secret-scanning/custom-patterns',
6639
+ 'verb': 'POST',
6640
+ 'summary': 'Bulk create organization custom patterns',
6641
+ 'route_params': ['org'],
6642
+ 'body_params': ['patterns'],
6643
+ 'request_content_type': 'application/json',
6644
+ 'required_params': ['org', 'patterns'],
6645
+ 'param_types': {'org': 'str', 'patterns': 'list'},
6646
+ 'param_docs': {'org': 'The organization name. The name is not case sensitive.', 'patterns': 'The list of custom patterns to create.'},
6647
+ 'docs_url': 'https://docs.github.com/rest/secret-scanning/custom-patterns#bulk-create-organization-custom-patterns'},
6648
+ {'group': 'secret_scanning',
6649
+ 'name': 'bulk_delete_org_custom_patterns',
6650
+ 'path': '/orgs/{org}/secret-scanning/custom-patterns',
6651
+ 'verb': 'DELETE',
6652
+ 'summary': 'Bulk delete organization custom patterns',
6653
+ 'route_params': ['org'],
6654
+ 'body_params': ['patterns', 'post_delete_action'],
6655
+ 'request_content_type': 'application/json',
6656
+ 'required_params': ['org', 'patterns'],
6657
+ 'param_types': {'org': 'str', 'patterns': 'list', 'post_delete_action': 'str'},
6658
+ 'param_defaults': {'post_delete_action': 'delete_alerts'},
6659
+ 'param_docs': {'org': 'The organization name. The name is not case sensitive.',
6660
+ 'patterns': 'The list of custom patterns to delete.',
6661
+ 'post_delete_action': 'What to do with alerts associated with the deleted patterns. `delete_alerts` permanently removes the alerts. `resolve_alerts` resolves the alerts as "pattern deleted". Defaults to `delete_alerts` when not specified.'},
6662
+ 'docs_url': 'https://docs.github.com/rest/secret-scanning/custom-patterns#bulk-delete-organization-custom-patterns'},
6663
+ {'group': 'secret_scanning',
6664
+ 'name': 'update_org_custom_pattern',
6665
+ 'path': '/orgs/{org}/secret-scanning/custom-patterns/{pattern_id}',
6666
+ 'verb': 'PATCH',
6667
+ 'summary': 'Update an organization custom pattern',
6668
+ 'route_params': ['org', 'pattern_id'],
6669
+ 'body_params': ['pattern', 'start_delimiter', 'end_delimiter', 'must_match', 'must_not_match', 'custom_pattern_version'],
6670
+ 'request_content_type': 'application/json',
6671
+ 'required_params': ['custom_pattern_version', 'org', 'pattern_id'],
6672
+ 'param_types': {'org': 'str', 'pattern_id': 'int', 'pattern': 'str', 'start_delimiter': 'str', 'end_delimiter': 'str', 'must_match': 'list', 'must_not_match': 'list', 'custom_pattern_version': 'str'},
6673
+ 'param_docs': {'org': 'The organization name. The name is not case sensitive.',
6674
+ 'pattern_id': 'The ID of the custom pattern.',
6675
+ 'pattern': 'The updated regular expression of the custom pattern.',
6676
+ 'start_delimiter': 'The updated start delimiter regex for the custom pattern.',
6677
+ 'end_delimiter': 'The updated end delimiter regex for the custom pattern.',
6678
+ 'must_match': 'Updated list of regexes that the secret must match.',
6679
+ 'must_not_match': 'Updated list of regexes that the secret must not match.',
6680
+ 'custom_pattern_version': "The version of the entity. This is used to confirm you're updating the current version of the entity and mitigate unintentionally overriding someone else's update."},
6681
+ 'docs_url': 'https://docs.github.com/rest/secret-scanning/custom-patterns#update-an-organization-custom-pattern'},
6549
6682
  {'group': 'secret_scanning',
6550
6683
  'name': 'list_org_pattern_configs',
6551
6684
  'path': '/orgs/{org}/secret-scanning/pattern-configurations',
@@ -6796,10 +6929,10 @@ spec = {'base_url': 'https://api.github.com',
6796
6929
  'verb': 'POST',
6797
6930
  'summary': 'Create a team',
6798
6931
  'route_params': ['org'],
6799
- 'body_params': ['name', 'description', 'maintainers', 'repo_names', 'privacy', 'notification_setting', 'permission', 'parent_team_id'],
6932
+ 'body_params': ['name', 'description', 'maintainers', 'repo_names', 'privacy', 'notification_setting', 'permission', 'parent_team_id', 'parent_team_slug'],
6800
6933
  'request_content_type': 'application/json',
6801
6934
  'required_params': ['name', 'org'],
6802
- 'param_types': {'org': 'str', 'name': 'str', 'description': 'str', 'maintainers': 'list', 'repo_names': 'list', 'privacy': 'str', 'notification_setting': 'str', 'permission': 'str', 'parent_team_id': 'int'},
6935
+ 'param_types': {'org': 'str', 'name': 'str', 'description': 'str', 'maintainers': 'list', 'repo_names': 'list', 'privacy': 'str', 'notification_setting': 'str', 'permission': 'str', 'parent_team_id': 'int', 'parent_team_slug': 'str'},
6803
6936
  'param_defaults': {'permission': 'pull'},
6804
6937
  'param_docs': {'org': 'The organization name. The name is not case sensitive.',
6805
6938
  'name': 'The name of the team.',
@@ -6810,7 +6943,8 @@ spec = {'base_url': 'https://api.github.com',
6810
6943
  'organization. Default for child team: `closed`',
6811
6944
  'notification_setting': 'The notification setting the team has chosen. The options are: * `notifications_enabled` - team members receive notifications when the team is @mentioned. * `notifications_disabled` - no one receives notifications. Default: `notifications_enabled`',
6812
6945
  'permission': '**Closing down notice**. The permission that new repositories will be added to the team with when none is specified.',
6813
- 'parent_team_id': 'The ID of a team to set as the parent team.'},
6946
+ 'parent_team_id': 'The ID of a team to set as the parent team.',
6947
+ 'parent_team_slug': 'The slug of a team to set as the parent team. Ignored when `parent_team_id` is also provided.'},
6814
6948
  'docs_url': 'https://docs.github.com/rest/teams/teams#create-a-team'},
6815
6949
  {'group': 'teams',
6816
6950
  'name': 'get_by_name',
@@ -6828,10 +6962,10 @@ spec = {'base_url': 'https://api.github.com',
6828
6962
  'verb': 'PATCH',
6829
6963
  'summary': 'Update a team',
6830
6964
  'route_params': ['org', 'team_slug'],
6831
- 'body_params': ['name', 'description', 'privacy', 'notification_setting', 'permission', 'parent_team_id'],
6965
+ 'body_params': ['name', 'description', 'privacy', 'notification_setting', 'permission', 'parent_team_id', 'parent_team_slug'],
6832
6966
  'request_content_type': 'application/json',
6833
6967
  'required_params': ['org', 'team_slug'],
6834
- 'param_types': {'org': 'str', 'team_slug': 'str', 'name': 'str', 'description': 'str', 'privacy': 'str', 'notification_setting': 'str', 'permission': 'str', 'parent_team_id': 'int'},
6968
+ 'param_types': {'org': 'str', 'team_slug': 'str', 'name': 'str', 'description': 'str', 'privacy': 'str', 'notification_setting': 'str', 'permission': 'str', 'parent_team_id': 'int', 'parent_team_slug': 'str'},
6835
6969
  'param_defaults': {'permission': 'pull'},
6836
6970
  'param_docs': {'org': 'The organization name. The name is not case sensitive.',
6837
6971
  'team_slug': 'The slug of the team name.',
@@ -6841,7 +6975,8 @@ spec = {'base_url': 'https://api.github.com',
6841
6975
  '- visible to all members of this organization. **For a parent or child team:** * `closed` - visible to all members of this organization.',
6842
6976
  'notification_setting': 'The notification setting the team has chosen. Editing teams without specifying this parameter leaves `notification_setting` intact. The options are: * `notifications_enabled` - team members receive notifications when the team is @mentioned. * `notifications_disabled` - no one receives notifications.',
6843
6977
  'permission': '**Closing down notice**. The permission that new repositories will be added to the team with when none is specified.',
6844
- 'parent_team_id': 'The ID of a team to set as the parent team.'},
6978
+ 'parent_team_id': 'The ID of a team to set as the parent team.',
6979
+ 'parent_team_slug': 'The slug of a team to set as the parent team. Ignored when `parent_team_id` is also provided.'},
6845
6980
  'docs_url': 'https://docs.github.com/rest/teams/teams#update-a-team'},
6846
6981
  {'group': 'teams',
6847
6982
  'name': 'delete_in_org',
@@ -9233,16 +9368,17 @@ spec = {'base_url': 'https://api.github.com',
9233
9368
  'verb': 'PATCH',
9234
9369
  'summary': 'Update a code quality setup configuration',
9235
9370
  'route_params': ['owner', 'repo'],
9236
- 'body_params': ['state', 'runner_type', 'runner_label', 'languages'],
9371
+ 'body_params': ['state', 'runner_type', 'runner_label', 'languages', 'ai_findings_option'],
9237
9372
  'request_content_type': 'application/json',
9238
9373
  'required_params': ['owner', 'repo'],
9239
- 'param_types': {'owner': 'str', 'repo': 'str', 'state': 'str', 'runner_type': 'str', 'runner_label': 'str', 'languages': 'list'},
9374
+ 'param_types': {'owner': 'str', 'repo': 'str', 'state': 'str', 'runner_type': 'str', 'runner_label': 'str', 'languages': 'list', 'ai_findings_option': 'str'},
9240
9375
  'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
9241
9376
  'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
9242
9377
  'state': 'The desired state of code quality setup.',
9243
9378
  'runner_type': 'Runner type to be used.',
9244
9379
  'runner_label': 'Runner label to be used if the runner type is labeled.',
9245
- 'languages': 'Languages to be analyzed.'},
9380
+ 'languages': 'Languages to be analyzed.',
9381
+ 'ai_findings_option': 'Whether AI findings run for Code Quality on this repository.'},
9246
9382
  'docs_url': 'https://docs.github.com/rest/code-quality/code-quality#update-a-code-quality-setup-configuration'},
9247
9383
  {'group': 'code_scanning',
9248
9384
  'name': 'list_alerts_for_repo',
@@ -11681,7 +11817,7 @@ spec = {'base_url': 'https://api.github.com',
11681
11817
  'body_params': ['title', 'body', 'assignee', 'state', 'state_reason', 'duplicate_issue_id', 'milestone', 'labels', 'assignees', 'issue_field_values', 'type'],
11682
11818
  'request_content_type': 'application/json',
11683
11819
  'required_params': ['issue_number', 'owner', 'repo'],
11684
- 'param_types': {'owner': 'str', 'repo': 'str', 'issue_number': 'int', 'body': 'str', 'assignee': 'str', 'state': 'str', 'state_reason': 'str', 'duplicate_issue_id': 'int', 'labels': 'list', 'assignees': 'list', 'issue_field_values': 'list', 'type': 'str'},
11820
+ 'param_types': {'owner': 'str', 'repo': 'str', 'issue_number': 'int', 'body': 'str', 'assignee': 'str', 'state': 'str', 'state_reason': 'str', 'duplicate_issue_id': 'int', 'labels': 'list', 'assignees': 'list', 'issue_field_values': 'list'},
11685
11821
  'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
11686
11822
  'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
11687
11823
  'issue_number': 'The number that identifies the issue.',
@@ -11695,7 +11831,7 @@ spec = {'base_url': 'https://api.github.com',
11695
11831
  'labels': 'Labels to associate with this issue. Pass one or more labels to _replace_ the set of labels on this issue. Send an empty array (`[]`) to clear all labels from the issue. Only users with push access can set labels for issues. Without push access to the repository, label changes are silently dropped.',
11696
11832
  'assignees': 'Usernames to assign to this issue. Pass one or more user logins to _replace_ the set of assignees on this issue. Send an empty array (`[]`) to clear all assignees from the issue. Only users with push access can set assignees for new issues. Without push access to the repository, assignee changes are silently dropped.',
11697
11833
  'issue_field_values': 'An array of issue field values to set on this issue. Each field value must include the field ID and the value to set. Only users with push access can set field values for issues',
11698
- 'type': 'The name of the issue type to associate with this issue or use `null` to remove the current issue type. Only users with push access can set the type for issues. Without push access to the repository, type changes are silently dropped.'},
11834
+ 'type': 'The issue type to associate with this issue. Only users with push access can set the type for issues. Without push access to the repository, type changes are silently dropped.'},
11699
11835
  'docs_url': 'https://docs.github.com/rest/issues/issues#update-an-issue'},
11700
11836
  {'group': 'issues',
11701
11837
  'name': 'add_assignees',
@@ -11921,7 +12057,7 @@ spec = {'base_url': 'https://api.github.com',
11921
12057
  'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
11922
12058
  'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
11923
12059
  'issue_number': 'The number that identifies the issue.',
11924
- 'labels': 'The names of the labels to add to the issue\'s existing labels. You can also pass an `array` of labels directly, but GitHub recommends passing an object with the `labels` key. To replace all of the labels for an issue, use "[Set labels for an issue](https://docs.github.com/rest/issues/labels#set-labels-for-an-issue)."'},
12060
+ 'labels': 'The labels to add to the issue\'s existing labels. You can also pass an `array` of labels directly, but GitHub recommends passing an object with the `labels` key. To replace all of the labels for an issue, use "[Set labels for an issue](https://docs.github.com/rest/issues/labels#set-labels-for-an-issue)."'},
11925
12061
  'docs_url': 'https://docs.github.com/rest/issues/labels#add-labels-to-an-issue'},
11926
12062
  {'group': 'issues',
11927
12063
  'name': 'set_labels',
@@ -12093,21 +12229,60 @@ spec = {'base_url': 'https://api.github.com',
12093
12229
  'after_id': 'The id of the sub-issue to be prioritized after (either positional argument after OR before should be specified).',
12094
12230
  'before_id': 'The id of the sub-issue to be prioritized before (either positional argument after OR before should be specified).'},
12095
12231
  'docs_url': 'https://docs.github.com/rest/issues/sub-issues#reprioritize-sub-issue'},
12232
+ {'group': 'issues',
12233
+ 'name': 'list_suggestions',
12234
+ 'path': '/repos/{owner}/{repo}/issues/{issue_number}/suggestions',
12235
+ 'verb': 'GET',
12236
+ 'summary': 'List issue suggestions',
12237
+ 'route_params': ['owner', 'repo', 'issue_number'],
12238
+ 'query_params': ['state', 'action', 'per_page', 'page'],
12239
+ 'required_params': ['issue_number', 'owner', 'repo'],
12240
+ 'param_types': {'owner': 'str', 'repo': 'str', 'issue_number': 'int', 'state': 'str', 'action': 'str', 'per_page': 'int', 'page': 'int'},
12241
+ 'param_defaults': {'state': 'pending', 'per_page': 30, 'page': 1},
12242
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
12243
+ 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
12244
+ 'issue_number': 'The number that identifies the issue.',
12245
+ 'state': 'Filter suggestions by their state.',
12246
+ 'action': 'Filter suggestions by the change they propose.',
12247
+ 'per_page': 'The number of results per page (max 100). For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."',
12248
+ 'page': 'The page number of the results to fetch. For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."'},
12249
+ 'docs_url': 'https://docs.github.com/rest/issues/issues#list-issue-suggestions'},
12250
+ {'group': 'issues',
12251
+ 'name': 'approve_suggestion',
12252
+ 'path': '/repos/{owner}/{repo}/issues/{issue_number}/suggestions/{suggestion_id}/approve',
12253
+ 'verb': 'POST',
12254
+ 'summary': 'Approve an issue suggestion',
12255
+ 'route_params': ['owner', 'repo', 'issue_number', 'suggestion_id'],
12256
+ 'required_params': ['issue_number', 'owner', 'repo', 'suggestion_id'],
12257
+ 'param_types': {'owner': 'str', 'repo': 'str', 'issue_number': 'int', 'suggestion_id': 'int'},
12258
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.', 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.', 'issue_number': 'The number that identifies the issue.', 'suggestion_id': 'The unique identifier of the suggestion.'},
12259
+ 'docs_url': 'https://docs.github.com/rest/issues/issues#approve-an-issue-suggestion'},
12260
+ {'group': 'issues',
12261
+ 'name': 'dismiss_suggestion',
12262
+ 'path': '/repos/{owner}/{repo}/issues/{issue_number}/suggestions/{suggestion_id}/dismiss',
12263
+ 'verb': 'POST',
12264
+ 'summary': 'Dismiss an issue suggestion',
12265
+ 'route_params': ['owner', 'repo', 'issue_number', 'suggestion_id'],
12266
+ 'required_params': ['issue_number', 'owner', 'repo', 'suggestion_id'],
12267
+ 'param_types': {'owner': 'str', 'repo': 'str', 'issue_number': 'int', 'suggestion_id': 'int'},
12268
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.', 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.', 'issue_number': 'The number that identifies the issue.', 'suggestion_id': 'The unique identifier of the suggestion.'},
12269
+ 'docs_url': 'https://docs.github.com/rest/issues/issues#dismiss-an-issue-suggestion'},
12096
12270
  {'group': 'issues',
12097
12271
  'name': 'list_events_for_timeline',
12098
12272
  'path': '/repos/{owner}/{repo}/issues/{issue_number}/timeline',
12099
12273
  'verb': 'GET',
12100
12274
  'summary': 'List timeline events for an issue',
12101
12275
  'route_params': ['owner', 'repo', 'issue_number'],
12102
- 'query_params': ['per_page', 'page'],
12276
+ 'query_params': ['per_page', 'page', 'exclude'],
12103
12277
  'required_params': ['issue_number', 'owner', 'repo'],
12104
- 'param_types': {'owner': 'str', 'repo': 'str', 'issue_number': 'int', 'per_page': 'int', 'page': 'int'},
12278
+ 'param_types': {'owner': 'str', 'repo': 'str', 'issue_number': 'int', 'per_page': 'int', 'page': 'int', 'exclude': 'str'},
12105
12279
  'param_defaults': {'per_page': 30, 'page': 1},
12106
12280
  'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
12107
12281
  'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
12108
12282
  'issue_number': 'The number that identifies the issue.',
12109
12283
  'per_page': 'The number of results per page (max 100). For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."',
12110
- 'page': 'The page number of the results to fetch. For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."'},
12284
+ 'page': 'The page number of the results to fetch. For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."',
12285
+ 'exclude': 'A comma-separated list of timeline event names to exclude from the response.'},
12111
12286
  'docs_url': 'https://docs.github.com/rest/issues/timeline#list-timeline-events-for-an-issue'},
12112
12287
  {'group': 'repos',
12113
12288
  'name': 'list_deploy_keys',
@@ -12912,6 +13087,38 @@ spec = {'base_url': 'https://api.github.com',
12912
13087
  'sha': 'SHA that pull request head must match to allow merge.',
12913
13088
  'merge_method': 'The merge method to use.'},
12914
13089
  'docs_url': 'https://docs.github.com/rest/pulls/pulls#merge-a-pull-request'},
13090
+ {'group': 'pulls',
13091
+ 'name': 'merge_async',
13092
+ 'path': '/repos/{owner}/{repo}/pulls/{pull_number}/merge-async',
13093
+ 'verb': 'PUT',
13094
+ 'summary': 'Merge a pull request asynchronously',
13095
+ 'route_params': ['owner', 'repo', 'pull_number'],
13096
+ 'body_params': ['commit_title', 'commit_message', 'sha', 'merge_method', 'merge_action'],
13097
+ 'request_content_type': 'application/json',
13098
+ 'required_params': ['owner', 'pull_number', 'repo'],
13099
+ 'param_types': {'owner': 'str', 'repo': 'str', 'pull_number': 'int', 'commit_title': 'str', 'commit_message': 'str', 'sha': 'str', 'merge_method': 'str', 'merge_action': 'str'},
13100
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
13101
+ 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
13102
+ 'pull_number': 'The number that identifies the pull request.',
13103
+ 'commit_title': 'Title for the automatic commit message.',
13104
+ 'commit_message': 'Extra detail to append to automatic commit message.',
13105
+ 'sha': 'SHA that pull request head must match to allow merge. If not provided, the current head of the PR at the time of the request will be used; if the PR is pushed in between the merge being requested and being executed, the merge will be cancelled.',
13106
+ 'merge_method': 'The merge method to use.',
13107
+ 'merge_action': 'The action that will be taken to merge the pull request. `direct_merge` merges the pull request directly without using a merge queue; `merge_queue` adds the pull request to a merge queue; `default` selects the most appropriate option.'},
13108
+ 'docs_url': 'https://docs.github.com/rest/pulls/pulls#merge-a-pull-request-asynchronously'},
13109
+ {'group': 'pulls',
13110
+ 'name': 'get_merge_async_result',
13111
+ 'path': '/repos/{owner}/{repo}/pulls/{pull_number}/merge-async/{uuid}',
13112
+ 'verb': 'GET',
13113
+ 'summary': 'Get the result of an asynchronous merge',
13114
+ 'route_params': ['owner', 'repo', 'pull_number', 'uuid'],
13115
+ 'required_params': ['owner', 'pull_number', 'repo', 'uuid'],
13116
+ 'param_types': {'owner': 'str', 'repo': 'str', 'pull_number': 'int', 'uuid': 'str'},
13117
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
13118
+ 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
13119
+ 'pull_number': 'The number that identifies the pull request.',
13120
+ 'uuid': 'The UUID of the asynchronous merge request, as returned when the merge was requested.'},
13121
+ 'docs_url': 'https://docs.github.com/rest/pulls/pulls#get-the-result-of-an-asynchronous-merge'},
12915
13122
  {'group': 'pulls',
12916
13123
  'name': 'list_requested_reviewers',
12917
13124
  'path': '/repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers',
@@ -13603,6 +13810,73 @@ spec = {'base_url': 'https://api.github.com',
13603
13810
  'page': 'The page number of the results to fetch. For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."',
13604
13811
  'per_page': 'The number of results per page (max 100). For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."'},
13605
13812
  'docs_url': 'https://docs.github.com/rest/secret-scanning/secret-scanning#list-locations-for-a-secret-scanning-alert'},
13813
+ {'group': 'secret_scanning',
13814
+ 'name': 'list_repo_custom_patterns',
13815
+ 'path': '/repos/{owner}/{repo}/secret-scanning/custom-patterns',
13816
+ 'verb': 'GET',
13817
+ 'summary': 'List repository custom patterns',
13818
+ 'route_params': ['owner', 'repo'],
13819
+ 'query_params': ['state', 'push_protection', 'sort', 'direction', 'page', 'per_page'],
13820
+ 'required_params': ['owner', 'repo'],
13821
+ 'param_types': {'owner': 'str', 'repo': 'str', 'state': 'str', 'push_protection': 'str', 'sort': 'str', 'direction': 'str', 'page': 'int', 'per_page': 'int'},
13822
+ 'param_defaults': {'sort': 'created', 'direction': 'desc', 'page': 1, 'per_page': 30},
13823
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
13824
+ 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
13825
+ 'state': 'Filter custom patterns by state. When absent, returns patterns in all states.',
13826
+ 'push_protection': 'Filter custom patterns by whether push protection is enabled. When absent, returns patterns regardless of push protection status.',
13827
+ 'sort': 'The property to sort the results by.',
13828
+ 'direction': 'The direction to sort the results by.',
13829
+ 'page': 'The page number of the results to fetch. For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."',
13830
+ 'per_page': 'The number of results per page (max 100). For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."'},
13831
+ 'docs_url': 'https://docs.github.com/rest/secret-scanning/custom-patterns#list-repository-custom-patterns'},
13832
+ {'group': 'secret_scanning',
13833
+ 'name': 'bulk_create_repo_custom_patterns',
13834
+ 'path': '/repos/{owner}/{repo}/secret-scanning/custom-patterns',
13835
+ 'verb': 'POST',
13836
+ 'summary': 'Bulk create repository custom patterns',
13837
+ 'route_params': ['owner', 'repo'],
13838
+ 'body_params': ['patterns'],
13839
+ 'request_content_type': 'application/json',
13840
+ 'required_params': ['owner', 'patterns', 'repo'],
13841
+ 'param_types': {'owner': 'str', 'repo': 'str', 'patterns': 'list'},
13842
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.', 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.', 'patterns': 'The list of custom patterns to create.'},
13843
+ 'docs_url': 'https://docs.github.com/rest/secret-scanning/custom-patterns#bulk-create-repository-custom-patterns'},
13844
+ {'group': 'secret_scanning',
13845
+ 'name': 'bulk_delete_repo_custom_patterns',
13846
+ 'path': '/repos/{owner}/{repo}/secret-scanning/custom-patterns',
13847
+ 'verb': 'DELETE',
13848
+ 'summary': 'Bulk delete repository custom patterns',
13849
+ 'route_params': ['owner', 'repo'],
13850
+ 'body_params': ['patterns', 'post_delete_action'],
13851
+ 'request_content_type': 'application/json',
13852
+ 'required_params': ['owner', 'patterns', 'repo'],
13853
+ 'param_types': {'owner': 'str', 'repo': 'str', 'patterns': 'list', 'post_delete_action': 'str'},
13854
+ 'param_defaults': {'post_delete_action': 'delete_alerts'},
13855
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
13856
+ 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
13857
+ 'patterns': 'The list of custom patterns to delete.',
13858
+ 'post_delete_action': 'What to do with alerts associated with the deleted patterns. `delete_alerts` permanently removes the alerts. `resolve_alerts` resolves the alerts as "pattern deleted". Defaults to `delete_alerts` when not specified.'},
13859
+ 'docs_url': 'https://docs.github.com/rest/secret-scanning/custom-patterns#bulk-delete-repository-custom-patterns'},
13860
+ {'group': 'secret_scanning',
13861
+ 'name': 'update_repo_custom_pattern',
13862
+ 'path': '/repos/{owner}/{repo}/secret-scanning/custom-patterns/{pattern_id}',
13863
+ 'verb': 'PATCH',
13864
+ 'summary': 'Update a repository custom pattern',
13865
+ 'route_params': ['owner', 'repo', 'pattern_id'],
13866
+ 'body_params': ['pattern', 'start_delimiter', 'end_delimiter', 'must_match', 'must_not_match', 'custom_pattern_version'],
13867
+ 'request_content_type': 'application/json',
13868
+ 'required_params': ['custom_pattern_version', 'owner', 'pattern_id', 'repo'],
13869
+ 'param_types': {'owner': 'str', 'repo': 'str', 'pattern_id': 'int', 'pattern': 'str', 'start_delimiter': 'str', 'end_delimiter': 'str', 'must_match': 'list', 'must_not_match': 'list', 'custom_pattern_version': 'str'},
13870
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
13871
+ 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
13872
+ 'pattern_id': 'The ID of the custom pattern.',
13873
+ 'pattern': 'The updated regular expression of the custom pattern.',
13874
+ 'start_delimiter': 'The updated start delimiter regex for the custom pattern.',
13875
+ 'end_delimiter': 'The updated end delimiter regex for the custom pattern.',
13876
+ 'must_match': 'Updated list of regexes that the secret must match.',
13877
+ 'must_not_match': 'Updated list of regexes that the secret must not match.',
13878
+ 'custom_pattern_version': "The version of the entity. This is used to confirm you're updating the current version of the entity and mitigate unintentionally overriding someone else's update."},
13879
+ 'docs_url': 'https://docs.github.com/rest/secret-scanning/custom-patterns#update-a-repository-custom-pattern'},
13606
13880
  {'group': 'secret_scanning',
13607
13881
  'name': 'create_push_protection_bypass',
13608
13882
  'path': '/repos/{owner}/{repo}/secret-scanning/push-protection-bypasses',
@@ -13748,6 +14022,69 @@ spec = {'base_url': 'https://api.github.com',
13748
14022
  'param_types': {'owner': 'str', 'repo': 'str', 'ghsa_id': 'str'},
13749
14023
  'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.', 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.', 'ghsa_id': 'The GHSA (GitHub Security Advisory) identifier of the advisory.'},
13750
14024
  'docs_url': 'https://docs.github.com/rest/security-advisories/repository-advisories#create-a-temporary-private-fork'},
14025
+ {'group': 'pull_request_stacks',
14026
+ 'name': 'list',
14027
+ 'path': '/repos/{owner}/{repo}/stacks',
14028
+ 'verb': 'GET',
14029
+ 'summary': 'List pull request stacks',
14030
+ 'route_params': ['owner', 'repo'],
14031
+ 'query_params': ['pull_request', 'per_page', 'page'],
14032
+ 'required_params': ['owner', 'repo'],
14033
+ 'param_types': {'owner': 'str', 'repo': 'str', 'pull_request': 'int', 'per_page': 'int', 'page': 'int'},
14034
+ 'param_defaults': {'per_page': 30, 'page': 1},
14035
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
14036
+ 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
14037
+ 'pull_request': 'Filter to the stack containing this repository pull request number.',
14038
+ 'per_page': 'The number of results per page (max 100). For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."',
14039
+ 'page': 'The page number of the results to fetch. For more information, see "[Using pagination in the REST API](https://docs.github.com/rest/using-the-rest-api/using-pagination-in-the-rest-api)."'},
14040
+ 'docs_url': 'https://docs.github.com/rest/pulls/stacks#list-pull-request-stacks'},
14041
+ {'group': 'pull_request_stacks',
14042
+ 'name': 'create',
14043
+ 'path': '/repos/{owner}/{repo}/stacks',
14044
+ 'verb': 'POST',
14045
+ 'summary': 'Create a pull request stack',
14046
+ 'route_params': ['owner', 'repo'],
14047
+ 'body_params': ['pull_requests'],
14048
+ 'request_content_type': 'application/json',
14049
+ 'required_params': ['owner', 'pull_requests', 'repo'],
14050
+ 'param_types': {'owner': 'str', 'repo': 'str', 'pull_requests': 'list'},
14051
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.', 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.', 'pull_requests': 'An ordered list of pull request numbers forming the stack from bottom to top.'},
14052
+ 'docs_url': 'https://docs.github.com/rest/pulls/stacks#create-a-pull-request-stack'},
14053
+ {'group': 'pull_request_stacks',
14054
+ 'name': 'get',
14055
+ 'path': '/repos/{owner}/{repo}/stacks/{stack_number}',
14056
+ 'verb': 'GET',
14057
+ 'summary': 'Get a pull request stack',
14058
+ 'route_params': ['owner', 'repo', 'stack_number'],
14059
+ 'required_params': ['owner', 'repo', 'stack_number'],
14060
+ 'param_types': {'owner': 'str', 'repo': 'str', 'stack_number': 'int'},
14061
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.', 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.', 'stack_number': 'The number that identifies the pull request stack.'},
14062
+ 'docs_url': 'https://docs.github.com/rest/pulls/stacks#get-a-pull-request-stack'},
14063
+ {'group': 'pull_request_stacks',
14064
+ 'name': 'add',
14065
+ 'path': '/repos/{owner}/{repo}/stacks/{stack_number}/add',
14066
+ 'verb': 'POST',
14067
+ 'summary': 'Add pull requests to a pull request stack',
14068
+ 'route_params': ['owner', 'repo', 'stack_number'],
14069
+ 'body_params': ['pull_requests'],
14070
+ 'request_content_type': 'application/json',
14071
+ 'required_params': ['owner', 'pull_requests', 'repo', 'stack_number'],
14072
+ 'param_types': {'owner': 'str', 'repo': 'str', 'stack_number': 'int', 'pull_requests': 'list'},
14073
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.',
14074
+ 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.',
14075
+ 'stack_number': 'The number that identifies the pull request stack.',
14076
+ 'pull_requests': 'An ordered list of pull request numbers to append to the stack, from the current top upward.'},
14077
+ 'docs_url': 'https://docs.github.com/rest/pulls/stacks#add-pull-requests-to-a-pull-request-stack'},
14078
+ {'group': 'pull_request_stacks',
14079
+ 'name': 'unstack',
14080
+ 'path': '/repos/{owner}/{repo}/stacks/{stack_number}/unstack',
14081
+ 'verb': 'POST',
14082
+ 'summary': 'Remove pull requests from a pull request stack',
14083
+ 'route_params': ['owner', 'repo', 'stack_number'],
14084
+ 'required_params': ['owner', 'repo', 'stack_number'],
14085
+ 'param_types': {'owner': 'str', 'repo': 'str', 'stack_number': 'int'},
14086
+ 'param_docs': {'owner': 'The account owner of the repository. The name is not case sensitive.', 'repo': 'The name of the repository without the `.git` extension. The name is not case sensitive.', 'stack_number': 'The number that identifies the pull request stack.'},
14087
+ 'docs_url': 'https://docs.github.com/rest/pulls/stacks#remove-pull-requests-from-a-pull-request-stack'},
13751
14088
  {'group': 'activity',
13752
14089
  'name': 'list_stargazers_for_repo',
13753
14090
  'path': '/repos/{owner}/{repo}/stargazers',
@@ -14209,10 +14546,10 @@ spec = {'base_url': 'https://api.github.com',
14209
14546
  'verb': 'PATCH',
14210
14547
  'summary': 'Update a team (Legacy)',
14211
14548
  'route_params': ['team_id'],
14212
- 'body_params': ['name', 'description', 'privacy', 'notification_setting', 'permission', 'parent_team_id'],
14549
+ 'body_params': ['name', 'description', 'privacy', 'notification_setting', 'permission', 'parent_team_id', 'parent_team_slug'],
14213
14550
  'request_content_type': 'application/json',
14214
14551
  'required_params': ['name', 'team_id'],
14215
- 'param_types': {'team_id': 'int', 'name': 'str', 'description': 'str', 'privacy': 'str', 'notification_setting': 'str', 'permission': 'str', 'parent_team_id': 'int'},
14552
+ 'param_types': {'team_id': 'int', 'name': 'str', 'description': 'str', 'privacy': 'str', 'notification_setting': 'str', 'permission': 'str', 'parent_team_id': 'int', 'parent_team_slug': 'str'},
14216
14553
  'param_defaults': {'permission': 'pull'},
14217
14554
  'param_docs': {'team_id': 'The unique identifier of the team.',
14218
14555
  'name': 'The name of the team.',
@@ -14221,7 +14558,8 @@ spec = {'base_url': 'https://api.github.com',
14221
14558
  'team:** * `closed` - visible to all members of this organization.',
14222
14559
  'notification_setting': 'The notification setting the team has chosen. Editing teams without specifying this parameter leaves `notification_setting` intact. The options are: * `notifications_enabled` - team members receive notifications when the team is @mentioned. * `notifications_disabled` - no one receives notifications.',
14223
14560
  'permission': '**Closing down notice**. The permission that new repositories will be added to the team with when none is specified.',
14224
- 'parent_team_id': 'The ID of a team to set as the parent team.'},
14561
+ 'parent_team_id': 'The ID of a team to set as the parent team.',
14562
+ 'parent_team_slug': 'The slug of a team to set as the parent team. Ignored when `parent_team_id` is also provided.'},
14225
14563
  'docs_url': 'https://docs.github.com/rest/teams/teams#update-a-team-legacy'},
14226
14564
  {'group': 'teams',
14227
14565
  'name': 'delete_legacy',
@@ -36,7 +36,14 @@ When you want the whole thing as one LLM-ready markdown string rather than struc
36
36
 
37
37
  `await api.check_status(ref)` merges the two ways CI results get reported -- the modern Checks API (`checks.list_for_ref`, what GitHub Actions uses) and the legacy Commit Status API (`repos.get_combined_status_for_ref`, used by some external CI) -- into one call, given a SHA/branch/tag. `api.pr_status(pull_number)` is the same, resolved from a PR's head commit.
38
38
 
39
- The result's repr is a one-line-per-check summary with a verdict computed from the check runs (the raw `state` field only reflects legacy statuses, so it reads `pending` on repos that only use Actions). Display it bare; drop to `.check_runs`/`.statuses` only when the summary isn't enough.
39
+ The result's repr is the triage step: a verdict line (computed from the check runs -- the raw `state` field only reflects legacy statuses, so it reads `pending` on repos that only use Actions), then the run list as concise one-line rows, `id name: conclusion (duration)`, plus any legacy statuses. Display it bare; drop to the `.check_runs`/`.statuses` fields only when the rows aren't enough.
40
+
41
+ The recommended process for working through a set of possibly-red repos:
42
+
43
+ api = GhApi(owner='AnswerDotAI')
44
+ sts = dict(zip(repos, await asyncio.gather(*(api.check_status('main', repo=r) for r in repos))))
45
+
46
+ One `gather` gives every repo's verdict at once. For each red repo, display its full status -- every run, not just the failures, since a failed run beside a similar green one is itself diagnostic -- then feed the failing row's id to `await api.failed_step_log(id, repo=r)`: a check run and its Actions job share an id, so the row leads straight to its log, returned cut down to just the failed steps' sections. Job logs expire after about 90 days, so grab them while the run is fresh.
40
47
 
41
48
  # Day-to-day work
42
49
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ghapi
3
- Version: 2.0.5
3
+ Version: 2.0.6
4
4
  Summary: A python client for the GitHub API
5
5
  Author-email: Jeremy Howard <info@fast.ai>
6
6
  License: Apache-2.0
@@ -16,7 +16,8 @@ Requires-Python: >=3.10
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: fastcore>=2.1.16
19
- Requires-Dist: fastspec>=0.1.2
19
+ Requires-Dist: fastspec>=0.1.5
20
+ Requires-Dist: tomli; python_version < "3.11"
20
21
  Provides-Extra: dev
21
22
  Requires-Dist: fastgit; extra == "dev"
22
23
  Requires-Dist: matplotlib; extra == "dev"
@@ -1,5 +1,8 @@
1
1
  fastcore>=2.1.16
2
- fastspec>=0.1.2
2
+ fastspec>=0.1.5
3
+
4
+ [:python_version < "3.11"]
5
+ tomli
3
6
 
4
7
  [dev]
5
8
  fastgit
@@ -12,7 +12,7 @@ license = {text = "Apache-2.0"}
12
12
  authors = [{name = "Jeremy Howard", email = "info@fast.ai"}]
13
13
  keywords = ['github', 'api']
14
14
  classifiers = ["Natural Language :: English", "Intended Audience :: Developers", "Development Status :: 5 - Production/Stable", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only"]
15
- dependencies = ['fastcore>=2.1.16', 'fastspec>=0.1.2']
15
+ dependencies = ['fastcore>=2.1.16', 'fastspec>=0.1.5', 'tomli; python_version < "3.11"']
16
16
 
17
17
  [project.urls]
18
18
  Repository = "https://github.com/fastai/ghapi"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes