#!/usr/bin/env python # Copyright (C) 2017 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Generates the text to paste into the email for announcing a new # release of Gerrit. The text is generated based on a template that # is filled with values either passed to the script or calculated # at runtime. # # The script outputs a plain text file with the announcement text: # # release-announcement-gerrit-X.Y.txt # # and, if GPG is available, the announcement text wrapped with a # signature: # # release-announcement-gerrit-X.Y.txt.asc # # Usage: # # ./tools/release-announcement.py -v 2.14.2 -p 2.14.1 \ # -s "This release fixes several bugs since 2.14.1" # # Parameters: # # --version (-v): The version of Gerrit being released. # # --previous (-p): The previous version of Gerrit. Optional. If # specified, the generated text includes a link to the gitiles # log of commits between the previous and new versions. # # --summary (-s): Short summary of the release. Optional. When # specified, the summary is inserted in the introductory sentence # of the generated text. # # Prerequisites: # # - The Jinja2 python library [1] must be installed. # # - For GPG signing to work, the python-gnupg library [2] must be # installed, and the ~/.gnupg folder must exist. # # - The war file must have been installed to the local Maven repository # using the `./tools/mvn/api.sh war_install` command. # # [1] http://jinja.pocoo.org/ # [2] http://pythonhosted.org/gnupg/ from __future__ import print_function import argparse import hashlib import os import sys from gnupg import GPG from jinja2 import Template class Version: def __init__(self, version): self.version = version parts = version.split('.') if len(parts) > 2: self.major = ".".join(parts[:2]) self.patch = version else: self.major = version self.patch = None def __str__(self): return self.version def _main(): descr = 'Generate Gerrit release announcement email text' parser = argparse.ArgumentParser( description=descr, formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('-v', '--version', dest='version', required=True, help='gerrit version to release') parser.add_argument('-p', '--previous', dest='previous', help='previous gerrit version (optional)') parser.add_argument('-s', '--summary', dest='summary', help='summary of the release content (optional)') options = parser.parse_args() summary = options.summary if summary and not summary.endswith("."): summary = summary + "." data = { "version": Version(options.version), "previous": options.previous, "summary": summary } war = os.path.join( os.path.expanduser("~/.m2/repository/com/google/gerrit/gerrit-war/"), "%(version)s/gerrit-war-%(version)s.war" % data) if not os.path.isfile(war): print("Could not find war file for Gerrit %s in local Maven repository" % data["version"], file=sys.stderr) sys.exit(1) md5 = hashlib.md5() sha1 = hashlib.sha1() sha256 = hashlib.sha256() BUF_SIZE = 65536 # Read data in 64kb chunks with open(war, 'rb') as f: while True: d = f.read(BUF_SIZE) if not d: break md5.update(d) sha1.update(d) sha256.update(d) data["sha1"] = sha1.hexdigest() data["sha256"] = sha256.hexdigest() data["md5"] = md5.hexdigest() template = Template(open("tools/release-announcement-template.txt").read()) output = template.render(data=data) filename = "release-announcement-gerrit-%s.txt" % data["version"] with open(filename, "w") as f: f.write(output) gpghome = os.path.abspath(os.path.expanduser("~/.gnupg")) if not os.path.isdir(gpghome): print("Skipping signing due to missing gnupg home folder") else: try: gpg = GPG(homedir=gpghome) except TypeError: gpg = GPG(gnupghome=gpghome) signed = gpg.sign(output) filename = filename + ".asc" with open(filename, "w") as f: f.write(str(signed)) if __name__ == "__main__": _main()