github-overlord 0.6.9__tar.gz → 0.7.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: github-overlord
3
- Version: 0.6.9
3
+ Version: 0.7.0
4
4
  Summary: Automatically merge Dependabot PRs in public repositories
5
5
  Home-page: https://github.com/iloveitaly/github-overlord
6
6
  Keywords: github,dependabot,automation
@@ -13,10 +13,10 @@ Classifier: Programming Language :: Python :: 3.12
13
13
  Requires-Dist: apscheduler (>=3.10.4,<4.0.0)
14
14
  Requires-Dist: click (>=8.1.7,<9.0.0)
15
15
  Requires-Dist: funcy-pipe (>=0.11.0,<0.12.0)
16
- Requires-Dist: openai (>=1.35.3,<2.0.0)
16
+ Requires-Dist: openai (>=1.37.1,<2.0.0)
17
17
  Requires-Dist: pygithub (>=2.3.0,<3.0.0)
18
18
  Requires-Dist: python-decouple-typed (>=3.11.0,<4.0.0)
19
- Requires-Dist: structlog (>=24.2.0,<25.0.0)
19
+ Requires-Dist: structlog (>=24.4.0,<25.0.0)
20
20
  Description-Content-Type: text/markdown
21
21
 
22
22
  [![Release Notes](https://img.shields.io/github/release/iloveitaly/github-overlord)](https://github.com/iloveitaly/github-overlord/releases) [![Downloads](https://static.pepy.tech/badge/github-overlord/month)](https://pepy.tech/project/github-overlord) [![Python Versions](https://img.shields.io/pypi/pyversions/github-overlord)](https://pypi.org/project/github-overlord) ![GitHub CI Status](https://github.com/iloveitaly/github-overlord/actions/workflows/build_and_publish.yml/badge.svg) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -5,6 +5,7 @@ from types import NoneType
5
5
 
6
6
  import click
7
7
  import funcy_pipe as fp
8
+ import funcy as f
8
9
  from github import Github
9
10
  from github.GithubObject import NotSet
10
11
  from github.Notification import Notification
@@ -244,26 +245,82 @@ def keep_alive_prs(token, dry_run, repo):
244
245
  log.info("stale PR check complete")
245
246
 
246
247
 
247
- def notifications(token, dry_run):
248
+ @click.command()
249
+ @click.option(
250
+ "--token",
251
+ help="GitHub token, can also be set via GITHUB_TOKEN",
252
+ default=os.getenv("GITHUB_TOKEN"),
253
+ )
254
+ # TODO move this into the parent command
255
+ @click.option("--dry-run", is_flag=True, help="Run script without merging PRs")
256
+ @click.option(
257
+ "--only-unread", is_flag=True, help="Only process a single repository", default=True
258
+ )
259
+ def notifications(token, dry_run, only_unread):
248
260
  """
249
261
  Look at notifications and mark them as read if they are dependabot notifications
262
+
263
+ * Dependabot notifications
264
+ * Releases on repos I own
265
+ * Closed (merged, closed) pull requests on repos I own
266
+ * Closed pull requests that I authored
250
267
  """
251
268
 
252
- g = Github(token)
253
- user = g.get_user()
254
- notifications = user.get_notifications()
269
+ github = Github(token)
270
+ user = github.get_user()
271
+ login = user.login
272
+
273
+ # all includes read notifications AND done notifications :/
274
+ # there is no way to determine if a notification is marked as done
275
+ notifications = list(user.get_notifications(all=not only_unread))
276
+
277
+ # TODO fix funcy_pipe here
278
+ released_on_owned_repos = (
279
+ notifications
280
+ | fp.filter(
281
+ lambda n: n.subject.type == "Release"
282
+ and n.repository.owner.login == login
283
+ # TODO I think there is a way to convert the instance method to a standard method so it could be mapped
284
+ # patchy had some code for this
285
+ )
286
+ | fp.map(lambda n: n.mark_as_done())
287
+ | fp.to_list()
288
+ )
289
+
290
+ def is_dependabot_notification(notification: Notification) -> bool:
291
+ return notification.get_pull_request().user.login == "dependabot[bot]"
292
+
293
+ def is_pull_request(notification: Notification) -> bool:
294
+ return notification.subject.type == "PullRequest"
255
295
 
256
- def handle_notification(notification: Notification):
257
- pass
296
+ def is_pull_request_open(notification: Notification) -> bool:
297
+ return notification.get_pull_request().state == "open"
258
298
 
259
- # for notification in notifications:
260
- # print(f"Notification: {notification.subject['title']}, Reason: {notification.reason}")
261
- # if not read_only:
262
- # notification.mark_as_read()
299
+ # TODO github digest has some logic to detect bots, maybev we can use that
300
+ pull_requests_by_dependabot = (
301
+ notifications
302
+ | fp.filter(is_pull_request)
303
+ | fp.filter(is_dependabot_notification)
304
+ | fp.map(Notification.mark_as_done)
305
+ | fp.to_list()
306
+ )
307
+
308
+ # Closed (merged, closed) pull requests that I authored
309
+ owned_closed_pull_requests = (
310
+ notifications
311
+ # PRs that I did not author may still be interesting
312
+ | fp.where_attr(reason="author")
313
+ | fp.filter(is_pull_request)
314
+ # TODO should use `fp`
315
+ | fp.filter(f.complement(is_pull_request_open))
316
+ | fp.map(Notification.mark_as_done)
317
+ | fp.to_list()
318
+ )
263
319
 
264
320
 
265
321
  cli.add_command(dependabot)
266
322
  cli.add_command(keep_alive_prs)
323
+ cli.add_command(notifications)
267
324
 
268
325
  if __name__ == "__main__":
269
326
  cli()
@@ -0,0 +1,14 @@
1
+ from github.Notification import Notification
2
+
3
+
4
+ def mark_as_done(self) -> None:
5
+ """
6
+ :calls: `PATCH /notifications/threads/{id} <https://docs.github.com/en/rest/activity/notifications?apiVersion=2022-11-28#mark-a-thread-as-done>`_
7
+ """
8
+ headers, data = self._requester.requestJsonAndCheck(
9
+ "DELETE",
10
+ self.url,
11
+ )
12
+
13
+
14
+ Notification.mark_as_done = mark_as_done
@@ -60,8 +60,6 @@ def setup():
60
60
  # clear thread-local context
61
61
  log.clear = structlog.contextvars.clear_contextvars # type: ignore
62
62
 
63
- logger = log
64
-
65
63
  configure_logger()
66
64
 
67
65
  log.debug("application setup")
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "github-overlord"
3
- version = "0.6.9"
3
+ version = "0.7.0"
4
4
  description = "Automatically merge Dependabot PRs in public repositories"
5
5
  authors = ["Michael Bianco <mike@mikebian.co>"]
6
6
  readme = "README.md"
@@ -13,9 +13,9 @@ pygithub = "^2.3.0"
13
13
  click = "^8.1.7"
14
14
  python-decouple-typed = "^3.11.0"
15
15
  funcy-pipe = "^0.11.0"
16
- structlog = "^24.2.0"
16
+ structlog = "^24.4.0"
17
17
  apscheduler = "^3.10.4"
18
- openai = "^1.35.3"
18
+ openai = "^1.37.1"
19
19
 
20
20
  [tool.poetry.scripts]
21
21
  github-overlord = "github_overlord:cli"
@@ -29,8 +29,8 @@ float_to_top = true
29
29
  [tool.poetry.group.dev.dependencies]
30
30
  isort = "^5.13.2"
31
31
  black = "^24.4.2"
32
- pyright = "^1.1.368"
33
- pylint = "^3.2.3"
32
+ pyright = "^1.1.373"
33
+ pylint = "^3.2.6"
34
34
 
35
35
  [build-system]
36
36
  requires = ["poetry-core"]