This is an automated email from the ASF dual-hosted git repository. ewencp pushed a commit to branch 2.1 in repository https://gitbox.apache.org/repos/asf/kafka.git
The following commit(s) were added to refs/heads/2.1 by this push: new 4055a24 KAFKA-7131: Update release script to generate announcement email text 4055a24 is described below commit 4055a248b4c4baf5b29f067b2f203e252e1ba563 Author: Bibin Sebastian <bisebast...@delc02qp51sg8wn.sea.corp.expecn.com> AuthorDate: Sat Oct 20 20:43:22 2018 -0700 KAFKA-7131: Update release script to generate announcement email text Author: Bibin Sebastian <bisebast...@delc02qp51sg8wn.sea.corp.expecn.com> Author: Ewen Cheslack-Postava <m...@ewencp.org> Reviewers: Matthias J. Sax <mj...@apache.org>, Ewen Cheslack-Postava <e...@confluent.io> Closes #5572 from bibinss/release_mail (cherry picked from commit 83e98334a94ce2071a3294a8b310f1d646127f1c) Signed-off-by: Ewen Cheslack-Postava <m...@ewencp.org> --- release.py | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 133 insertions(+), 8 deletions(-) diff --git a/release.py b/release.py index 3573a7f..802c9de 100755 --- a/release.py +++ b/release.py @@ -45,6 +45,10 @@ release.py stage-docs [kafka-site-path] With no arguments this script assumes you have the Kafka repository and kafka-site repository checked out side-by-side, but you can specify a full path to the kafka-site repository if this is not the case. +release.py release-email + + Generates the email content/template for sending release announcement email. + """ from __future__ import print_function @@ -56,6 +60,7 @@ import os import subprocess import sys import tempfile +import re PROJECT_NAME = "kafka" CAPITALIZED_PROJECT_NAME = "kafka".upper() @@ -256,11 +261,138 @@ def command_stage_docs(): sys.exit(0) +def validate_release_version_parts(version): + try: + version_parts = version.split('.') + if len(version_parts) != 3: + fail("Invalid release version, should have 3 version number components") + # Validate each part is a number + [int(x) for x in version_parts] + except ValueError: + fail("Invalid release version, should be a dotted version number") + +def get_release_version_parts(version): + validate_release_version_parts(version) + return version.split('.') + +def validate_release_num(version): + tags = cmd_output('git tag').split() + if version not in tags: + fail("The specified version is not a valid release version number") + validate_release_version_parts(version) + +def command_release_announcement_email(): + tags = cmd_output('git tag').split() + release_tag_pattern = re.compile('^[0-9]+\.[0-9]+\.[0-9]+$') + release_tags = sorted([t for t in tags if re.match(release_tag_pattern, t)]) + release_version_num = release_tags[-1] + if not user_ok("""Is the current release %s ? (y/n): """ % release_version_num): + release_version_num = raw_input('What is the current release version:') + validate_release_num(release_version_num) + previous_release_version_num = release_tags[-2] + if not user_ok("""Is the previous release %s ? (y/n): """ % previous_release_version_num): + previous_release_version_num = raw_input('What is the previous release version:') + validate_release_num(previous_release_version_num) + if release_version_num < previous_release_version_num : + fail("Current release version number can't be less than previous release version number") + number_of_contributors = int(subprocess.check_output('git shortlog -sn --no-merges %s..%s | wc -l' % (previous_release_version_num, release_version_num) , shell=True)) + contributors = subprocess.check_output("git shortlog -sn --no-merges %s..%s | cut -f2 | sort --ignore-case" % (previous_release_version_num, release_version_num), shell=True) + release_announcement_data = { + 'number_of_contributors': number_of_contributors, + 'contributors': ', '.join(str(x) for x in filter(None, contributors.split('\n'))), + 'release_version': release_version_num + } + + release_announcement_email = """ +To: annou...@apache.org, d...@kafka.apache.org, us...@kafka.apache.org, kafka-clie...@googlegroups.com +Subject: [ANNOUNCE] Apache Kafka %(release_version)s + +The Apache Kafka community is pleased to announce the release for Apache Kafka %(release_version)s + +<DETAILS OF THE CHANGES> + +All of the changes in this release can be found in the release notes: +https://www.apache.org/dist/kafka/%(release_version)s/RELEASE_NOTES.html + + +You can download the source and binary release (Scala <VERSIONS>) from: +https://kafka.apache.org/downloads#%(release_version)s + +--------------------------------------------------------------------------------------------------- + + +Apache Kafka is a distributed streaming platform with four core APIs: + + +** The Producer API allows an application to publish a stream records to +one or more Kafka topics. + +** The Consumer API allows an application to subscribe to one or more +topics and process the stream of records produced to them. + +** The Streams API allows an application to act as a stream processor, +consuming an input stream from one or more topics and producing an +output stream to one or more output topics, effectively transforming the +input streams to output streams. + +** The Connector API allows building and running reusable producers or +consumers that connect Kafka topics to existing applications or data +systems. For example, a connector to a relational database might +capture every change to a table. + + +With these APIs, Kafka can be used for two broad classes of application: + +** Building real-time streaming data pipelines that reliably get data +between systems or applications. + +** Building real-time streaming applications that transform or react +to the streams of data. + + +Apache Kafka is in use at large and small companies worldwide, including +Capital One, Goldman Sachs, ING, LinkedIn, Netflix, Pinterest, Rabobank, +Target, The New York Times, Uber, Yelp, and Zalando, among others. + +A big thank you for the following %(number_of_contributors)d contributors to this release! + +%(contributors)s + +We welcome your help and feedback. For more information on how to +report problems, and to get involved, visit the project website at +https://kafka.apache.org/ + +Thank you! + + +Regards, + +<YOU>""" % release_announcement_data + + print() + print("*****************************************************************") + print() + print(release_announcement_email) + print() + print("*****************************************************************") + print() + print("Use the above template to send the announcement for the release to the mailing list.") + print("IMPORTANT: Note that there are still some substitutions that need to be made in the template:") + print(" - Describe major changes in this release") + print(" - Scala versions") + print(" - Fill in your name in the signature") + print(" - You will need to use your apache email address to send out the email (otherwise, it won't be delivered to annou...@apache.org)") + print(" - Finally, validate all the links before shipping!") + print("Note that all substitutions are annotated with <> around them.") + sys.exit(0) + # Dispatch to subcommand subcommand = sys.argv[1] if len(sys.argv) > 1 else None if subcommand == 'stage-docs': command_stage_docs() +elif subcommand == 'release-email': + command_release_announcement_email() elif not (subcommand is None or subcommand == 'stage'): fail("Unknown subcommand: %s" % subcommand) # else -> default subcommand stage @@ -328,14 +460,7 @@ cmd("Verifying that you have no unstaged git changes", 'git diff --exit-code --q cmd("Verifying that you have no staged git changes", 'git diff --cached --exit-code --quiet') release_version = raw_input("Release version (without any RC info, e.g. 1.0.0): ") -try: - release_version_parts = release_version.split('.') - if len(release_version_parts) != 3: - fail("Invalid release version, should have 3 version number components") - # Validate each part is a number - [int(x) for x in release_version_parts] -except ValueError: - fail("Invalid release version, should be a dotted version number") +release_version_parts = get_release_version_parts(release_version) rc = raw_input("Release candidate number: ")