Attention is currently required from: cron2. Hello cron2,
I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/361?usp=email to look at the new patch set (#2). Change subject: dev-tools/gerrit-send-mail.py: tool to send Gerrit patchsets to Patchwork ...................................................................... dev-tools/gerrit-send-mail.py: tool to send Gerrit patchsets to Patchwork Since we're trying to use Gerrit for patch reviews, but the actual merge process is still implemented against the ML and Patchwork, I wrote a script that attempts to bridge the gap. It extracts all relevant information about a patch from Gerrit and converts it into a mail compatible to git-am. Mostly this work is done by Gerrit already, since we can get the original patch in git format-patch format. But we add Acked-by information according to the approvals in Gerrit and some other metadata. This should allow the merge to happen based on this one mail alone. Change-Id: If4e9c2e58441efb3fd00872cd62d1cc6c607f160 Signed-off-by: Frank Lichtenheld <fr...@lichtenheld.com> --- A dev-tools/gerrit-send-mail.py 1 file changed, 133 insertions(+), 0 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/61/361/2 diff --git a/dev-tools/gerrit-send-mail.py b/dev-tools/gerrit-send-mail.py new file mode 100644 index 0000000..74bd272 --- /dev/null +++ b/dev-tools/gerrit-send-mail.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2023 OpenVPN Inc <sa...@openvpn.net> +# Copyright (C) 2023 Frank Lichtenheld <frank.lichtenh...@openvpn.net> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 +# as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Extract a patch from Gerrit and transform it in a file suitable as input +# for git send-email. + +import argparse +import base64 +from datetime import timezone +import json +import sys +from urllib.parse import urlparse + +import dateutil.parser +import requests + + +def get_details(args): + params = {"o": ["CURRENT_REVISION", "LABELS", "DETAILED_ACCOUNTS"]} + r = requests.get(args.url + "/changes/" + args.changeid, params=params) + print(r.url) + json_txt = r.text.removeprefix(")]}'\n") + json_data = json.loads(json_txt) + assert len(json_data["revisions"]) == 1 # CURRENT_REVISION works as expected + revision = json_data["revisions"].popitem()[1]["_number"] + assert "Code-Review" in json_data["labels"] + acked_by = [] + for reviewer in json_data["labels"]["Code-Review"]["all"]: + if "value" in reviewer: + assert reviewer["value"] >= 0 # no NACK + if reviewer["value"] == 2: + ack = "{} <{}>".format(reviewer["display_name"], reviewer["email"]) + print("Acked-by: " + ack) + acked_by.append(ack) + change_id = json_data["change_id"] + # assumes that the created date in Gerrit is in UTC + utc_stamp = ( + dateutil.parser.parse(json_data["created"]) + .replace(tzinfo=timezone.utc) + .timestamp() + ) + # convert to milliseconds as used in message id + created_stamp = int(utc_stamp * 1000) + hostname = urlparse(args.url).hostname + msg_id = f"gerrit.{created_stamp}.{change_id}@{hostname}" + return { + "revision": revision, + "project": json_data["project"], + "target": json_data["branch"], + "msg_id": msg_id, + "acked_by": acked_by, + } + + +def get_patch(details, args): + r = requests.get( + "{}/changes/{}/revisions/{}/patch?download".format( + args.url, args.changeid, details["revision"] + ) + ) + print(r.url) + patch_text = base64.b64decode(r.text).decode() + return patch_text + + +def apply_patch_mods(patch_text, details, args): + signed_off_start = patch_text.rindex("\nSigned-off-by: ") + signed_off_end = patch_text.index("\n", signed_off_start + 1) + 1 + comment_start = patch_text.index("\n---\n") + len("\n---\n") + assert comment_start > signed_off_end + acked_by_text = "" + acked_by_names = "" + for ack in details["acked_by"]: + acked_by_text += f"Acked-by: {ack}\n" + acked_by_names += f"{ack}\n" + patch_text_mod = ( + patch_text[:signed_off_end] + + acked_by_text + + patch_text[signed_off_end:comment_start] + + """ +This change was reviewed on Gerrit and approved by at least one +developer. I request to merge it to {target}. + +Gerrit URL: {url}/c/{project}/+/{changeid} +This mail reflects revision {revision} of this Change. +Acked-by according to Gerrit (reflected above): +{acked_by_names} + """.format( + url=args.url, + changeid=args.changeid, + acked_by_names=acked_by_names, + **details, + ) + + patch_text[comment_start:] + ) + filename = "gerrit-{}-{}.patch".format(args.changeid, details["revision"]) + with open(filename, "w") as patch_file: + patch_file.write(patch_text_mod) + print("send with:") + print("git send-email --in-reply-to {} {}".format(details["msg_id"], filename)) + + +def main(): + parser = argparse.ArgumentParser( + prog="gerrit-send-mail", + description="Send patchset from Gerrit to mailing list", + ) + parser.add_argument("changeid") + parser.add_argument("-u", "--url", default="https://gerrit.openvpn.net") + args = parser.parse_args() + + details = get_details(args) + patch = get_patch(details, args) + apply_patch_mods(patch, details, args) + + +if __name__ == "__main__": + sys.exit(main()) -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/361?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: If4e9c2e58441efb3fd00872cd62d1cc6c607f160 Gerrit-Change-Number: 361 Gerrit-PatchSet: 2 Gerrit-Owner: flichtenheld <fr...@lichtenheld.com> Gerrit-Reviewer: cron2 Gerrit-CC: openvpn-devel <openvpn-devel@lists.sourceforge.net> Gerrit-Attention: cron2 Gerrit-MessageType: newpatchset
_______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel