|  | #!/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: | 
|  | gpg = GPG(homedir=gpghome) | 
|  | signed = gpg.sign(output) | 
|  | filename = filename + ".asc" | 
|  | with open(filename, "w") as f: | 
|  | f.write(str(signed)) | 
|  |  | 
|  |  | 
|  | if __name__ == "__main__": | 
|  | _main() |