You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kafka.apache.org by ew...@apache.org on 2018/10/21 03:44:05 UTC
[kafka] branch 2.1 updated: KAFKA-7131: Update release script to
generate announcement email text
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 <bi...@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 <bi...@DELC02QP51SG8WN.sea.corp.expecn.com>
Author: Ewen Cheslack-Postava <me...@ewencp.org>
Reviewers: Matthias J. Sax <mj...@apache.org>, Ewen Cheslack-Postava <ew...@confluent.io>
Closes #5572 from bibinss/release_mail
(cherry picked from commit 83e98334a94ce2071a3294a8b310f1d646127f1c)
Signed-off-by: Ewen Cheslack-Postava <me...@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: announce@apache.org, dev@kafka.apache.org, users@kafka.apache.org, kafka-clients@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 announce@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: ")