154 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/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()
 | 
