github-rest-api 0.47.2__py3-none-any.whl → 0.48.0__py3-none-any.whl

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.
github_rest_api/github.py CHANGED
@@ -31,9 +31,9 @@ DEFAULT_PR_MODEL = "anthropic/claude-haiku-4-5-20251001"
31
31
  # Defaults for automatic pull request merging (see Repository.auto_merge_pull_requests).
32
32
  # A marker comment from an allowlisted approver is accepted as an approval signal
33
33
  # for AI reviewers that only comment instead of submitting a formal review.
34
- DEFAULT_AUTO_MERGE_MARKER = "<!-- auto-merge: approved -->"
34
+ DEFAULT_AUTO_MERGE_MARKER = "AUTO_MERGE_APPROVED"
35
35
  # Conventional-commit title types eligible for auto-merge.
36
- DEFAULT_AUTO_MERGE_TYPES = ("chore", "docs", "deps")
36
+ DEFAULT_AUTO_MERGE_TYPES = ("build", "chore", "ci", "docs", "deps")
37
37
  # A PR is only auto-merged once its head commit is at least this old, an anti-race
38
38
  # guard so a PR that momentarily reads `clean` before CI registers is not merged.
39
39
  # A just-created PR is simply deferred to the next run, never dropped, so a small
@@ -177,8 +177,15 @@ def _field_gate_failure(
177
177
  return "it is a draft"
178
178
  if not _in_allowlist(_login(pr), _normalized_logins(authors)):
179
179
  return "its author is not in the allowlist"
180
- if not _title_type_allowed(pr.get("title") or "", allowed_types):
181
- return "its title type is not auto-merge eligible"
180
+ title = pr.get("title") or ""
181
+ if not _title_type_allowed(title, allowed_types):
182
+ type_ = _conventional_type(title)
183
+ current = f"'{type_}'" if type_ is not None else "missing/unrecognized"
184
+ eligible = ", ".join(allowed_types) or "none"
185
+ return (
186
+ f"its title type ({current}) is not auto-merge eligible "
187
+ f"(eligible types: {eligible})"
188
+ )
182
189
  return None
183
190
 
184
191
 
@@ -67,8 +67,12 @@ def _init_local_repo(
67
67
  dir_: str,
68
68
  token: str,
69
69
  protocol: str,
70
+ push: bool,
70
71
  branches: Sequence[str] = ("main",),
71
72
  ) -> None:
73
+ branches = list(dict.fromkeys(branches))
74
+ if not branches:
75
+ raise ValueError("At least one branch must be specified.")
72
76
  repo_name = repo.split("/")[-1]
73
77
  path = Path(dir_) if dir_ else Path(repo_name)
74
78
  path.mkdir(parents=True, exist_ok=True)
@@ -94,21 +98,26 @@ def _init_local_repo(
94
98
  if initial_branch not in branches:
95
99
  porcelain.branch_delete(repo=path, name=initial_branch)
96
100
  logger.info("Deleted initial branch '%s'", initial_branch)
101
+ else:
102
+ existing_branches = {b.decode() for b in porcelain.branch_list(path)}
103
+ for branch in branches:
104
+ if branch not in existing_branches:
105
+ porcelain.branch_create(repo=path, name=branch)
106
+ logger.info("Created branch '%s' from HEAD", branch)
97
107
  _ensure_remote(path, repo, protocol)
98
- local_branches = {b.decode() for b in porcelain.branch_list(path)}
99
- branches_to_push = [branch for branch in branches if branch in local_branches]
100
- if not branches_to_push:
101
- branches_to_push = [_active_branch(path)]
102
- for branch in branches_to_push:
103
- logger.info("Pushing branch '%s' to remote '%s'...", branch, repo)
104
- porcelain.push(
105
- repo=path,
106
- remote_location=_remote_url(repo, "https"),
107
- refspecs=[branch.encode()],
108
- username="x-access-token",
109
- password=token,
110
- )
111
- logger.info("Successfully pushed branch '%s'.", branch)
108
+ if push:
109
+ for branch in branches:
110
+ logger.info("Pushing branch '%s' to remote '%s'...", branch, repo)
111
+ porcelain.push(
112
+ repo=path,
113
+ remote_location=_remote_url(repo, "https"),
114
+ refspecs=[branch.encode()],
115
+ username="x-access-token",
116
+ password=token,
117
+ )
118
+ logger.info("Successfully pushed branch '%s'.", branch)
119
+ else:
120
+ logger.info("Skipping push (pass --push to push branches to the remote).")
112
121
  _add_workflow(path, language)
113
122
 
114
123
 
@@ -120,6 +129,7 @@ def create_github_repo(
120
129
  dir_: str,
121
130
  token: str,
122
131
  protocol: str,
132
+ push: bool,
123
133
  branches: Sequence[str] = ("main",),
124
134
  ) -> None:
125
135
  token = token or os.getenv("GITHUB_TOKEN", "")
@@ -141,6 +151,7 @@ def create_github_repo(
141
151
  token=token,
142
152
  branches=branches,
143
153
  protocol=protocol,
154
+ push=push,
144
155
  )
145
156
 
146
157
 
@@ -223,7 +234,7 @@ def parse_args(args=None, namespace=None):
223
234
  nargs="+",
224
235
  default=["main"],
225
236
  metavar="BRANCH",
226
- help="Branches to create and push to remote (default: main).",
237
+ help="Branches to create (and push if --push is set) (default: main).",
227
238
  )
228
239
  parser.add_argument(
229
240
  "--https",
@@ -233,6 +244,12 @@ def parse_args(args=None, namespace=None):
233
244
  default="git",
234
245
  help="Use the HTTPS protocol for the remote URL.",
235
246
  )
247
+ parser.add_argument(
248
+ "--push",
249
+ dest="push",
250
+ action="store_true",
251
+ help="Push branches to the remote (by default, nothing is pushed).",
252
+ )
236
253
  parser.add_argument(
237
254
  "-v",
238
255
  "--verbose",
@@ -256,6 +273,7 @@ def main() -> int:
256
273
  token=args.token,
257
274
  branches=args.branches,
258
275
  protocol=args.protocol,
276
+ push=args.push,
259
277
  )
260
278
  except Exception as e:
261
279
  logger.error("Failed to create GitHub repo: %s", e, exc_info=args.verbose)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github-rest-api
3
- Version: 0.47.2
3
+ Version: 0.48.0
4
4
  Summary: Simple wrapper of GitHub REST APIs.
5
5
  Author-email: Ben Du <longendu@yahoo.com>
6
6
  Classifier: Programming Language :: Python :: 3 :: Only
@@ -1,5 +1,5 @@
1
1
  github_rest_api/__init__.py,sha256=VVpiUHVLbjjJGNN88OmEvCwq4xmBnXv68T8Apk_lwVc,282
2
- github_rest_api/github.py,sha256=iAfhPLH9UGPtScZfcV1TCeY5XfUzAMqenf5FrSNplQc,45146
2
+ github_rest_api/github.py,sha256=tcP2ETyIySFto82S73IZLDaRaRrj9bZjd9wi-VWKUIo,45427
3
3
  github_rest_api/pr_content.py,sha256=og1VwsMtwqwl-HUJcJrkwjUjFPw9E1k5xDtJVMAXBRo,10039
4
4
  github_rest_api/utils.py,sha256=RspoIZik0g105KpyFXCf4epAtgu1dUsxwlwUSSGhXPI,2697
5
5
  github_rest_api/scripts/__init__.py,sha256=NkHTngnnWXPc0JmO5mqVKjDf4JPofuwWjDW1SU3aE7Y,36
@@ -14,7 +14,7 @@ github_rest_api/scripts/container/config_container.py,sha256=BtOqgZlQFM9cWZMoHKv
14
14
  github_rest_api/scripts/container/update_version_containerfile.py,sha256=1PkuJkAsJBCEMdacMSndbuZKcmgUyXy6nBArnxKoPZk,4535
15
15
  github_rest_api/scripts/github/__init__.py,sha256=tEU1SdCS51M4M13WoqXZt3rjGEAI_QgNljt5XAyQJ_w,38
16
16
  github_rest_api/scripts/github/auto_merge_pull_request.py,sha256=_5191Xt_b8DtxjIqHrdY-gKLxvkzWd8oWoSbF2uauc8,3527
17
- github_rest_api/scripts/github/create_github_repo.py,sha256=jH1uKOXKOxooO-PHMGlQ5YnIluWNqzRhkfgKdkH5UGU,8316
17
+ github_rest_api/scripts/github/create_github_repo.py,sha256=6WBMcHtY0rn_ZaF_3TN_sX2QFpklE4TPKNSXOPBwmw0,8919
18
18
  github_rest_api/scripts/github/create_pull_request.py,sha256=gXtRRsxzegGxagHb6k3kxtRd3mt4QVwSPZQpsFnzz1Y,3968
19
19
  github_rest_api/scripts/github/release_on_github.py,sha256=9psaIv-GtrHdvE-tkw0yxCMDmW0bPts-db2vUxhoKXo,4368
20
20
  github_rest_api/scripts/github/remove_branch.py,sha256=iKZ4Y_lQlSOIfifC4plqP-B6pEMnFrknGMvV1oLnuLc,3538
@@ -25,7 +25,7 @@ github_rest_api/scripts/github/workflows/create_pr_to_main.yaml,sha256=mgHPlewkC
25
25
  github_rest_api/scripts/github/workflows/remove_branch.yaml,sha256=KDpB76ovrhuRdP0HN5j6Th9gjIQWSDdh8b4b4yAgtoI,544
26
26
  github_rest_api/scripts/github/workflows/python/lint.yaml,sha256=toP2oUdVIKyu_n20Dr14k5cJYxN8rPksfbX4sfflXxc,699
27
27
  github_rest_api/scripts/github/workflows/python/test.yaml,sha256=86MljYEWX1E9kJYmhMCLwu46WNEWvoyO9PwqeRew540,887
28
- github_rest_api-0.47.2.dist-info/METADATA,sha256=7Z7N5_Ed4-TbTs2G9T17mSdtM74ZO2FU_8dyvfKFoOE,915
29
- github_rest_api-0.47.2.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
30
- github_rest_api-0.47.2.dist-info/entry_points.txt,sha256=OfbP9GuQC7SyGbymfCYrXEG-TCcKuu31v0EPNvHc1Q4,659
31
- github_rest_api-0.47.2.dist-info/RECORD,,
28
+ github_rest_api-0.48.0.dist-info/METADATA,sha256=GUo2AkySz1q5KewbBDYUPV-2Yvbchmhd4WXyT2zescs,915
29
+ github_rest_api-0.48.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
30
+ github_rest_api-0.48.0.dist-info/entry_points.txt,sha256=OfbP9GuQC7SyGbymfCYrXEG-TCcKuu31v0EPNvHc1Q4,659
31
+ github_rest_api-0.48.0.dist-info/RECORD,,