Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions scripts/release-notes/gen-ec-release-notes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#!/usr/bin/env python3

"""Engineering Candidate Release Note Tool

This script partially automates the process of publishing release
notes for engineering candidate builds of MicroShift.

It looks for the most recent RPM to have been published to the mirror,
and uses information encoded in that filename to determine the SHA of
the commit that was used for the build and the version number given to
it.

Then it looks for that tag in the local repository, and emits
instructions for tagging the commit if there is no tag already.

Then it uses gh to produce a draft release with a preamble that
includes download URLs and a body that is auto-generated by GitHub's
service based on the pull requests that have merged since the last
tagged release.

The script creates a draft release, which must be published by hand to
make it public. Open the link printed at the end of the script run and
use the web interface to review and then publish the release.

NOTE: To use this script, you must have the GitHub command line tool
"gh" installed and you must have enough privileges on the
openshift/microshift repository to create releases.

"""

import re
import subprocess
import textwrap
from urllib import request

VERSION="4.13"
RPM_LIST_URL=f"https://mirror.openshift.com/pub/openshift-v4/aarch64/microshift/ocp-dev-preview/latest-{VERSION}/el8/os/rpm_list"
MICROSHIFT_RPM_NAME_PREFIX=f"microshift-{VERSION}"

# An RPM filename looks like
# microshift-4.13.0~ec.3-202302130757.p0.ge636e15.assembly.ec.3.el8.aarch64.rpm
VERSION_RE = re.compile(
"""
microshift- # prefix
(?P<product_version>\d+\.\d+\.\d+) # product version
~ # separator
ec\.(?P<ec_number>\d+) # ec number
-
(?P<release_date>\d+)\. # date
p(?P<patch_num>\d+)\. # patch number
g(?P<commit_sha>[\dabcdef]+)\. # commit SHA prefix
""",
re.VERBOSE,
)


def main():
# Get the list of the latest RPMs for the VERSION of MicroShift.
rpm_list_response = request.urlopen(RPM_LIST_URL)
rpm_list = rpm_list_response.read().decode("utf-8").splitlines()

# Look for the RPM for MicroShift itself, with a name like
#
# Packages/microshift-4.13.0~ec.3-202302130757.p0.ge636e15.assembly.ec.3.el8__aarch64/microshift-4.13.0~ec.3-202302130757.p0.ge636e15.assembly.ec.3.el8.aarch64.rpm
#
# then parse out the EC version number and other details needed to
# build the release tag.
microshift_rpm_filename = None
for package_path in rpm_list:
parts = package_path.split("/")
if parts[-1].startswith(MICROSHIFT_RPM_NAME_PREFIX):
microshift_rpm_filename = parts[-1]
break
else:
raise RuntimeError(f"Did not find {MICROSHIFT_RPM_NAME_PREFIX} in {rpm_list}")

match = VERSION_RE.search(microshift_rpm_filename)
if match is None:
raise RuntimeError(f"Could not parse version info from '{microshift_rpm_filename}'")
rpm_version_details = match.groupdict()
product_version = rpm_version_details["product_version"]
ec_number = rpm_version_details["ec_number"]
commit_sha = rpm_version_details["commit_sha"]

# To be consistent with past releases, the release name should
# look like: 4.13.0-ec-2
release_name = "-".join([
rpm_version_details["product_version"],
"ec",
rpm_version_details["ec_number"],
])

# Check if the release already exists
print(f"Checking for {release_name}...")
try:
subprocess.run(["gh", "release", "view", release_name],
check=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
except subprocess.CalledProcessError:
print("Not found")
else:
print("Found, no work to do")
return

# Check for the tag to be present in the local git repository
try:
subprocess.run(["git", "show", release_name],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
check=True)
except subprocess.CalledProcessError:
print(f"Check for tag {release_name} on commit {commit_sha}")
print("")
print(f"git tag -s -m '{product_version} EC {ec_number}' {release_name} {commit_sha}")
print(f"git push origin {release_name}")
return

# Set up the release notes preamble with download links
notes = textwrap.dedent(f"""
This is a pre-release Engineering Candidate for {product_version}.

See the mirror for build artifacts:
- https://mirror.openshift.com/pub/openshift-v4/x86_64/microshift/ocp-dev-preview/{product_version}-ec.{ec_number}/
- https://mirror.openshift.com/pub/openshift-v4/aarch64/microshift/ocp-dev-preview/{product_version}-ec.{ec_number}/

""")

# Create draft release with message that includes download URLs and history
try:
subprocess.run(["gh", "release", "create",
"--draft",
"--prerelease",
"--notes", notes,
"--generate-notes",
release_name,
],
check=True)
except subprocess.CalledProcessError as err:
print(f"Failed to create the release: {err}")
return


if __name__ == "__main__":
main()