mirror of https://github.com/apache/kafka.git
KAFKA-10712; Update release scripts to Python3 (#11538)
Reviewers: Mickael Maison <mickael.maison@gmail.com>
This commit is contained in:
parent
6c59d2d685
commit
cec4d231ff
47
release.py
47
release.py
|
@ -51,8 +51,6 @@ release.py release-email
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from getpass import getpass
|
from getpass import getpass
|
||||||
import json
|
import json
|
||||||
|
@ -99,25 +97,25 @@ def print_output(output):
|
||||||
print(">", line)
|
print(">", line)
|
||||||
|
|
||||||
def cmd(action, cmd_arg, *args, **kwargs):
|
def cmd(action, cmd_arg, *args, **kwargs):
|
||||||
if isinstance(cmd_arg, basestring) and not kwargs.get("shell", False):
|
if isinstance(cmd_arg, str) and not kwargs.get("shell", False):
|
||||||
cmd_arg = cmd_arg.split()
|
cmd_arg = cmd_arg.split()
|
||||||
allow_failure = kwargs.pop("allow_failure", False)
|
allow_failure = kwargs.pop("allow_failure", False)
|
||||||
num_retries = kwargs.pop("num_retries", 0)
|
num_retries = kwargs.pop("num_retries", 0)
|
||||||
|
|
||||||
stdin_log = ""
|
stdin_log = ""
|
||||||
if "stdin" in kwargs and isinstance(kwargs["stdin"], basestring):
|
if "stdin" in kwargs and isinstance(kwargs["stdin"], str):
|
||||||
stdin_log = "--> " + kwargs["stdin"]
|
stdin_log = "--> " + kwargs["stdin"]
|
||||||
stdin = tempfile.TemporaryFile()
|
stdin = tempfile.TemporaryFile()
|
||||||
stdin.write(kwargs["stdin"])
|
stdin.write(kwargs["stdin"].encode('utf-8'))
|
||||||
stdin.seek(0)
|
stdin.seek(0)
|
||||||
kwargs["stdin"] = stdin
|
kwargs["stdin"] = stdin
|
||||||
|
|
||||||
print(action, cmd_arg, stdin_log)
|
print(action, cmd_arg, stdin_log)
|
||||||
try:
|
try:
|
||||||
output = subprocess.check_output(cmd_arg, *args, stderr=subprocess.STDOUT, **kwargs)
|
output = subprocess.check_output(cmd_arg, *args, stderr=subprocess.STDOUT, **kwargs)
|
||||||
print_output(output)
|
print_output(output.decode('utf-8'))
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
print_output(e.output)
|
print_output(e.output.decode('utf-8'))
|
||||||
|
|
||||||
if num_retries > 0:
|
if num_retries > 0:
|
||||||
kwargs['num_retries'] = num_retries - 1
|
kwargs['num_retries'] = num_retries - 1
|
||||||
|
@ -137,9 +135,9 @@ def cmd(action, cmd_arg, *args, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def cmd_output(cmd, *args, **kwargs):
|
def cmd_output(cmd, *args, **kwargs):
|
||||||
if isinstance(cmd, basestring):
|
if isinstance(cmd, str):
|
||||||
cmd = cmd.split()
|
cmd = cmd.split()
|
||||||
return subprocess.check_output(cmd, *args, stderr=subprocess.STDOUT, **kwargs)
|
return subprocess.check_output(cmd, *args, stderr=subprocess.STDOUT, **kwargs).decode('utf-8')
|
||||||
|
|
||||||
def replace(path, pattern, replacement):
|
def replace(path, pattern, replacement):
|
||||||
updated = []
|
updated = []
|
||||||
|
@ -162,7 +160,7 @@ def regexReplace(path, pattern, replacement):
|
||||||
f.write(line)
|
f.write(line)
|
||||||
|
|
||||||
def user_ok(msg):
|
def user_ok(msg):
|
||||||
ok = raw_input(msg)
|
ok = input(msg)
|
||||||
return ok.strip().lower() == 'y'
|
return ok.strip().lower() == 'y'
|
||||||
|
|
||||||
def sftp_mkdir(dir):
|
def sftp_mkdir(dir):
|
||||||
|
@ -211,13 +209,14 @@ def get_jdk(prefs, version):
|
||||||
"""
|
"""
|
||||||
Get settings for the specified JDK version.
|
Get settings for the specified JDK version.
|
||||||
"""
|
"""
|
||||||
jdk_java_home = get_pref(prefs, 'jdk%d' % version, lambda: raw_input("Enter the path for JAVA_HOME for a JDK%d compiler (blank to use default JAVA_HOME): " % version))
|
jdk_java_home = get_pref(prefs, 'jdk%d' % version, lambda: input("Enter the path for JAVA_HOME for a JDK%d compiler (blank to use default JAVA_HOME): " % version))
|
||||||
jdk_env = dict(os.environ) if jdk_java_home.strip() else None
|
jdk_env = dict(os.environ) if jdk_java_home.strip() else None
|
||||||
if jdk_env is not None: jdk_env['JAVA_HOME'] = jdk_java_home
|
if jdk_env is not None: jdk_env['JAVA_HOME'] = jdk_java_home
|
||||||
java_version = cmd_output("%s/bin/java -version" % jdk_java_home, env=jdk_env)
|
java_version = cmd_output("%s/bin/java -version" % jdk_java_home, env=jdk_env)
|
||||||
if version == 8 and "1.8.0" not in java_version:
|
if version == 8:
|
||||||
fail("JDK 8 is required")
|
if "1.8.0" not in java_version:
|
||||||
elif "%d.0" % version not in java_version or '"%d"' % version not in java_version:
|
fail("JDK 8 is required")
|
||||||
|
elif "%d.0" % version not in java_version and '"%d"' % version not in java_version:
|
||||||
fail("JDK %s is required" % version)
|
fail("JDK %s is required" % version)
|
||||||
return jdk_env
|
return jdk_env
|
||||||
|
|
||||||
|
@ -278,7 +277,7 @@ def command_stage_docs():
|
||||||
|
|
||||||
versioned_docs_path = os.path.join(kafka_site_repo_path, docs_version(version))
|
versioned_docs_path = os.path.join(kafka_site_repo_path, docs_version(version))
|
||||||
if not os.path.exists(versioned_docs_path):
|
if not os.path.exists(versioned_docs_path):
|
||||||
os.mkdir(versioned_docs_path, 0755)
|
os.mkdir(versioned_docs_path, 755)
|
||||||
|
|
||||||
# The contents of the docs jar are site-docs/<docs dir>. We need to get rid of the site-docs prefix and dump everything
|
# The contents of the docs jar are site-docs/<docs dir>. We need to get rid of the site-docs prefix and dump everything
|
||||||
# inside it into the docs version subdirectory in the kafka-site repo
|
# inside it into the docs version subdirectory in the kafka-site repo
|
||||||
|
@ -316,16 +315,16 @@ def command_release_announcement_email():
|
||||||
release_tags = sorted([t for t in tags if re.match(release_tag_pattern, t)])
|
release_tags = sorted([t for t in tags if re.match(release_tag_pattern, t)])
|
||||||
release_version_num = release_tags[-1]
|
release_version_num = release_tags[-1]
|
||||||
if not user_ok("""Is the current release %s ? (y/n): """ % release_version_num):
|
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:')
|
release_version_num = input('What is the current release version:')
|
||||||
validate_release_num(release_version_num)
|
validate_release_num(release_version_num)
|
||||||
previous_release_version_num = release_tags[-2]
|
previous_release_version_num = release_tags[-2]
|
||||||
if not user_ok("""Is the previous release %s ? (y/n): """ % previous_release_version_num):
|
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:')
|
previous_release_version_num = input('What is the previous release version:')
|
||||||
validate_release_num(previous_release_version_num)
|
validate_release_num(previous_release_version_num)
|
||||||
if release_version_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")
|
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))
|
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).decode('utf-8'))
|
||||||
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)
|
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).decode('utf-8')
|
||||||
release_announcement_data = {
|
release_announcement_data = {
|
||||||
'number_of_contributors': number_of_contributors,
|
'number_of_contributors': number_of_contributors,
|
||||||
'contributors': ', '.join(str(x) for x in filter(None, contributors.split('\n'))),
|
'contributors': ', '.join(str(x) for x in filter(None, contributors.split('\n'))),
|
||||||
|
@ -488,10 +487,10 @@ starting_branch = cmd_output('git rev-parse --abbrev-ref HEAD')
|
||||||
cmd("Verifying that you have no unstaged git changes", 'git diff --exit-code --quiet')
|
cmd("Verifying that you have no unstaged git changes", 'git diff --exit-code --quiet')
|
||||||
cmd("Verifying that you have no staged git changes", 'git diff --cached --exit-code --quiet')
|
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): ")
|
release_version = input("Release version (without any RC info, e.g. 1.0.0): ")
|
||||||
release_version_parts = get_release_version_parts(release_version)
|
release_version_parts = get_release_version_parts(release_version)
|
||||||
|
|
||||||
rc = raw_input("Release candidate number: ")
|
rc = input("Release candidate number: ")
|
||||||
|
|
||||||
dev_branch = '.'.join(release_version_parts[:2])
|
dev_branch = '.'.join(release_version_parts[:2])
|
||||||
docs_release_version = docs_version(release_version)
|
docs_release_version = docs_version(release_version)
|
||||||
|
@ -515,7 +514,7 @@ if not rc:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
# Prereq checks
|
# Prereq checks
|
||||||
apache_id = get_pref(prefs, 'apache_id', lambda: raw_input("Enter your apache username: "))
|
apache_id = get_pref(prefs, 'apache_id', lambda: input("Enter your apache username: "))
|
||||||
|
|
||||||
jdk8_env = get_jdk(prefs, 8)
|
jdk8_env = get_jdk(prefs, 8)
|
||||||
jdk17_env = get_jdk(prefs, 17)
|
jdk17_env = get_jdk(prefs, 17)
|
||||||
|
@ -524,7 +523,7 @@ def select_gpg_key():
|
||||||
print("Here are the available GPG keys:")
|
print("Here are the available GPG keys:")
|
||||||
available_keys = cmd_output("gpg --list-secret-keys")
|
available_keys = cmd_output("gpg --list-secret-keys")
|
||||||
print(available_keys)
|
print(available_keys)
|
||||||
key_name = raw_input("Which user name (enter the user name without email address): ")
|
key_name = input("Which user name (enter the user name without email address): ")
|
||||||
if key_name not in available_keys:
|
if key_name not in available_keys:
|
||||||
fail("Couldn't find the requested key.")
|
fail("Couldn't find the requested key.")
|
||||||
return key_name
|
return key_name
|
||||||
|
@ -534,7 +533,7 @@ key_name = get_pref(prefs, 'gpg-key', select_gpg_key)
|
||||||
gpg_passphrase = get_pref(prefs, 'gpg-pass', lambda: getpass("Passphrase for this GPG key: "))
|
gpg_passphrase = get_pref(prefs, 'gpg-pass', lambda: getpass("Passphrase for this GPG key: "))
|
||||||
# Do a quick validation so we can fail fast if the password is incorrect
|
# Do a quick validation so we can fail fast if the password is incorrect
|
||||||
with tempfile.NamedTemporaryFile() as gpg_test_tempfile:
|
with tempfile.NamedTemporaryFile() as gpg_test_tempfile:
|
||||||
gpg_test_tempfile.write("abcdefg")
|
gpg_test_tempfile.write("abcdefg".encode('utf-8'))
|
||||||
cmd("Testing GPG key & passphrase", ["gpg", "--batch", "--pinentry-mode", "loopback", "--passphrase-fd", "0", "-u", key_name, "--armor", "--output", gpg_test_tempfile.name + ".asc", "--detach-sig", gpg_test_tempfile.name], stdin=gpg_passphrase)
|
cmd("Testing GPG key & passphrase", ["gpg", "--batch", "--pinentry-mode", "loopback", "--passphrase-fd", "0", "-u", key_name, "--armor", "--output", gpg_test_tempfile.name + ".asc", "--detach-sig", gpg_test_tempfile.name], stdin=gpg_passphrase)
|
||||||
|
|
||||||
save_prefs(prefs)
|
save_prefs(prefs)
|
||||||
|
|
|
@ -28,7 +28,7 @@ from jira import JIRA
|
||||||
import itertools, sys
|
import itertools, sys
|
||||||
|
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
print >>sys.stderr, "Usage: release_notes.py <version>"
|
print("Usage: release_notes.py <version>", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
version = sys.argv[1]
|
version = sys.argv[1]
|
||||||
|
@ -58,7 +58,7 @@ if __name__ == "__main__":
|
||||||
apache = JIRA(JIRA_BASE_URL)
|
apache = JIRA(JIRA_BASE_URL)
|
||||||
issues = get_issues(apache, 'project=KAFKA and fixVersion=%s' % version)
|
issues = get_issues(apache, 'project=KAFKA and fixVersion=%s' % version)
|
||||||
if not issues:
|
if not issues:
|
||||||
print >>sys.stderr, "Didn't find any issues for the target fix version"
|
print("Didn't find any issues for the target fix version", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Some resolutions, including a lack of resolution, indicate that the bug hasn't actually been addressed and we shouldn't even be able to create a release until they are fixed
|
# Some resolutions, including a lack of resolution, indicate that the bug hasn't actually been addressed and we shouldn't even be able to create a release until they are fixed
|
||||||
|
@ -78,11 +78,11 @@ if __name__ == "__main__":
|
||||||
]
|
]
|
||||||
unresolved_issues = [issue for issue in issues if issue.fields.resolution in UNRESOLVED_RESOLUTIONS or issue.fields.resolution.name in UNRESOLVED_RESOLUTIONS]
|
unresolved_issues = [issue for issue in issues if issue.fields.resolution in UNRESOLVED_RESOLUTIONS or issue.fields.resolution.name in UNRESOLVED_RESOLUTIONS]
|
||||||
if unresolved_issues:
|
if unresolved_issues:
|
||||||
print >>sys.stderr, "The release is not completed since unresolved issues or improperly resolved issues were found still tagged with this release as the fix version:"
|
print("The release is not completed since unresolved issues or improperly resolved issues were found still tagged with this release as the fix version:", file=sys.stderr)
|
||||||
for issue in unresolved_issues:
|
for issue in unresolved_issues:
|
||||||
print >>sys.stderr, "Unresolved issue: %15s %20s %s" % (issue.key, issue.fields.resolution, issue_link(issue))
|
print("Unresolved issue: %15s %20s %s" % (issue.key, issue.fields.resolution, issue_link(issue)), file=sys.stderr)
|
||||||
print >>sys.stderr
|
print("", file=sys.stderr)
|
||||||
print >>sys.stderr, "Note that for some resolutions, you should simply remove the fix version as they have not been truly fixed in this release."
|
print("Note that for some resolutions, you should simply remove the fix version as they have not been truly fixed in this release.", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Get list of (issue type, [issues]) sorted by the issue ID type, with each subset of issues sorted by their key so they
|
# Get list of (issue type, [issues]) sorted by the issue ID type, with each subset of issues sorted by their key so they
|
||||||
|
@ -93,11 +93,12 @@ if __name__ == "__main__":
|
||||||
return -2
|
return -2
|
||||||
if issue.fields.issuetype.name == 'Improvement':
|
if issue.fields.issuetype.name == 'Improvement':
|
||||||
return -1
|
return -1
|
||||||
return issue.fields.issuetype.id
|
return int(issue.fields.issuetype.id)
|
||||||
|
|
||||||
by_group = [(k,sorted(g, key=lambda issue: issue.id)) for k,g in itertools.groupby(sorted(issues, key=issue_type_key), lambda issue: issue.fields.issuetype.name)]
|
by_group = [(k,sorted(g, key=lambda issue: issue.id)) for k,g in itertools.groupby(sorted(issues, key=issue_type_key), lambda issue: issue.fields.issuetype.name)]
|
||||||
|
|
||||||
print "<h1>Release Notes - Kafka - Version %s</h1>" % version
|
print("<h1>Release Notes - Kafka - Version %s</h1>" % version)
|
||||||
print """<p>Below is a summary of the JIRA issues addressed in the %(version)s release of Kafka. For full documentation of the
|
print("""<p>Below is a summary of the JIRA issues addressed in the %(version)s release of Kafka. For full documentation of the
|
||||||
release, a guide to get started, and information about the project, see the <a href="https://kafka.apache.org/">Kafka
|
release, a guide to get started, and information about the project, see the <a href="https://kafka.apache.org/">Kafka
|
||||||
project site</a>.</p>
|
project site</a>.</p>
|
||||||
|
|
||||||
|
@ -107,10 +108,10 @@ if __name__ == "__main__":
|
||||||
changes, performance changes, and any other changes that might impact your production deployment of Kafka.</p>
|
changes, performance changes, and any other changes that might impact your production deployment of Kafka.</p>
|
||||||
|
|
||||||
<p>The documentation for the most recent release can be found at
|
<p>The documentation for the most recent release can be found at
|
||||||
<a href="https://kafka.apache.org/documentation.html">https://kafka.apache.org/documentation.html</a>.</p>""" % { 'version': version, 'minor': minor_version_dotless }
|
<a href="https://kafka.apache.org/documentation.html">https://kafka.apache.org/documentation.html</a>.</p>""" % { 'version': version, 'minor': minor_version_dotless })
|
||||||
for itype, issues in by_group:
|
for itype, issues in by_group:
|
||||||
print "<h2>%s</h2>" % itype
|
print("<h2>%s</h2>" % itype)
|
||||||
print "<ul>"
|
print("<ul>")
|
||||||
for issue in issues:
|
for issue in issues:
|
||||||
print '<li>[<a href="%(link)s">%(key)s</a>] - %(summary)s</li>' % {'key': issue.key, 'link': issue_link(issue), 'summary': issue.fields.summary}
|
print('<li>[<a href="%(link)s">%(key)s</a>] - %(summary)s</li>' % {'key': issue.key, 'link': issue_link(issue), 'summary': issue.fields.summary})
|
||||||
print "</ul>"
|
print("</ul>")
|
||||||
|
|
Loading…
Reference in New Issue