Review: commented --- docs/usage/forge.rst> @@ -0,0 +1,294 @@> +Forge Integration> +=================> +> +Patchwork can synchronize patch workflows with code forges such as GitHub.> +When enabled, patch series submitted to a mailing list are automatically> +converted into pull requests, and pull requests opened on a forge are converted> +into patch series on the mailing list. Comments, reviews, and CI results flow> +in both directions.> +> +.. contents::> + :local:> +> +Overview> +--------> +> +The forge integration provides bidirectional synchronization:> +> +**Mailing list to forge:**> +> +- A completed patch series creates a pull request on the forge.> +- Respin submissions (v2, v3, ...) force-push to the same branch and post an> + update comment on the existing pull request.> +- Comments on patches or cover letters are forwarded to the pull request.> +> +**Forge to mailing list:**> +> +- A pull request opened on the forge generates a patch series email sent to the> + mailing list and ingested directly into the Patchwork database.> +- Respin (force-push) events generate a new version of the patch series with> + proper version numbering and optional threading to the original.> +- Comments and reviews on the pull request are forwarded as email replies to the> + series.Ceci est très faux.
Message
[v3,00/16] Implement forge bidirectional sync Does it work or not? Robin Jarry (16): parsemail: wrap parse_mail() in a single transaction parsemail: fix SeriesReference race with concurrent delivery series: add respin tracking for patch series versions series: add metadata key-value store forge: add per-project configuration model forge: add backend abstraction layer forge: add utilities for mailing-list sync forge: add git mirror utilities forge: sync github pull requests to mailing list forge: sync github comments and reviews to mailing list fixup! forge: sync github comments and reviews to mailing list forge: sync github check results to patchwork forge: sync patch series to github pull requests forge: forward mailing list comments to forge pull requests docs: add forge integration documentation deploy Makefile | 147 +++++++ docs/deployment/configuration.rst | 37 ++ docs/usage/forge.rst | 294 +++++++++++++ docs/usage/index.rst | 1 + nginx.conf | 62 +++ parsemail.sh | 14 + patchwork.service | 22 + patchwork/admin.py | 24 ++ patchwork/api/series.py | 20 +-patchwork/forge/__init__.py | 273 ++++++++++++ patchwork/forge/git.py | 289 +++++++++++++ patchwork/forge/github/__init__.py | 107 +++++ patchwork/forge/github/api.py | 137 ++++++ patchwork/forge/github/from_ml.py | 133 ++++++ patchwork/forge/github/to_ml.py | 226 ++++++++++ patchwork/forge/github/webhook.py | 124 ++++++ patchwork/forge/urls.py | 16 + patchwork/forge/util.py | 289 +++++++++++++ patchwork/forge/views.py | 82 ++++ patchwork/management/commands/parsemail.py | 4 +-.../migrations/0049_series_respin_tracking.py | 33 ++ patchwork/migrations/0050_series_metadata.py | 41 ++ patchwork/migrations/0051_forgeconfig.py | 46 ++ patchwork/models.py | 107 +++++ patchwork/parser.py | 174 +++++++-patchwork/settings/base.py | 32 ++ patchwork/settings/production.py | 67 +++ patchwork/templates/patchwork/submission.html | 25 ++ patchwork/templatetags/utils.py | 9 + patchwork/tests/api/test_series.py | 2 +-patchwork/tests/forge/__init__.py | 0 patchwork/tests/forge/test_git.py | 278 ++++++++++++ patchwork/tests/forge/test_util.py | 406 ++++++++++++++++++ patchwork/tests/test_series.py | 39 ++ patchwork/urls.py | 9 + patchwork/views/cover.py | 3 + patchwork/views/patch.py | 2 + postfix/client_access | 2 + postfix/header_checks | 2 + postfix/main.cf | 53 +++ postfix/master.cf | 28 ++ postfix/recipient_bcc | 1 + postfix/transport | 2 + .../parsemail-race-fix-e5f6g7h8i9j0k1l2.yaml | 5 + ...arsemail-transaction-d4e5f6g7h8i9j0k1.yaml | 6 + ...ries-respin-tracking-c3d4e5f6g7h8i9j0.yaml | 16 + uwsgi.ini | 10 + 47 files changed, 3677 insertions(+), 22 deletions(-) create mode 100644 Makefile create mode 100644 docs/usage/forge.rst create mode 100644 nginx.conf create mode 100755 parsemail.sh create mode 100644 patchwork.service create mode 100644 patchwork/forge/__init__.py create mode 100644 patchwork/forge/git.py create mode 100644 patchwork/forge/github/__init__.py create mode 100644 patchwork/forge/github/api.py create mode 100644 patchwork/forge/github/from_ml.py create mode 100644 patchwork/forge/github/to_ml.py create mode 100644 patchwork/forge/github/webhook.py create mode 100644 patchwork/forge/urls.py create mode 100644 patchwork/forge/util.py create mode 100644 patchwork/forge/views.py create mode 100644 patchwork/migrations/0049_series_respin_tracking.py create mode 100644 patchwork/migrations/0050_series_metadata.py create mode 100644 patchwork/migrations/0051_forgeconfig.py create mode 100644 patchwork/settings/production.py create mode 100644 patchwork/tests/forge/__init__.py create mode 100644 patchwork/tests/forge/test_git.py create mode 100644 patchwork/tests/forge/test_util.py create mode 100644 postfix/client_access create mode 100644 postfix/header_checks create mode 100644 postfix/main.cf create mode 100644 postfix/master.cf create mode 100644 postfix/recipient_bcc create mode 100644 postfix/transport create mode 100644 releasenotes/notes/parsemail-race-fix-e5f6g7h8i9j0k1l2.yaml create mode 100644 releasenotes/notes/parsemail-transaction-d4e5f6g7h8i9j0k1.yaml create mode 100644 releasenotes/notes/series-respin-tracking-c3d4e5f6g7h8i9j0.yaml create mode 100644 uwsgi.ini
Comments
Review: commented Bof bof. --- patchwork/forge/__init__.py> @@ -0,0 +1,175 @@> +# Patchwork - automated patch tracking system> +# Copyright (C) 2026 Robin Jarry <robin@jarry.cc>> +#> +# SPDX-License-Identifier: GPL-2.0-or-later> +> +"""> +Forge integration framework.> +> +Provides an abstraction layer for synchronizing patch workflows between> +patchwork and code forges (GitHub, GitLab, etc.). Each forge platform is> +implemented as a backend that registers itself at import time and is only> +loaded when listed in settings.FORGE_BACKENDS.> +> +Backends are responsible for webhook signature verification and event parsing.> +Sync logic (creating patches from PRs, forwarding comments) is implemented> +per-backend but can reuse generic utilities from patchwork.forge.sync.> +> +Forge-specific dependencies remain entirely optional: a backend module is never> +imported unless explicitly enabled in settings.Foobar baz 1. --- patchwork/forge/__init__.py> @@ -0,0 +1,175 @@> +# Patchwork - automated patch tracking system> +# Copyright (C) 2026 Robin Jarry <robin@jarry.cc>> +#> +# SPDX-License-Identifier: GPL-2.0-or-later> +> +"""> +Forge integration framework.> +> +Provides an abstraction layer for synchronizing patch workflows between> +patchwork and code forges (GitHub, GitLab, etc.). Each forge platform is> +implemented as a backend that registers itself at import time and is only> +loaded when listed in settings.FORGE_BACKENDS.> +> +Backends are responsible for webhook signature verification and event parsing.> +Sync logic (creating patches from PRs, forwarding comments) is implemented> +per-backend but can reuse generic utilities from patchwork.forge.sync.> +> +Forge-specific dependencies remain entirely optional: a backend module is never> +imported unless explicitly enabled in settings.> +"""> +> +import importlib> +import logging> +from abc import ABC> +from abc import abstractmethod> +from dataclasses import dataclass> +from dataclasses import field> +> +from django.conf import settings> +> +logger = logging.getLogger(__name__)> +> +> +@dataclass> +class ForgeUser:> + login: str = ''> + name: str = ''> + email: str = ''> +> +> +@dataclass> +class ReviewComment:> + path: str = ''> + diff_hunk: str = ''> + body: str = ''> +> +> +@dataclass> +class CheckRun:> + name: str = ''> + status: str = ''> + url: str = ''> + description: str = ''> +> +> +@dataclass> +class ForgeEvent:> + type: str = ''> + repo_key: str = ''> + pr_number: int = 0> + author: ForgeUser = field(default_factory=ForgeUser)> + body: str = ''> +> + # review fields> + review_id: int = 0> + review_state: str = ''> +> + # check fields> + check_suite_id: int = 0> + check_name: str = ''> + check_status: str = ''> + check_url: str = ''> + check_description: str = ''> +> + # pull request fields> + pr_title: str = ''> + pr_body: str = ''> + pr_head: str = ''> + pr_base: str = ''> + pr_head_branch: str = ''> + pr_action: str = ''> + pr_before: str = ''> +> +> +class ForgeBackend(ABC):> + """> + Base class for forge backend implementations.> +> + Each backend handles webhook signature verification and event parsing for> + a specific forge platform (GitHub, GitLab, etc.). Backends register> + themselves at import time via register_backend().Foo 2. --- patchwork/forge/github/api.py> @@ -94,3 +94,43 @@ def fetch_check_runs(gh, forge_config, check_suite_id):> )> )> return runs> +> +> +def create_pr(gh, forge_config, title, body, head, base):> + """> + Create a pull request on GitHub. Return the PR number.> + """> + owner, repo = forge_config.repo.split('/', 1)> + result = gh_api_request(> + gh,> + forge_config,> + 'POST',> + f'/repos/{owner}/{repo}/pulls',> + {'title': title, 'body': body, 'head': head, 'base': base},> + )> + return result['number']> +> +> +def base_branch(gh, forge_config):> + """> + Return the default branch of the GitHub repository.> + """> + owner, repo = forge_config.repo.split('/', 1)> + result = gh_api_request(> + gh,> + forge_config,> + 'GET',> + f'/repos/{owner}/{repo}',> + )B llkjlsdjf lkjsdf