github-rest-api 0.39.1__tar.gz → 0.41.0__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.
- github_rest_api-0.41.0/.devcontainer/devcontainer.json +30 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/PKG-INFO +2 -1
- github_rest_api-0.41.0/github_rest_api/__init__.py +11 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/github.py +147 -25
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/github/add_github_repo.py +87 -64
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/github/create_pull_request.py +30 -3
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/utils.py +23 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/pyproject.toml +2 -1
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/tests/test_github.py +11 -1
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/uv.lock +104 -1
- github_rest_api-0.39.1/.claude/settings.json +0 -9
- github_rest_api-0.39.1/.gemini/system.md +0 -10
- github_rest_api-0.39.1/.gitpod.yml +0 -9
- github_rest_api-0.39.1/github_rest_api/__init__.py +0 -5
- /github_rest_api-0.39.1/.github/workflows/create_pr_to_main.yml → /github_rest_api-0.41.0/.github/workflows/create_pr_to_main.yaml +0 -0
- /github_rest_api-0.39.1/.github/workflows/lint.yml → /github_rest_api-0.41.0/.github/workflows/lint.yaml +0 -0
- /github_rest_api-0.39.1/.github/workflows/release.yml → /github_rest_api-0.41.0/.github/workflows/release.yaml +0 -0
- /github_rest_api-0.39.1/.github/workflows/remove_branch.yml → /github_rest_api-0.41.0/.github/workflows/remove_branch.yaml +0 -0
- /github_rest_api-0.39.1/.github/workflows/test.yml → /github_rest_api-0.41.0/.github/workflows/test.yaml +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/.gitignore +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/GEMINI.md +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/README.md +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/__init__.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/cargo/__init__.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/cargo/benchmark.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/cargo/profiling.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/cargo/utils.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/container/__init__.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/container/build_container_images.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/container/config_container.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/container/update_version_containerfile.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/github/__init__.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/github/release_on_github.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/github/remove_branch.py +0 -0
- /github_rest_api-0.39.1/github_rest_api/scripts/github/workflows/create_pr_dev_to_main.yml → /github_rest_api-0.41.0/github_rest_api/scripts/github/workflows/create_pr_dev_to_main.yaml +0 -0
- /github_rest_api-0.39.1/github_rest_api/scripts/github/workflows/create_pr_to_dev.yml → /github_rest_api-0.41.0/github_rest_api/scripts/github/workflows/create_pr_to_dev.yaml +0 -0
- /github_rest_api-0.39.1/github_rest_api/scripts/github/workflows/create_pr_to_main.yml → /github_rest_api-0.41.0/github_rest_api/scripts/github/workflows/create_pr_to_main.yaml +0 -0
- /github_rest_api-0.39.1/github_rest_api/scripts/github/workflows/python/lint.yml → /github_rest_api-0.41.0/github_rest_api/scripts/github/workflows/python/lint.yaml +0 -0
- /github_rest_api-0.39.1/github_rest_api/scripts/github/workflows/python/test.yml → /github_rest_api-0.41.0/github_rest_api/scripts/github/workflows/python/test.yaml +0 -0
- /github_rest_api-0.39.1/github_rest_api/scripts/github/workflows/remove_branch.yml → /github_rest_api-0.41.0/github_rest_api/scripts/github/workflows/remove_branch.yaml +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/utils.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/memory/MEMORY.md +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/memory/feedback_test_runner.md +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/tests/__init__.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/tests/test_build_container_images.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/tests/test_release_on_github.py +0 -0
- {github_rest_api-0.39.1 → github_rest_api-0.41.0}/tests/test_utils.py +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Fedora Codespace",
|
|
3
|
+
"image": "quay.io/legendu/codespaces:next",
|
|
4
|
+
"remoteUser": "vscode",
|
|
5
|
+
"customizations": {
|
|
6
|
+
"vscode": {
|
|
7
|
+
"settings": {
|
|
8
|
+
"terminal.integrated.defaultProfile.linux": "fish"
|
|
9
|
+
},
|
|
10
|
+
"extensions": [
|
|
11
|
+
"Google.geminicodeassist",
|
|
12
|
+
"anthropic.claude-code",
|
|
13
|
+
"asvetliakov.vscode-neovim",
|
|
14
|
+
"mechatroner.rainbow-csv",
|
|
15
|
+
"usernamehw.errorlens",
|
|
16
|
+
"ms-python.python",
|
|
17
|
+
"charliermarsh.ruff",
|
|
18
|
+
"astral-sh.ty",
|
|
19
|
+
"golang.Go",
|
|
20
|
+
"njpwerner.autodocstring",
|
|
21
|
+
"rust-lang.rust-analyzer",
|
|
22
|
+
"fill-labs.dependi",
|
|
23
|
+
"vadimcn.vscode-lldb",
|
|
24
|
+
"fwcd.kotlin",
|
|
25
|
+
"karsten7.mojo-vscode",
|
|
26
|
+
"ReneSaarsoo.sql-formatter-vsc"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: github-rest-api
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.41.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
|
|
@@ -10,6 +10,7 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
10
10
|
Requires-Python: <4,>=3.12
|
|
11
11
|
Requires-Dist: dulwich>=0.25.1
|
|
12
12
|
Requires-Dist: psutil>=5.9.4
|
|
13
|
+
Requires-Dist: pynacl>=1.5
|
|
13
14
|
Requires-Dist: pyyaml>=6
|
|
14
15
|
Requires-Dist: requests>=2.28.2
|
|
15
16
|
Requires-Dist: tenacity>=9.1.4
|
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
"""Simple wrapper of GitHub REST APIs."""
|
|
2
2
|
|
|
3
3
|
from abc import ABCMeta, abstractmethod
|
|
4
|
+
from base64 import b64encode
|
|
5
|
+
from collections.abc import Sequence
|
|
4
6
|
from enum import StrEnum
|
|
5
7
|
from typing import Any, Callable
|
|
6
8
|
from pathlib import Path
|
|
7
9
|
import requests
|
|
10
|
+
from nacl import encoding, public
|
|
11
|
+
|
|
12
|
+
URL_API = "https://api.github.com"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _encrypt_secret(public_key: str, value: str) -> str:
|
|
16
|
+
"""Encrypt a secret value using a LibSodium sealed box.
|
|
17
|
+
:param public_key: The base64-encoded public key to encrypt against.
|
|
18
|
+
:param value: The plaintext secret value to encrypt.
|
|
19
|
+
"""
|
|
20
|
+
pkey = public.PublicKey(public_key.encode(), encoding.Base64Encoder)
|
|
21
|
+
encrypted = public.SealedBox(pkey).encrypt(value.encode())
|
|
22
|
+
return b64encode(encrypted).decode()
|
|
8
23
|
|
|
9
24
|
|
|
10
25
|
def build_http_headers(token: str) -> dict[str, str]:
|
|
@@ -36,6 +51,12 @@ class GitHub:
|
|
|
36
51
|
def _get(
|
|
37
52
|
self, url: str, raise_for_status: bool = True, **kwargs
|
|
38
53
|
) -> requests.Response:
|
|
54
|
+
"""Send a GET request to a GitHub REST API endpoint.
|
|
55
|
+
:param url: The endpoint URL to request.
|
|
56
|
+
:param raise_for_status: Whether to raise on a non-2xx response.
|
|
57
|
+
:param kwargs: Additional keyword arguments (e.g. `params`) forwarded
|
|
58
|
+
to `requests.get`.
|
|
59
|
+
"""
|
|
39
60
|
resp = requests.get(
|
|
40
61
|
url=url,
|
|
41
62
|
headers=self._headers,
|
|
@@ -49,6 +70,13 @@ class GitHub:
|
|
|
49
70
|
def _post(
|
|
50
71
|
self, url: str, headers=None, raise_for_status: bool = True, **kwargs
|
|
51
72
|
) -> requests.Response:
|
|
73
|
+
"""Send a POST request to a GitHub REST API endpoint.
|
|
74
|
+
:param url: The endpoint URL to request.
|
|
75
|
+
:param headers: Request headers; defaults to the standard auth headers.
|
|
76
|
+
:param raise_for_status: Whether to raise on a non-2xx response.
|
|
77
|
+
:param kwargs: Additional keyword arguments (e.g. `json`) forwarded
|
|
78
|
+
to `requests.post`.
|
|
79
|
+
"""
|
|
52
80
|
if headers is None:
|
|
53
81
|
headers = self._headers
|
|
54
82
|
resp = requests.post(
|
|
@@ -67,17 +95,32 @@ class GitHub:
|
|
|
67
95
|
resp.raise_for_status()
|
|
68
96
|
return resp
|
|
69
97
|
|
|
70
|
-
def _put(
|
|
98
|
+
def _put(
|
|
99
|
+
self, url: str, raise_for_status: bool = True, **kwargs
|
|
100
|
+
) -> requests.Response:
|
|
101
|
+
"""Send a PUT request to a GitHub REST API endpoint.
|
|
102
|
+
:param url: The endpoint URL to request.
|
|
103
|
+
:param raise_for_status: Whether to raise on a non-2xx response.
|
|
104
|
+
:param kwargs: Additional keyword arguments (e.g. `json`) forwarded
|
|
105
|
+
to `requests.put`.
|
|
106
|
+
"""
|
|
71
107
|
resp = requests.put(
|
|
72
108
|
url=url,
|
|
73
109
|
headers=self._headers,
|
|
74
110
|
timeout=10,
|
|
111
|
+
**kwargs,
|
|
75
112
|
)
|
|
76
113
|
if raise_for_status:
|
|
77
114
|
resp.raise_for_status()
|
|
78
115
|
return resp
|
|
79
116
|
|
|
80
117
|
def _patch(self, url, raise_for_status: bool = True, **kwargs) -> requests.Response:
|
|
118
|
+
"""Send a PATCH request to a GitHub REST API endpoint.
|
|
119
|
+
:param url: The endpoint URL to request.
|
|
120
|
+
:param raise_for_status: Whether to raise on a non-2xx response.
|
|
121
|
+
:param kwargs: Additional keyword arguments (e.g. `json`) forwarded
|
|
122
|
+
to `requests.patch`.
|
|
123
|
+
"""
|
|
81
124
|
resp = requests.patch(
|
|
82
125
|
url=url,
|
|
83
126
|
headers=self._headers,
|
|
@@ -118,8 +161,7 @@ class Repository(GitHub):
|
|
|
118
161
|
"""
|
|
119
162
|
super().__init__(token)
|
|
120
163
|
self._repo = repo
|
|
121
|
-
self.
|
|
122
|
-
self._url_repo = f"{self._url}/{repo}"
|
|
164
|
+
self._url_repo = f"{URL_API}/repos/{repo}"
|
|
123
165
|
self._url_tags = f"{self._url_repo}/tags"
|
|
124
166
|
self._url_transfer = f"{self._url_repo}/transfer"
|
|
125
167
|
self._url_pull = f"{self._url_repo}/pulls"
|
|
@@ -127,6 +169,7 @@ class Repository(GitHub):
|
|
|
127
169
|
self._url_refs = f"{self._url_repo}/git/refs"
|
|
128
170
|
self._url_issues = f"{self._url_repo}/issues"
|
|
129
171
|
self._url_releases = f"{self._url_repo}/releases"
|
|
172
|
+
self._url_secrets = f"{self._url_repo}/actions/secrets"
|
|
130
173
|
|
|
131
174
|
def get_releases(self, n: int = 0) -> list[dict[str, Any]]:
|
|
132
175
|
"""List releases in this repository."""
|
|
@@ -157,8 +200,6 @@ class Repository(GitHub):
|
|
|
157
200
|
For more details, please refer to
|
|
158
201
|
https://docs.github.com/en/rest/releases/releases#create-a-release.
|
|
159
202
|
"""
|
|
160
|
-
if not isinstance(json, dict):
|
|
161
|
-
raise ValueError("A dict value is required for `json`.")
|
|
162
203
|
return self._post(
|
|
163
204
|
url=self._url_releases,
|
|
164
205
|
json=json,
|
|
@@ -171,7 +212,9 @@ class Repository(GitHub):
|
|
|
171
212
|
path = Path(path)
|
|
172
213
|
with path.open(mode="rb") as fin:
|
|
173
214
|
return self._post(
|
|
174
|
-
url=f"{self._url_releases.replace('api', 'uploads', 1)}/{
|
|
215
|
+
url=f"{self._url_releases.replace('api', 'uploads', 1)}/{
|
|
216
|
+
release
|
|
217
|
+
}/assets",
|
|
175
218
|
params={
|
|
176
219
|
"name": name,
|
|
177
220
|
},
|
|
@@ -193,8 +236,6 @@ class Repository(GitHub):
|
|
|
193
236
|
about the pull request to be created.
|
|
194
237
|
It's passed to the json parameter of requests.post.
|
|
195
238
|
"""
|
|
196
|
-
if not isinstance(json, dict):
|
|
197
|
-
raise ValueError("A dict value is required for `json`.")
|
|
198
239
|
if not ("head" in json and "base" in json):
|
|
199
240
|
raise ValueError("The data dict must contains keys head and base!")
|
|
200
241
|
# return an existing PR
|
|
@@ -217,8 +258,6 @@ class Repository(GitHub):
|
|
|
217
258
|
"""Merge a pull request in this repository.
|
|
218
259
|
:param pr_number: The number of the pull quest to be merged.
|
|
219
260
|
"""
|
|
220
|
-
if not isinstance(pr_number, int):
|
|
221
|
-
raise ValueError("An integer value is required for `pr_number`.")
|
|
222
261
|
return self._put(
|
|
223
262
|
url=f"{self._url_pull}/{pr_number}/merge",
|
|
224
263
|
).json()
|
|
@@ -228,10 +267,6 @@ class Repository(GitHub):
|
|
|
228
267
|
:param update: The branch to update.
|
|
229
268
|
:param upstream: The upstream branch.
|
|
230
269
|
"""
|
|
231
|
-
if not isinstance(update, str):
|
|
232
|
-
raise ValueError("A string value is required for `update`.")
|
|
233
|
-
if not isinstance(upstream, str):
|
|
234
|
-
raise ValueError("A string value is required for `upstream`.")
|
|
235
270
|
pr = self.create_pull_request(
|
|
236
271
|
{
|
|
237
272
|
"base": update,
|
|
@@ -250,8 +285,6 @@ class Repository(GitHub):
|
|
|
250
285
|
|
|
251
286
|
:param pr_number: The number of the pull request.
|
|
252
287
|
"""
|
|
253
|
-
if not isinstance(pr_number, int):
|
|
254
|
-
raise ValueError("An integer value is required for `pr_number`.")
|
|
255
288
|
return self._extract_all(url=f"{self._url_pull}/{pr_number}/files", n=n)
|
|
256
289
|
|
|
257
290
|
def get_branches(self, n: int = 0) -> list[dict[str, Any]]:
|
|
@@ -272,8 +305,6 @@ class Repository(GitHub):
|
|
|
272
305
|
"""Delete a reference from this repository.
|
|
273
306
|
:param ref: The reference to delete from this repository.
|
|
274
307
|
"""
|
|
275
|
-
if not isinstance(ref, str):
|
|
276
|
-
raise ValueError("A string value is required for `ref`.")
|
|
277
308
|
return self._delete(
|
|
278
309
|
url=f"{self._url_refs}/{ref}",
|
|
279
310
|
)
|
|
@@ -284,6 +315,36 @@ class Repository(GitHub):
|
|
|
284
315
|
"""
|
|
285
316
|
return self.delete_ref(ref=f"heads/{branch}")
|
|
286
317
|
|
|
318
|
+
def delete_secret(self, name: str) -> requests.Response:
|
|
319
|
+
"""Delete a secret from this repository.
|
|
320
|
+
:param name: The name of the secret to delete.
|
|
321
|
+
"""
|
|
322
|
+
return self._delete(
|
|
323
|
+
url=f"{self._url_secrets}/{name}",
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
def get_secret_public_key(self) -> dict[str, Any]:
|
|
327
|
+
"""Get the public key for encrypting secrets in this repository."""
|
|
328
|
+
return self._get(url=f"{self._url_secrets}/public-key").json()
|
|
329
|
+
|
|
330
|
+
def create_or_update_secret(
|
|
331
|
+
self, name: str, value: str, public_key: dict[str, Any]
|
|
332
|
+
) -> requests.Response:
|
|
333
|
+
"""Create or update a secret in this repository.
|
|
334
|
+
:param name: The name of the secret.
|
|
335
|
+
:param value: The plaintext value of the secret.
|
|
336
|
+
:param public_key: A public key (as returned by `get_secret_public_key`)
|
|
337
|
+
to encrypt the secret with. Fetch it once and reuse it to avoid a
|
|
338
|
+
redundant request when creating or updating multiple secrets.
|
|
339
|
+
"""
|
|
340
|
+
return self._put(
|
|
341
|
+
url=f"{self._url_secrets}/{name}",
|
|
342
|
+
json={
|
|
343
|
+
"encrypted_value": _encrypt_secret(public_key["key"], value),
|
|
344
|
+
"key_id": public_key["key_id"],
|
|
345
|
+
},
|
|
346
|
+
)
|
|
347
|
+
|
|
287
348
|
def pr_has_change(
|
|
288
349
|
self, pr_number: int, pred: Callable[[str], bool] = lambda _: True
|
|
289
350
|
) -> bool:
|
|
@@ -313,10 +374,6 @@ class Repository(GitHub):
|
|
|
313
374
|
:param issue_number: The number of the issue.
|
|
314
375
|
:param body: Body text of the new comment.
|
|
315
376
|
"""
|
|
316
|
-
if not isinstance(issue_number, int):
|
|
317
|
-
raise ValueError("An integer value is required for `issue_number`.")
|
|
318
|
-
if not isinstance(body, str):
|
|
319
|
-
raise ValueError("A string message is required for `body`.")
|
|
320
377
|
return self._post(
|
|
321
378
|
url=f"{self._url_issues}/{issue_number}/comments",
|
|
322
379
|
json={"body": body},
|
|
@@ -344,6 +401,12 @@ class RepositoryType(StrEnum):
|
|
|
344
401
|
PRIVATE = "private"
|
|
345
402
|
|
|
346
403
|
|
|
404
|
+
class SecretVisibility(StrEnum):
|
|
405
|
+
ALL = "all"
|
|
406
|
+
PRIVATE = "private"
|
|
407
|
+
SELECTED = "selected"
|
|
408
|
+
|
|
409
|
+
|
|
347
410
|
class Owner(GitHub, metaclass=ABCMeta):
|
|
348
411
|
"""An abstract owner class representing an organization or user."""
|
|
349
412
|
|
|
@@ -354,6 +417,7 @@ class Owner(GitHub, metaclass=ABCMeta):
|
|
|
354
417
|
"""
|
|
355
418
|
super().__init__(token)
|
|
356
419
|
self._owner = owner
|
|
420
|
+
self._url_owner = ""
|
|
357
421
|
self._url_repos = ""
|
|
358
422
|
self._url_create_repo = ""
|
|
359
423
|
|
|
@@ -376,6 +440,14 @@ class Owner(GitHub, metaclass=ABCMeta):
|
|
|
376
440
|
def create_repository(
|
|
377
441
|
self, name: str, description: str = "", private: bool = True, **kwargs
|
|
378
442
|
) -> dict[str, Any]:
|
|
443
|
+
"""Create a repository for this owner.
|
|
444
|
+
:param name: The name of the repository.
|
|
445
|
+
:param description: A short description of the repository.
|
|
446
|
+
:param private: Whether the repository is private.
|
|
447
|
+
:param kwargs: Additional keyword arguments forwarded to `_post`
|
|
448
|
+
(e.g. `params` or `raise_for_status`). Note `json` is already set
|
|
449
|
+
from the other parameters and must not be passed here.
|
|
450
|
+
"""
|
|
379
451
|
data = {
|
|
380
452
|
"name": name,
|
|
381
453
|
"description": description,
|
|
@@ -400,8 +472,9 @@ class User(Owner):
|
|
|
400
472
|
self._set_urls()
|
|
401
473
|
|
|
402
474
|
def _set_urls(self) -> None:
|
|
403
|
-
self.
|
|
404
|
-
self.
|
|
475
|
+
self._url_owner = f"{URL_API}/users/{self._owner}"
|
|
476
|
+
self._url_repos = f"{self._url_owner}/repos"
|
|
477
|
+
self._url_create_repo = f"{URL_API}/user/repos"
|
|
405
478
|
|
|
406
479
|
|
|
407
480
|
class Organization(Owner):
|
|
@@ -416,5 +489,54 @@ class Organization(Owner):
|
|
|
416
489
|
self._set_urls()
|
|
417
490
|
|
|
418
491
|
def _set_urls(self) -> None:
|
|
419
|
-
self.
|
|
492
|
+
self._url_owner = f"{URL_API}/orgs/{self._owner}"
|
|
493
|
+
self._url_repos = f"{self._url_owner}/repos"
|
|
420
494
|
self._url_create_repo = self._url_repos
|
|
495
|
+
self._url_secrets = f"{self._url_owner}/actions/secrets"
|
|
496
|
+
|
|
497
|
+
def delete_secret(self, name: str) -> requests.Response:
|
|
498
|
+
"""Delete an organization secret.
|
|
499
|
+
:param name: The name of the secret to delete.
|
|
500
|
+
"""
|
|
501
|
+
return self._delete(
|
|
502
|
+
url=f"{self._url_secrets}/{name}",
|
|
503
|
+
)
|
|
504
|
+
|
|
505
|
+
def get_secret_public_key(self) -> dict[str, Any]:
|
|
506
|
+
"""Get the public key for encrypting secrets in this organization."""
|
|
507
|
+
return self._get(url=f"{self._url_secrets}/public-key").json()
|
|
508
|
+
|
|
509
|
+
def create_or_update_secret(
|
|
510
|
+
self,
|
|
511
|
+
name: str,
|
|
512
|
+
value: str,
|
|
513
|
+
public_key: dict[str, Any],
|
|
514
|
+
visibility: SecretVisibility = SecretVisibility.ALL,
|
|
515
|
+
selected_repository_ids: Sequence[int] = (),
|
|
516
|
+
) -> requests.Response:
|
|
517
|
+
"""Create or update an organization secret.
|
|
518
|
+
:param name: The name of the secret.
|
|
519
|
+
:param value: The plaintext value of the secret.
|
|
520
|
+
:param public_key: A public key (as returned by `get_secret_public_key`)
|
|
521
|
+
to encrypt the secret with. Fetch it once and reuse it to avoid a
|
|
522
|
+
redundant request when creating or updating multiple secrets.
|
|
523
|
+
:param visibility: Which repositories can access the secret
|
|
524
|
+
(all, private, or selected).
|
|
525
|
+
:param selected_repository_ids: Repository IDs that can access the secret
|
|
526
|
+
when visibility is `selected`.
|
|
527
|
+
"""
|
|
528
|
+
if selected_repository_ids and visibility != SecretVisibility.SELECTED:
|
|
529
|
+
raise ValueError(
|
|
530
|
+
"`selected_repository_ids` can only be provided when `visibility` is 'selected'."
|
|
531
|
+
)
|
|
532
|
+
json: dict[str, Any] = {
|
|
533
|
+
"encrypted_value": _encrypt_secret(public_key["key"], value),
|
|
534
|
+
"key_id": public_key["key_id"],
|
|
535
|
+
"visibility": visibility,
|
|
536
|
+
}
|
|
537
|
+
if selected_repository_ids:
|
|
538
|
+
json["selected_repository_ids"] = list(selected_repository_ids)
|
|
539
|
+
return self._put(
|
|
540
|
+
url=f"{self._url_secrets}/{name}",
|
|
541
|
+
json=json,
|
|
542
|
+
)
|
{github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/github/add_github_repo.py
RENAMED
|
@@ -12,68 +12,6 @@ from dulwich import porcelain
|
|
|
12
12
|
from github_rest_api import User, Organization
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def parse_args(args=None, namespace=None):
|
|
16
|
-
parser = argparse.ArgumentParser(description="Add a GitHub repository.")
|
|
17
|
-
parser.add_argument(
|
|
18
|
-
"repo",
|
|
19
|
-
help="The GitHub repo (in the format of owner/repo) to be created.",
|
|
20
|
-
)
|
|
21
|
-
group = parser.add_mutually_exclusive_group(required=True)
|
|
22
|
-
group.add_argument(
|
|
23
|
-
"-u",
|
|
24
|
-
"--user",
|
|
25
|
-
dest="is_owner_user",
|
|
26
|
-
action="store_true",
|
|
27
|
-
help="The owner of the repo is a user.",
|
|
28
|
-
)
|
|
29
|
-
group.add_argument(
|
|
30
|
-
"-o",
|
|
31
|
-
"--org",
|
|
32
|
-
"--organization",
|
|
33
|
-
dest="is_owner_user",
|
|
34
|
-
action="store_false",
|
|
35
|
-
help="The owner of the repo is an organization.",
|
|
36
|
-
)
|
|
37
|
-
parser.add_argument(
|
|
38
|
-
"-t",
|
|
39
|
-
"--token",
|
|
40
|
-
dest="token",
|
|
41
|
-
default="",
|
|
42
|
-
help="The GitHub token to use.",
|
|
43
|
-
)
|
|
44
|
-
parser.add_argument(
|
|
45
|
-
"-p",
|
|
46
|
-
"--public",
|
|
47
|
-
dest="private",
|
|
48
|
-
action="store_false",
|
|
49
|
-
help="Whether to create the repository as public.",
|
|
50
|
-
)
|
|
51
|
-
parser.add_argument(
|
|
52
|
-
"-l",
|
|
53
|
-
"--lang",
|
|
54
|
-
"--language",
|
|
55
|
-
dest="language",
|
|
56
|
-
default="",
|
|
57
|
-
help="The language of the GitHub repository.",
|
|
58
|
-
)
|
|
59
|
-
parser.add_argument(
|
|
60
|
-
"-d",
|
|
61
|
-
"--dir",
|
|
62
|
-
dest="dir",
|
|
63
|
-
default="",
|
|
64
|
-
help="The directory (default to './repo') of the local Git repository.",
|
|
65
|
-
)
|
|
66
|
-
parser.add_argument(
|
|
67
|
-
"--branches",
|
|
68
|
-
dest="branches",
|
|
69
|
-
nargs="+",
|
|
70
|
-
default=["main"],
|
|
71
|
-
metavar="BRANCH",
|
|
72
|
-
help="Branches to create and push to remote (default: main).",
|
|
73
|
-
)
|
|
74
|
-
return parser.parse_args(args=args, namespace=namespace)
|
|
75
|
-
|
|
76
|
-
|
|
77
15
|
def _validate_repo(repo: str) -> None:
|
|
78
16
|
parts = repo.split("/")
|
|
79
17
|
if len(parts) != 2 or not parts[0] or not parts[1]:
|
|
@@ -93,8 +31,19 @@ def _create_remote_repo(
|
|
|
93
31
|
print(f"\nCreated the GitHub repo https://github.com/{repo}.\n")
|
|
94
32
|
|
|
95
33
|
|
|
34
|
+
def _remote_url(repo: str, protocol: str) -> str:
|
|
35
|
+
if protocol == "git":
|
|
36
|
+
return f"git@github.com:{repo}.git"
|
|
37
|
+
return f"https://github.com/{repo}.git"
|
|
38
|
+
|
|
39
|
+
|
|
96
40
|
def _init_local_repo(
|
|
97
|
-
repo: str,
|
|
41
|
+
repo: str,
|
|
42
|
+
language: str,
|
|
43
|
+
dir_: str,
|
|
44
|
+
token: str,
|
|
45
|
+
protocol: str,
|
|
46
|
+
branches: Sequence[str] = ("main",),
|
|
98
47
|
) -> None:
|
|
99
48
|
repo_name = repo.split("/")[-1]
|
|
100
49
|
path = Path(dir_) if dir_ else Path(repo_name)
|
|
@@ -104,6 +53,7 @@ def _init_local_repo(
|
|
|
104
53
|
readme.write_text(f"# {repo_name}\n")
|
|
105
54
|
if not (path / ".git").exists():
|
|
106
55
|
porcelain.init(path=path)
|
|
56
|
+
porcelain.remote_add(path, "origin", _remote_url(repo, protocol))
|
|
107
57
|
initial_branch = (
|
|
108
58
|
(path / ".git" / "HEAD").read_text().strip().partition("refs/heads/")[-1]
|
|
109
59
|
)
|
|
@@ -116,7 +66,7 @@ def _init_local_repo(
|
|
|
116
66
|
porcelain.checkout(repo=path, target=branch)
|
|
117
67
|
porcelain.push(
|
|
118
68
|
repo=path,
|
|
119
|
-
remote_location=
|
|
69
|
+
remote_location=_remote_url(repo, "https"),
|
|
120
70
|
username="x-access-token",
|
|
121
71
|
password=token,
|
|
122
72
|
)
|
|
@@ -136,6 +86,7 @@ def add_github_repo(
|
|
|
136
86
|
is_owner_user: bool,
|
|
137
87
|
dir_: str,
|
|
138
88
|
token: str,
|
|
89
|
+
protocol: str,
|
|
139
90
|
branches: Sequence[str] = ("main",),
|
|
140
91
|
) -> None:
|
|
141
92
|
token = token or os.getenv("GITHUB_TOKEN", "")
|
|
@@ -156,6 +107,7 @@ def add_github_repo(
|
|
|
156
107
|
dir_=dir_,
|
|
157
108
|
token=token,
|
|
158
109
|
branches=branches,
|
|
110
|
+
protocol=protocol,
|
|
159
111
|
)
|
|
160
112
|
|
|
161
113
|
|
|
@@ -177,6 +129,76 @@ def _add_workflow(path: Path, language: str, workflow_dir: Path | None = None) -
|
|
|
177
129
|
shutil.copy2(yaml, dir_dest)
|
|
178
130
|
|
|
179
131
|
|
|
132
|
+
def parse_args(args=None, namespace=None):
|
|
133
|
+
parser = argparse.ArgumentParser(description="Add a GitHub repository.")
|
|
134
|
+
parser.add_argument(
|
|
135
|
+
"repo",
|
|
136
|
+
help="The GitHub repo (in the format of owner/repo) to be created.",
|
|
137
|
+
)
|
|
138
|
+
group = parser.add_mutually_exclusive_group(required=True)
|
|
139
|
+
group.add_argument(
|
|
140
|
+
"-u",
|
|
141
|
+
"--user",
|
|
142
|
+
dest="is_owner_user",
|
|
143
|
+
action="store_true",
|
|
144
|
+
help="The owner of the repo is a user.",
|
|
145
|
+
)
|
|
146
|
+
group.add_argument(
|
|
147
|
+
"-o",
|
|
148
|
+
"--org",
|
|
149
|
+
"--organization",
|
|
150
|
+
dest="is_owner_user",
|
|
151
|
+
action="store_false",
|
|
152
|
+
help="The owner of the repo is an organization.",
|
|
153
|
+
)
|
|
154
|
+
parser.add_argument(
|
|
155
|
+
"-t",
|
|
156
|
+
"--token",
|
|
157
|
+
dest="token",
|
|
158
|
+
default="",
|
|
159
|
+
help="The GitHub token to use.",
|
|
160
|
+
)
|
|
161
|
+
parser.add_argument(
|
|
162
|
+
"-p",
|
|
163
|
+
"--public",
|
|
164
|
+
dest="private",
|
|
165
|
+
action="store_false",
|
|
166
|
+
help="Whether to create the repository as public.",
|
|
167
|
+
)
|
|
168
|
+
parser.add_argument(
|
|
169
|
+
"-l",
|
|
170
|
+
"--lang",
|
|
171
|
+
"--language",
|
|
172
|
+
dest="language",
|
|
173
|
+
default="",
|
|
174
|
+
help="The language of the GitHub repository.",
|
|
175
|
+
)
|
|
176
|
+
parser.add_argument(
|
|
177
|
+
"-d",
|
|
178
|
+
"--dir",
|
|
179
|
+
dest="dir",
|
|
180
|
+
default="",
|
|
181
|
+
help="The directory (default to './repo') of the local Git repository.",
|
|
182
|
+
)
|
|
183
|
+
parser.add_argument(
|
|
184
|
+
"--branches",
|
|
185
|
+
dest="branches",
|
|
186
|
+
nargs="+",
|
|
187
|
+
default=["main"],
|
|
188
|
+
metavar="BRANCH",
|
|
189
|
+
help="Branches to create and push to remote (default: main).",
|
|
190
|
+
)
|
|
191
|
+
parser.add_argument(
|
|
192
|
+
"--https",
|
|
193
|
+
dest="protocol",
|
|
194
|
+
action="store_const",
|
|
195
|
+
const="https",
|
|
196
|
+
default="git",
|
|
197
|
+
help="Use the HTTPS protocol for the remote URL.",
|
|
198
|
+
)
|
|
199
|
+
return parser.parse_args(args=args, namespace=namespace)
|
|
200
|
+
|
|
201
|
+
|
|
180
202
|
def main() -> int:
|
|
181
203
|
args = parse_args()
|
|
182
204
|
try:
|
|
@@ -188,6 +210,7 @@ def main() -> int:
|
|
|
188
210
|
dir_=args.dir,
|
|
189
211
|
token=args.token,
|
|
190
212
|
branches=args.branches,
|
|
213
|
+
protocol=args.protocol,
|
|
191
214
|
)
|
|
192
215
|
except Exception as e:
|
|
193
216
|
print(str(e), file=sys.stderr)
|
|
@@ -6,6 +6,7 @@ from argparse import ArgumentParser, Namespace
|
|
|
6
6
|
import os
|
|
7
7
|
import sys
|
|
8
8
|
from github_rest_api import Repository
|
|
9
|
+
from github_rest_api.utils import compile_patterns
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def parse_args(args=None, namespace=None) -> Namespace:
|
|
@@ -34,6 +35,19 @@ def parse_args(args=None, namespace=None) -> Namespace:
|
|
|
34
35
|
required=True,
|
|
35
36
|
help="The base branch to merge changes into.",
|
|
36
37
|
)
|
|
38
|
+
parser.add_argument(
|
|
39
|
+
"--ignore-patterns",
|
|
40
|
+
dest="ignore_patterns",
|
|
41
|
+
nargs="*",
|
|
42
|
+
default=["^_"],
|
|
43
|
+
help="A list of regular expression patterns. Branches matching any of these patterns will be ignored.",
|
|
44
|
+
)
|
|
45
|
+
parser.add_argument(
|
|
46
|
+
"--update",
|
|
47
|
+
dest="update",
|
|
48
|
+
action="store_true",
|
|
49
|
+
help="Update the head branch using the base branch before creating the pull request.",
|
|
50
|
+
)
|
|
37
51
|
return parser.parse_args(args=args, namespace=namespace)
|
|
38
52
|
|
|
39
53
|
|
|
@@ -43,10 +57,23 @@ def main() -> int:
|
|
|
43
57
|
The branch is updated (using dev) before creating the PR.
|
|
44
58
|
"""
|
|
45
59
|
args = parse_args()
|
|
46
|
-
# skip branches
|
|
47
|
-
|
|
48
|
-
|
|
60
|
+
# skip branches matching any of the ignore patterns
|
|
61
|
+
try:
|
|
62
|
+
compiled = compile_patterns(args.ignore_patterns)
|
|
63
|
+
except ValueError as e:
|
|
64
|
+
print(e, file=sys.stderr)
|
|
65
|
+
return 1
|
|
66
|
+
for pattern in compiled:
|
|
67
|
+
if pattern.search(args.head_branch):
|
|
68
|
+
print(
|
|
69
|
+
f"Branch '{args.head_branch}' matches ignore pattern '{
|
|
70
|
+
pattern.pattern
|
|
71
|
+
}', skipping."
|
|
72
|
+
)
|
|
73
|
+
return 0
|
|
49
74
|
repo = Repository(args.token, os.environ["GITHUB_REPOSITORY"])
|
|
75
|
+
if args.update:
|
|
76
|
+
repo.update_branch(update=args.head_branch, upstream=args.base_branch)
|
|
50
77
|
repo.create_pull_request(
|
|
51
78
|
{
|
|
52
79
|
"base": args.base_branch,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"""Some generally useful util functions."""
|
|
2
2
|
|
|
3
|
+
from collections.abc import Sequence
|
|
3
4
|
from itertools import tee, filterfalse
|
|
5
|
+
import re
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
def partition(pred, iterable):
|
|
@@ -12,6 +14,27 @@ def partition(pred, iterable):
|
|
|
12
14
|
return filter(pred, it1), filterfalse(pred, it2)
|
|
13
15
|
|
|
14
16
|
|
|
17
|
+
def compile_patterns(patterns: str | Sequence[str] | None) -> list[re.Pattern[str]]:
|
|
18
|
+
"""Compile a list of regular expression patterns.
|
|
19
|
+
|
|
20
|
+
:param patterns: A list of regular expression patterns to compile.
|
|
21
|
+
:return: A list of compiled regular expression patterns.
|
|
22
|
+
"""
|
|
23
|
+
if not patterns:
|
|
24
|
+
return []
|
|
25
|
+
if isinstance(patterns, str):
|
|
26
|
+
patterns = [patterns]
|
|
27
|
+
compiled = []
|
|
28
|
+
for pattern in patterns:
|
|
29
|
+
try:
|
|
30
|
+
compiled.append(re.compile(pattern))
|
|
31
|
+
except re.error as e:
|
|
32
|
+
raise ValueError(
|
|
33
|
+
f"Invalid regular expression pattern '{pattern}': {e}"
|
|
34
|
+
) from e
|
|
35
|
+
return compiled
|
|
36
|
+
|
|
37
|
+
|
|
15
38
|
def strip_patch_version(version: str) -> str:
|
|
16
39
|
"""Strip the patch version.
|
|
17
40
|
|
|
@@ -4,7 +4,7 @@ requires = [ "hatchling" ]
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "github-rest-api"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.41.0"
|
|
8
8
|
description = "Simple wrapper of GitHub REST APIs."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [ { name = "Ben Du", email = "longendu@yahoo.com" } ]
|
|
@@ -18,6 +18,7 @@ classifiers = [
|
|
|
18
18
|
dependencies = [
|
|
19
19
|
"dulwich>=0.25.1",
|
|
20
20
|
"psutil>=5.9.4",
|
|
21
|
+
"pynacl>=1.5",
|
|
21
22
|
"pyyaml>=6",
|
|
22
23
|
"requests>=2.28.2",
|
|
23
24
|
"tenacity>=9.1.4",
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import os
|
|
2
|
-
from
|
|
2
|
+
from base64 import b64decode
|
|
3
|
+
from nacl import encoding, public
|
|
4
|
+
from github_rest_api.github import User, Organization, Repository, _encrypt_secret
|
|
3
5
|
|
|
4
6
|
TOKEN = os.environ.get("GITHUB_TOKEN", "")
|
|
5
7
|
|
|
6
8
|
|
|
9
|
+
def test_encrypt_secret_roundtrip():
|
|
10
|
+
private_key = public.PrivateKey.generate()
|
|
11
|
+
public_key = private_key.public_key.encode(encoding.Base64Encoder).decode()
|
|
12
|
+
encrypted = _encrypt_secret(public_key, "s3cret-value")
|
|
13
|
+
decrypted = public.SealedBox(private_key).decrypt(b64decode(encrypted))
|
|
14
|
+
assert decrypted == b"s3cret-value"
|
|
15
|
+
|
|
16
|
+
|
|
7
17
|
def test_user_get_repositories():
|
|
8
18
|
user = User(TOKEN, "dclong")
|
|
9
19
|
repos = user.get_repositories()
|
|
@@ -11,6 +11,63 @@ wheels = [
|
|
|
11
11
|
{ url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" },
|
|
12
12
|
]
|
|
13
13
|
|
|
14
|
+
[[package]]
|
|
15
|
+
name = "cffi"
|
|
16
|
+
version = "2.0.0"
|
|
17
|
+
source = { registry = "https://pypi.org/simple" }
|
|
18
|
+
dependencies = [
|
|
19
|
+
{ name = "pycparser", marker = "implementation_name != 'PyPy'" },
|
|
20
|
+
]
|
|
21
|
+
sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" }
|
|
22
|
+
wheels = [
|
|
23
|
+
{ url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" },
|
|
24
|
+
{ url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" },
|
|
25
|
+
{ url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" },
|
|
26
|
+
{ url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" },
|
|
27
|
+
{ url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" },
|
|
28
|
+
{ url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" },
|
|
29
|
+
{ url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" },
|
|
30
|
+
{ url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" },
|
|
31
|
+
{ url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" },
|
|
32
|
+
{ url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" },
|
|
33
|
+
{ url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" },
|
|
34
|
+
{ url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" },
|
|
35
|
+
{ url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" },
|
|
36
|
+
{ url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" },
|
|
37
|
+
{ url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" },
|
|
38
|
+
{ url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" },
|
|
39
|
+
{ url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" },
|
|
40
|
+
{ url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" },
|
|
41
|
+
{ url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" },
|
|
42
|
+
{ url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" },
|
|
43
|
+
{ url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" },
|
|
44
|
+
{ url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" },
|
|
45
|
+
{ url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" },
|
|
46
|
+
{ url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" },
|
|
47
|
+
{ url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload-time = "2025-09-08T23:23:18.087Z" },
|
|
48
|
+
{ url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload-time = "2025-09-08T23:23:19.622Z" },
|
|
49
|
+
{ url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload-time = "2025-09-08T23:23:20.853Z" },
|
|
50
|
+
{ url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload-time = "2025-09-08T23:23:22.08Z" },
|
|
51
|
+
{ url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload-time = "2025-09-08T23:23:23.314Z" },
|
|
52
|
+
{ url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload-time = "2025-09-08T23:23:24.541Z" },
|
|
53
|
+
{ url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload-time = "2025-09-08T23:23:26.143Z" },
|
|
54
|
+
{ url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload-time = "2025-09-08T23:23:27.873Z" },
|
|
55
|
+
{ url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload-time = "2025-09-08T23:23:44.61Z" },
|
|
56
|
+
{ url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload-time = "2025-09-08T23:23:45.848Z" },
|
|
57
|
+
{ url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload-time = "2025-09-08T23:23:47.105Z" },
|
|
58
|
+
{ url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload-time = "2025-09-08T23:23:29.347Z" },
|
|
59
|
+
{ url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload-time = "2025-09-08T23:23:30.63Z" },
|
|
60
|
+
{ url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload-time = "2025-09-08T23:23:31.91Z" },
|
|
61
|
+
{ url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload-time = "2025-09-08T23:23:33.214Z" },
|
|
62
|
+
{ url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload-time = "2025-09-08T23:23:34.495Z" },
|
|
63
|
+
{ url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload-time = "2025-09-08T23:23:36.096Z" },
|
|
64
|
+
{ url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload-time = "2025-09-08T23:23:37.328Z" },
|
|
65
|
+
{ url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload-time = "2025-09-08T23:23:38.945Z" },
|
|
66
|
+
{ url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload-time = "2025-09-08T23:23:40.423Z" },
|
|
67
|
+
{ url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload-time = "2025-09-08T23:23:41.742Z" },
|
|
68
|
+
{ url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" },
|
|
69
|
+
]
|
|
70
|
+
|
|
14
71
|
[[package]]
|
|
15
72
|
name = "charset-normalizer"
|
|
16
73
|
version = "3.4.7"
|
|
@@ -166,11 +223,12 @@ wheels = [
|
|
|
166
223
|
|
|
167
224
|
[[package]]
|
|
168
225
|
name = "github-rest-api"
|
|
169
|
-
version = "0.
|
|
226
|
+
version = "0.40.0"
|
|
170
227
|
source = { editable = "." }
|
|
171
228
|
dependencies = [
|
|
172
229
|
{ name = "dulwich" },
|
|
173
230
|
{ name = "psutil" },
|
|
231
|
+
{ name = "pynacl" },
|
|
174
232
|
{ name = "pyyaml" },
|
|
175
233
|
{ name = "requests" },
|
|
176
234
|
{ name = "tenacity" },
|
|
@@ -191,6 +249,7 @@ dev = [
|
|
|
191
249
|
requires-dist = [
|
|
192
250
|
{ name = "dulwich", specifier = ">=0.25.1" },
|
|
193
251
|
{ name = "psutil", specifier = ">=5.9.4" },
|
|
252
|
+
{ name = "pynacl", specifier = ">=1.5" },
|
|
194
253
|
{ name = "pyyaml", specifier = ">=6" },
|
|
195
254
|
{ name = "requests", specifier = ">=2.28.2" },
|
|
196
255
|
{ name = "tenacity", specifier = ">=9.1.4" },
|
|
@@ -280,6 +339,15 @@ wheels = [
|
|
|
280
339
|
{ url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" },
|
|
281
340
|
]
|
|
282
341
|
|
|
342
|
+
[[package]]
|
|
343
|
+
name = "pycparser"
|
|
344
|
+
version = "3.0"
|
|
345
|
+
source = { registry = "https://pypi.org/simple" }
|
|
346
|
+
sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" }
|
|
347
|
+
wheels = [
|
|
348
|
+
{ url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" },
|
|
349
|
+
]
|
|
350
|
+
|
|
283
351
|
[[package]]
|
|
284
352
|
name = "pygments"
|
|
285
353
|
version = "2.20.0"
|
|
@@ -289,6 +357,41 @@ wheels = [
|
|
|
289
357
|
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
|
|
290
358
|
]
|
|
291
359
|
|
|
360
|
+
[[package]]
|
|
361
|
+
name = "pynacl"
|
|
362
|
+
version = "1.6.2"
|
|
363
|
+
source = { registry = "https://pypi.org/simple" }
|
|
364
|
+
dependencies = [
|
|
365
|
+
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
|
366
|
+
]
|
|
367
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d9/9a/4019b524b03a13438637b11538c82781a5eda427394380381af8f04f467a/pynacl-1.6.2.tar.gz", hash = "sha256:018494d6d696ae03c7e656e5e74cdfd8ea1326962cc401bcf018f1ed8436811c", size = 3511692, upload-time = "2026-01-01T17:48:10.851Z" }
|
|
368
|
+
wheels = [
|
|
369
|
+
{ url = "https://files.pythonhosted.org/packages/4b/79/0e3c34dc3c4671f67d251c07aa8eb100916f250ee470df230b0ab89551b4/pynacl-1.6.2-cp314-cp314t-macosx_10_10_universal2.whl", hash = "sha256:622d7b07cc5c02c666795792931b50c91f3ce3c2649762efb1ef0d5684c81594", size = 390064, upload-time = "2026-01-01T17:31:57.264Z" },
|
|
370
|
+
{ url = "https://files.pythonhosted.org/packages/eb/1c/23a26e931736e13b16483795c8a6b2f641bf6a3d5238c22b070a5112722c/pynacl-1.6.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d071c6a9a4c94d79eb665db4ce5cedc537faf74f2355e4d502591d850d3913c0", size = 809370, upload-time = "2026-01-01T17:31:59.198Z" },
|
|
371
|
+
{ url = "https://files.pythonhosted.org/packages/87/74/8d4b718f8a22aea9e8dcc8b95deb76d4aae380e2f5b570cc70b5fd0a852d/pynacl-1.6.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe9847ca47d287af41e82be1dd5e23023d3c31a951da134121ab02e42ac218c9", size = 1408304, upload-time = "2026-01-01T17:32:01.162Z" },
|
|
372
|
+
{ url = "https://files.pythonhosted.org/packages/fd/73/be4fdd3a6a87fe8a4553380c2b47fbd1f7f58292eb820902f5c8ac7de7b0/pynacl-1.6.2-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:04316d1fc625d860b6c162fff704eb8426b1a8bcd3abacea11142cbd99a6b574", size = 844871, upload-time = "2026-01-01T17:32:02.824Z" },
|
|
373
|
+
{ url = "https://files.pythonhosted.org/packages/55/ad/6efc57ab75ee4422e96b5f2697d51bbcf6cdcc091e66310df91fbdc144a8/pynacl-1.6.2-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44081faff368d6c5553ccf55322ef2819abb40e25afaec7e740f159f74813634", size = 1446356, upload-time = "2026-01-01T17:32:04.452Z" },
|
|
374
|
+
{ url = "https://files.pythonhosted.org/packages/78/b7/928ee9c4779caa0a915844311ab9fb5f99585621c5d6e4574538a17dca07/pynacl-1.6.2-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:a9f9932d8d2811ce1a8ffa79dcbdf3970e7355b5c8eb0c1a881a57e7f7d96e88", size = 826814, upload-time = "2026-01-01T17:32:06.078Z" },
|
|
375
|
+
{ url = "https://files.pythonhosted.org/packages/f7/a9/1bdba746a2be20f8809fee75c10e3159d75864ef69c6b0dd168fc60e485d/pynacl-1.6.2-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:bc4a36b28dd72fb4845e5d8f9760610588a96d5a51f01d84d8c6ff9849968c14", size = 1411742, upload-time = "2026-01-01T17:32:07.651Z" },
|
|
376
|
+
{ url = "https://files.pythonhosted.org/packages/f3/2f/5e7ea8d85f9f3ea5b6b87db1d8388daa3587eed181bdeb0306816fdbbe79/pynacl-1.6.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3bffb6d0f6becacb6526f8f42adfb5efb26337056ee0831fb9a7044d1a964444", size = 801714, upload-time = "2026-01-01T17:32:09.558Z" },
|
|
377
|
+
{ url = "https://files.pythonhosted.org/packages/06/ea/43fe2f7eab5f200e40fb10d305bf6f87ea31b3bbc83443eac37cd34a9e1e/pynacl-1.6.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2fef529ef3ee487ad8113d287a593fa26f48ee3620d92ecc6f1d09ea38e0709b", size = 1372257, upload-time = "2026-01-01T17:32:11.026Z" },
|
|
378
|
+
{ url = "https://files.pythonhosted.org/packages/4d/54/c9ea116412788629b1347e415f72195c25eb2f3809b2d3e7b25f5c79f13a/pynacl-1.6.2-cp314-cp314t-win32.whl", hash = "sha256:a84bf1c20339d06dc0c85d9aea9637a24f718f375d861b2668b2f9f96fa51145", size = 231319, upload-time = "2026-01-01T17:32:12.46Z" },
|
|
379
|
+
{ url = "https://files.pythonhosted.org/packages/ce/04/64e9d76646abac2dccf904fccba352a86e7d172647557f35b9fe2a5ee4a1/pynacl-1.6.2-cp314-cp314t-win_amd64.whl", hash = "sha256:320ef68a41c87547c91a8b58903c9caa641ab01e8512ce291085b5fe2fcb7590", size = 244044, upload-time = "2026-01-01T17:32:13.781Z" },
|
|
380
|
+
{ url = "https://files.pythonhosted.org/packages/33/33/7873dc161c6a06f43cda13dec67b6fe152cb2f982581151956fa5e5cdb47/pynacl-1.6.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d29bfe37e20e015a7d8b23cfc8bd6aa7909c92a1b8f41ee416bbb3e79ef182b2", size = 188740, upload-time = "2026-01-01T17:32:15.083Z" },
|
|
381
|
+
{ url = "https://files.pythonhosted.org/packages/be/7b/4845bbf88e94586ec47a432da4e9107e3fc3ce37eb412b1398630a37f7dd/pynacl-1.6.2-cp38-abi3-macosx_10_10_universal2.whl", hash = "sha256:c949ea47e4206af7c8f604b8278093b674f7c79ed0d4719cc836902bf4517465", size = 388458, upload-time = "2026-01-01T17:32:16.829Z" },
|
|
382
|
+
{ url = "https://files.pythonhosted.org/packages/1e/b4/e927e0653ba63b02a4ca5b4d852a8d1d678afbf69b3dbf9c4d0785ac905c/pynacl-1.6.2-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8845c0631c0be43abdd865511c41eab235e0be69c81dc66a50911594198679b0", size = 800020, upload-time = "2026-01-01T17:32:18.34Z" },
|
|
383
|
+
{ url = "https://files.pythonhosted.org/packages/7f/81/d60984052df5c97b1d24365bc1e30024379b42c4edcd79d2436b1b9806f2/pynacl-1.6.2-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:22de65bb9010a725b0dac248f353bb072969c94fa8d6b1f34b87d7953cf7bbe4", size = 1399174, upload-time = "2026-01-01T17:32:20.239Z" },
|
|
384
|
+
{ url = "https://files.pythonhosted.org/packages/68/f7/322f2f9915c4ef27d140101dd0ed26b479f7e6f5f183590fd32dfc48c4d3/pynacl-1.6.2-cp38-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:46065496ab748469cdd999246d17e301b2c24ae2fdf739132e580a0e94c94a87", size = 835085, upload-time = "2026-01-01T17:32:22.24Z" },
|
|
385
|
+
{ url = "https://files.pythonhosted.org/packages/3e/d0/f301f83ac8dbe53442c5a43f6a39016f94f754d7a9815a875b65e218a307/pynacl-1.6.2-cp38-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a66d6fb6ae7661c58995f9c6435bda2b1e68b54b598a6a10247bfcdadac996c", size = 1437614, upload-time = "2026-01-01T17:32:23.766Z" },
|
|
386
|
+
{ url = "https://files.pythonhosted.org/packages/c4/58/fc6e649762b029315325ace1a8c6be66125e42f67416d3dbd47b69563d61/pynacl-1.6.2-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:26bfcd00dcf2cf160f122186af731ae30ab120c18e8375684ec2670dccd28130", size = 818251, upload-time = "2026-01-01T17:32:25.69Z" },
|
|
387
|
+
{ url = "https://files.pythonhosted.org/packages/c9/a8/b917096b1accc9acd878819a49d3d84875731a41eb665f6ebc826b1af99e/pynacl-1.6.2-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c8a231e36ec2cab018c4ad4358c386e36eede0319a0c41fed24f840b1dac59f6", size = 1402859, upload-time = "2026-01-01T17:32:27.215Z" },
|
|
388
|
+
{ url = "https://files.pythonhosted.org/packages/85/42/fe60b5f4473e12c72f977548e4028156f4d340b884c635ec6b063fe7e9a5/pynacl-1.6.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:68be3a09455743ff9505491220b64440ced8973fe930f270c8e07ccfa25b1f9e", size = 791926, upload-time = "2026-01-01T17:32:29.314Z" },
|
|
389
|
+
{ url = "https://files.pythonhosted.org/packages/fa/f9/e40e318c604259301cc091a2a63f237d9e7b424c4851cafaea4ea7c4834e/pynacl-1.6.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8b097553b380236d51ed11356c953bf8ce36a29a3e596e934ecabe76c985a577", size = 1363101, upload-time = "2026-01-01T17:32:31.263Z" },
|
|
390
|
+
{ url = "https://files.pythonhosted.org/packages/48/47/e761c254f410c023a469284a9bc210933e18588ca87706ae93002c05114c/pynacl-1.6.2-cp38-abi3-win32.whl", hash = "sha256:5811c72b473b2f38f7e2a3dc4f8642e3a3e9b5e7317266e4ced1fba85cae41aa", size = 227421, upload-time = "2026-01-01T17:32:33.076Z" },
|
|
391
|
+
{ url = "https://files.pythonhosted.org/packages/41/ad/334600e8cacc7d86587fe5f565480fde569dfb487389c8e1be56ac21d8ac/pynacl-1.6.2-cp38-abi3-win_amd64.whl", hash = "sha256:62985f233210dee6548c223301b6c25440852e13d59a8b81490203c3227c5ba0", size = 239754, upload-time = "2026-01-01T17:32:34.557Z" },
|
|
392
|
+
{ url = "https://files.pythonhosted.org/packages/29/7d/5945b5af29534641820d3bd7b00962abbbdfee84ec7e19f0d5b3175f9a31/pynacl-1.6.2-cp38-abi3-win_arm64.whl", hash = "sha256:834a43af110f743a754448463e8fd61259cd4ab5bbedcf70f9dabad1d28a394c", size = 184801, upload-time = "2026-01-01T17:32:36.309Z" },
|
|
393
|
+
]
|
|
394
|
+
|
|
292
395
|
[[package]]
|
|
293
396
|
name = "pyproject-fmt"
|
|
294
397
|
version = "2.21.1"
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
You have my permissions to
|
|
2
|
-
|
|
3
|
-
- read any file on the machine if it's readable to the current user
|
|
4
|
-
- make changes to files under this project only
|
|
5
|
-
- to create and/or remove temporary files under this project only
|
|
6
|
-
- to run shell command `uv`, `fish -n` and `fish_indent` to lint or test Python and fish scripts
|
|
7
|
-
- to run the shell commands which does NOT change any files
|
|
8
|
-
|
|
9
|
-
However,
|
|
10
|
-
please do NOT commit changes so that I can review the diff locally.
|
|
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
|
{github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/cargo/benchmark.py
RENAMED
|
File without changes
|
{github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/cargo/profiling.py
RENAMED
|
File without changes
|
|
File without changes
|
{github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/container/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/github/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{github_rest_api-0.39.1 → github_rest_api-0.41.0}/github_rest_api/scripts/github/remove_branch.py
RENAMED
|
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
|