imbi-plugin-github 2.34.0__py3-none-any.whl → 2.35.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.
- imbi/plugins/github/commits.py +27 -22
- imbi/plugins/github/pull_requests.py +9 -8
- {imbi_plugin_github-2.34.0.dist-info → imbi_plugin_github-2.35.0.dist-info}/METADATA +2 -2
- {imbi_plugin_github-2.34.0.dist-info → imbi_plugin_github-2.35.0.dist-info}/RECORD +5 -5
- {imbi_plugin_github-2.34.0.dist-info → imbi_plugin_github-2.35.0.dist-info}/WHEEL +0 -0
imbi/plugins/github/commits.py
CHANGED
|
@@ -19,11 +19,11 @@ backfill: there is no push payload, so the GitHub host is read from
|
|
|
19
19
|
it walks the full default-branch history and the complete tag list rather
|
|
20
20
|
than a single push delta.
|
|
21
21
|
|
|
22
|
-
Commit / tag rows are
|
|
23
|
-
``tags``
|
|
24
|
-
best-effort: a
|
|
25
|
-
hiccup never 5xxs the webhook,
|
|
26
|
-
recording behaves.
|
|
22
|
+
Commit / tag rows are published via :func:`imbi.common.iggy.publish` to
|
|
23
|
+
the ``commits`` / ``tags`` streams, which the ClickHouse sink drains into
|
|
24
|
+
the tables of the same name. Writes are best-effort: a publish failure is
|
|
25
|
+
logged and swallowed so an analytics hiccup never 5xxs the webhook,
|
|
26
|
+
exactly as the gateway's own event recording behaves.
|
|
27
27
|
"""
|
|
28
28
|
|
|
29
29
|
from __future__ import annotations
|
|
@@ -40,7 +40,7 @@ import httpx
|
|
|
40
40
|
import jsonpointer
|
|
41
41
|
import pydantic
|
|
42
42
|
|
|
43
|
-
from imbi.common import cache, clickhouse
|
|
43
|
+
from imbi.common import cache, clickhouse, iggy
|
|
44
44
|
from imbi.common.json_pointer import JsonPointer
|
|
45
45
|
from imbi.common.models import CommitRecord, TagRecord
|
|
46
46
|
from imbi.common.plugins.base import (
|
|
@@ -67,6 +67,9 @@ from imbi.plugins.github.deployment import (
|
|
|
67
67
|
|
|
68
68
|
LOGGER = logging.getLogger(__name__)
|
|
69
69
|
|
|
70
|
+
#: The Iggy topic every row this plugin publishes goes to.
|
|
71
|
+
_TOPIC = 'github'
|
|
72
|
+
|
|
70
73
|
_HTTP_TIMEOUT_SECONDS = 10.0
|
|
71
74
|
_ZERO_SHA = '0' * 40
|
|
72
75
|
# GitHub's compare endpoint caps ``commits[]`` at 250 per page and
|
|
@@ -903,25 +906,26 @@ async def _fetch_commits_since(
|
|
|
903
906
|
return out
|
|
904
907
|
|
|
905
908
|
|
|
906
|
-
async def
|
|
907
|
-
|
|
909
|
+
async def _publish_best_effort(
|
|
910
|
+
stream: str, records: list[pydantic.BaseModel], project_id: str
|
|
908
911
|
) -> int:
|
|
909
|
-
"""
|
|
912
|
+
"""Publish ``records`` to ``stream``; return rows sent (0 on fail).
|
|
910
913
|
|
|
911
|
-
|
|
912
|
-
|
|
914
|
+
The stream is named for the ClickHouse table the sink lands it in.
|
|
915
|
+
``imbi.common.iggy.publish`` rejects an empty list, so an empty set
|
|
916
|
+
short-circuits to 0. A publish failure is logged and swallowed,
|
|
913
917
|
mirroring the webhook actions -- an analytics hiccup must not fail the
|
|
914
918
|
sync.
|
|
915
919
|
"""
|
|
916
920
|
if not records:
|
|
917
921
|
return 0
|
|
918
922
|
try:
|
|
919
|
-
await
|
|
923
|
+
await iggy.publish(stream, _TOPIC, records)
|
|
920
924
|
except Exception:
|
|
921
925
|
LOGGER.exception(
|
|
922
926
|
'github-commit-sync: failed to record %d %s rows for project %s',
|
|
923
927
|
len(records),
|
|
924
|
-
|
|
928
|
+
stream,
|
|
925
929
|
project_id,
|
|
926
930
|
)
|
|
927
931
|
return 0
|
|
@@ -1094,7 +1098,7 @@ async def sync_commits(
|
|
|
1094
1098
|
if not records:
|
|
1095
1099
|
return
|
|
1096
1100
|
try:
|
|
1097
|
-
await
|
|
1101
|
+
await iggy.publish('commits', _TOPIC, records)
|
|
1098
1102
|
except Exception:
|
|
1099
1103
|
LOGGER.exception(
|
|
1100
1104
|
'github-commit-sync: failed to record %d commits for project %s',
|
|
@@ -1464,7 +1468,7 @@ async def sync_tags(
|
|
|
1464
1468
|
if not records:
|
|
1465
1469
|
return # every tag in this delivery was unpeelable (warned above)
|
|
1466
1470
|
try:
|
|
1467
|
-
await
|
|
1471
|
+
await iggy.publish('tags', _TOPIC, records)
|
|
1468
1472
|
except Exception:
|
|
1469
1473
|
LOGGER.exception(
|
|
1470
1474
|
'github-commit-sync: failed to record %d tags for project %s',
|
|
@@ -1478,7 +1482,8 @@ sync_commits_descriptor = ActionDescriptor(
|
|
|
1478
1482
|
label='Sync Commit History',
|
|
1479
1483
|
description=(
|
|
1480
1484
|
'Fetch the full set of commits in a push (via the GitHub compare '
|
|
1481
|
-
'API) and
|
|
1485
|
+
'API) and publish them to the stream that lands in the ClickHouse '
|
|
1486
|
+
'commits table.'
|
|
1482
1487
|
),
|
|
1483
1488
|
callable=typing.cast(
|
|
1484
1489
|
'typing.Any', 'imbi.plugins.github.commits:sync_commits'
|
|
@@ -1492,8 +1497,8 @@ sync_tags_descriptor = ActionDescriptor(
|
|
|
1492
1497
|
name='sync_tags',
|
|
1493
1498
|
label='Sync Tag History',
|
|
1494
1499
|
description=(
|
|
1495
|
-
'
|
|
1496
|
-
'tag list) in the ClickHouse tags table.'
|
|
1500
|
+
'Publish the pushed tag (and, when reconcile_all is set, the full '
|
|
1501
|
+
'tag list) to the stream that lands in the ClickHouse tags table.'
|
|
1497
1502
|
),
|
|
1498
1503
|
callable=typing.cast(
|
|
1499
1504
|
'typing.Any', 'imbi.plugins.github.commits:sync_tags'
|
|
@@ -1625,10 +1630,10 @@ class GitHubCommitSync(CommitSyncCapability):
|
|
|
1625
1630
|
for item in raw_commits
|
|
1626
1631
|
if item.get('sha')
|
|
1627
1632
|
]
|
|
1628
|
-
commits_recorded = await
|
|
1633
|
+
commits_recorded = await _publish_best_effort(
|
|
1629
1634
|
'commits', commit_records, ctx.project_id
|
|
1630
1635
|
)
|
|
1631
|
-
tags_recorded = await
|
|
1636
|
+
tags_recorded = await _publish_best_effort(
|
|
1632
1637
|
'tags', list(tags), ctx.project_id
|
|
1633
1638
|
)
|
|
1634
1639
|
return commits_recorded, tags_recorded
|
|
@@ -1724,7 +1729,7 @@ class GitHubCommitSync(CommitSyncCapability):
|
|
|
1724
1729
|
)
|
|
1725
1730
|
if record is None:
|
|
1726
1731
|
return 0 # unpeelable (warned by _tag_record)
|
|
1727
|
-
return await
|
|
1732
|
+
return await _publish_best_effort('tags', [record], ctx.project_id)
|
|
1728
1733
|
|
|
1729
1734
|
async def sync_new_commits(
|
|
1730
1735
|
self,
|
|
@@ -1791,7 +1796,7 @@ class GitHubCommitSync(CommitSyncCapability):
|
|
|
1791
1796
|
for item in raw
|
|
1792
1797
|
if item.get('sha')
|
|
1793
1798
|
]
|
|
1794
|
-
return await
|
|
1799
|
+
return await _publish_best_effort('commits', records, ctx.project_id)
|
|
1795
1800
|
|
|
1796
1801
|
async def _fetch_new_commits(
|
|
1797
1802
|
self,
|
|
@@ -13,10 +13,11 @@ GitHub's list-PRs API omits per-file diff stats
|
|
|
13
13
|
(``additions``/``deletions``/``changed_files``), so backfill rows
|
|
14
14
|
store ``0`` for those fields; they are accurate on webhook-driven rows.
|
|
15
15
|
|
|
16
|
-
PR rows are
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
webhook, exactly as the
|
|
16
|
+
PR rows are published via :func:`imbi.common.iggy.publish` to the
|
|
17
|
+
``pull_requests`` stream, which the ClickHouse sink drains into the table
|
|
18
|
+
of the same name. Writes are best-effort: a publish failure is logged and
|
|
19
|
+
swallowed so an analytics hiccup never 5xxs the webhook, exactly as the
|
|
20
|
+
gateway's own event recording behaves.
|
|
20
21
|
"""
|
|
21
22
|
|
|
22
23
|
from __future__ import annotations
|
|
@@ -29,7 +30,7 @@ import httpx
|
|
|
29
30
|
import jsonpointer
|
|
30
31
|
import pydantic
|
|
31
32
|
|
|
32
|
-
from imbi.common import
|
|
33
|
+
from imbi.common import iggy
|
|
33
34
|
from imbi.common.json_pointer import JsonPointer
|
|
34
35
|
from imbi.common.models import PullRequestRecord
|
|
35
36
|
from imbi.common.plugins.base import (
|
|
@@ -43,7 +44,7 @@ from imbi.plugins.github._repos import resolve_owner_repo
|
|
|
43
44
|
from imbi.plugins.github.commits import (
|
|
44
45
|
_BACKFILL_MAX_WAIT_SECONDS, # pyright: ignore[reportPrivateUsage]
|
|
45
46
|
_client, # pyright: ignore[reportPrivateUsage]
|
|
46
|
-
|
|
47
|
+
_publish_best_effort, # pyright: ignore[reportPrivateUsage]
|
|
47
48
|
_request, # pyright: ignore[reportPrivateUsage]
|
|
48
49
|
_resolve, # pyright: ignore[reportPrivateUsage]
|
|
49
50
|
_resolve_bearer, # pyright: ignore[reportPrivateUsage]
|
|
@@ -237,7 +238,7 @@ async def sync_pull_requests(
|
|
|
237
238
|
)
|
|
238
239
|
return
|
|
239
240
|
try:
|
|
240
|
-
await
|
|
241
|
+
await iggy.publish('pull_requests', 'github', [record])
|
|
241
242
|
except Exception:
|
|
242
243
|
LOGGER.exception(
|
|
243
244
|
'github-pr-sync: failed to record PR #%d for project %s',
|
|
@@ -356,6 +357,6 @@ class GitHubPullRequestSync(PullRequestSyncCapability):
|
|
|
356
357
|
record = _pr_record(pr, project_id=ctx.project_id)
|
|
357
358
|
if record is not None:
|
|
358
359
|
records.append(record)
|
|
359
|
-
return await
|
|
360
|
+
return await _publish_best_effort(
|
|
360
361
|
'pull_requests', records, ctx.project_id
|
|
361
362
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: imbi-plugin-github
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.35.0
|
|
4
4
|
Summary: GitHub identity plugin for Imbi (github.com / GHEC / GHES)
|
|
5
5
|
Author-email: "Gavin M. Roy" <gavinr@aweber.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.14
|
|
13
13
|
Requires-Python: >=3.14
|
|
14
14
|
Requires-Dist: httpx>=0.27
|
|
15
|
-
Requires-Dist: imbi-common[databases]==2.
|
|
15
|
+
Requires-Dist: imbi-common[databases]==2.35.0
|
|
16
16
|
Requires-Dist: pydantic>=2
|
|
17
17
|
Requires-Dist: pyjwt[crypto]>=2.8
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
@@ -3,14 +3,14 @@ imbi/plugins/github/__init__.py,sha256=L_5_kr22VkjJob6SVLVzCkIvnWddxi54GIrM2cNs2
|
|
|
3
3
|
imbi/plugins/github/_app_auth.py,sha256=Fte_3Tohxw6xBl1U2AB3uatVfTxfl9xPEc8M0lmVCpc,18420
|
|
4
4
|
imbi/plugins/github/_hosts.py,sha256=sYuE3f7934125VZ6GGTqm8t3sVa3m0DNt3jL9Hb8nM0,4014
|
|
5
5
|
imbi/plugins/github/_repos.py,sha256=BeSwrpzQnFBtlUGW-eP7v6_gAcSaSkqObq-vhj5wcYA,6575
|
|
6
|
-
imbi/plugins/github/commits.py,sha256=
|
|
6
|
+
imbi/plugins/github/commits.py,sha256=wHs_NUl4cmhfvD3WrnOCmqaaJS-Eku-E-lOMh6Cb8IU,71882
|
|
7
7
|
imbi/plugins/github/deployment.py,sha256=sx7xyK7MbOCXgt52RcHvsaNJ2aA9fMCNYZBUdRbsTbA,110360
|
|
8
8
|
imbi/plugins/github/doctor.py,sha256=9pSXnpMTihhBrJ6OsLFFq2V6mpyqRRnvG1U94RL79L4,27156
|
|
9
9
|
imbi/plugins/github/identity.py,sha256=9t_e-_jUbQ1iL0Vb6vaK2d7bT1ki6pw9aWwc4ics6gI,10354
|
|
10
10
|
imbi/plugins/github/lifecycle.py,sha256=KJSzB36zFqetQBY5HNXLsRGRoIwGhrBJ-I1mA8G9H_Q,37711
|
|
11
11
|
imbi/plugins/github/plugin.py,sha256=V1BzHPR5a0gGr1ttSqo_yTVdK5ShKs26AcReX2N-eOg,15531
|
|
12
|
-
imbi/plugins/github/pull_requests.py,sha256=
|
|
12
|
+
imbi/plugins/github/pull_requests.py,sha256=FiHbjdGqghJ2Q1--d15XfOtpUe_KZE7hYRb8JLQ5U1I,13510
|
|
13
13
|
imbi/plugins/github/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
-
imbi_plugin_github-2.
|
|
15
|
-
imbi_plugin_github-2.
|
|
16
|
-
imbi_plugin_github-2.
|
|
14
|
+
imbi_plugin_github-2.35.0.dist-info/METADATA,sha256=D5Tl4UHk3dD8dD1PeBAP9Bh2NTm0wkGD5bSKpsUjp2E,7618
|
|
15
|
+
imbi_plugin_github-2.35.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
16
|
+
imbi_plugin_github-2.35.0.dist-info/RECORD,,
|
|
File without changes
|