repomatic.github.unsubscribe moduleΒΆ
Unsubscribe from closed, inactive GitHub notification threads.
Processes notification threads in two phases:
REST notification threads: fetches the Issue/PullRequest notification threads last moved before the cutoff via
/notifications, resolves each subject in batched GraphQL lookups, and unsubscribes the closed, stale ones viaDELETE+PATCH.GraphQL threadless subscriptions: searches for closed issues/PRs the user is involved in but that lack notification threads, and unsubscribes via the
updateSubscriptionmutation.
Requires the gh CLI to be installed and authenticated with a token that
has the notifications scope (classic PAT) or equivalent fine-grained
permissions.
- repomatic.github.unsubscribe.GRAPHQL_PAGE_SIZE = 25ΒΆ
Per-page count for GraphQL search results.
- repomatic.github.unsubscribe.NOTIFICATION_PAGE_SIZE = 50ΒΆ
Per-page count for REST
/notificationsresults.
- repomatic.github.unsubscribe.NOTIFICATION_SUBJECT_TYPES = frozenset({'Issue', 'PullRequest'})ΒΆ
Notification subject types to process.
- repomatic.github.unsubscribe.SUBJECT_BATCH_SIZE = 50ΒΆ
Subjects looked up per GraphQL round trip.
Looked up one at a time, each thread costs a REST detail call. A batched lookup answers 50 in one request for a single rate-limit point, so a 113-thread pool costs three requests instead of 113.
- repomatic.github.unsubscribe.SUBJECT_STATES = {'CLOSED': 'closed', 'MERGED': 'closed', 'OPEN': 'open'}ΒΆ
GraphQL subject states, mapped onto the REST spelling the phase compares.
REST reports a merged pull request as
closed, where GraphQL distinguishesMERGED. Collapsing the two here keeps one vocabulary in the caller, and keeps the batched lookup a drop-in for the one-subject REST lookup,_get_thread_details.
- repomatic.github.unsubscribe.SUBJECT_URL_PATTERN = re.compile('/repos/(?P<owner>[^/]+)/(?P<repo>[^/]+)/(?:issues|pulls)/(?P<number>\\d+)$')ΒΆ
Owner, repository and number, read off a notificationβs subject URL.
A subject URL is the only handle the notification list gives out. GraphQL addresses the same object by coordinates, and
issueOrPullRequestcovers both shapes, so theissues/pullshalf of the path is read and discarded.
- repomatic.github.unsubscribe.UNSUBSCRIBE_WORKFLOW = 'unsubscribe.yaml'ΒΆ
Workflow file the backlog warning links to for a manual run with a higher cap.
The report renders inside that workflowβs own run, so the reader is one click from the
Run workflowform the warning tells them to use. Kept equal to the filenamerepomatic.registry.COMPONENTSships, since a link to a workflow a repository does not have is worse than no link.
- class repomatic.github.unsubscribe.DetailRow(action, html_url, number, repo, title, updated_at)[source]ΒΆ
Bases:
objectPer-item detail for the markdown report table.
- action: ReportActionΒΆ
- class repomatic.github.unsubscribe.Phase1Result(cutoff=None, max_unsubscribes=0, newest_updated=None, oldest_updated=None, rows=<factory>, threads_deferred=0, threads_failed=0, threads_skipped_open=0, threads_skipped_recent=0, threads_skipped_unknown=0, threads_total=0, threads_unsubscribed=0)[source]ΒΆ
Bases:
objectAccumulated counts and details from REST notification phase.
- class repomatic.github.unsubscribe.Phase2Result(cutoff=None, items_deferred=0, items_failed=0, items_not_subscribed=0, items_skipped_recent=0, items_total=0, items_unsubscribed=0, max_unsubscribes=0, rows=<factory>, search_query='', skipped=False, skip_reason='')[source]ΒΆ
Bases:
objectAccumulated counts and details from GraphQL threadless phase.
- class repomatic.github.unsubscribe.UnsubscribeResult(dry_run=False, months=3, phase1=<factory>, phase2=<factory>)[source]ΒΆ
Bases:
objectAccumulated results from both unsubscribe phases.
- phase1: Phase1ResultΒΆ
- phase2: Phase2ResultΒΆ
- repomatic.github.unsubscribe.render_report(result, repo_url=None)[source]ΒΆ
Render a markdown report from unsubscribe results.
Pure function that produces the same markdown structure as the downstream
unsubscribe.yamlworkflowβs$GITHUB_STEP_SUMMARY. The repository is passed in rather than probed, so the renderer stays pure and the caller keeps the one environment lookup.- Parameters:
result (
UnsubscribeResult) β Structured results from both phases.repo_url (
str|None) β Repository the run belongs to, linking the backlog warning to its workflow. Omitted, that warning renders as plain text.
- Return type:
- Returns:
Markdown report string.
- repomatic.github.unsubscribe.unsubscribe_threads(months, max_unsubscribes, dry_run)[source]ΒΆ
Unsubscribe from closed, inactive notification threads.
Runs two phases, each behind its own runner:
REST notification threads (
_run_rest_phase): fetches notification threads, inspects each subject for closed + stale status, and unsubscribes.GraphQL threadless subscriptions (
_run_graphql_phase): searches for closed issues/PRs the user is involved in and unsubscribes via mutation.
- Parameters:
- Return type:
- Returns:
Structured results from both phases.