From 56af5bffad374e954be12062f4a931a35c139e6f Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Wed, 10 Jun 2020 16:38:26 -0700 Subject: [PATCH 1/3] chore: moving code to prepare the release to eachdist --- scripts/eachdist.py | 123 +++++++++++++++++++++++++++++++++++++ scripts/prepare_release.sh | 62 +++---------------- 2 files changed, 132 insertions(+), 53 deletions(-) diff --git a/scripts/eachdist.py b/scripts/eachdist.py index 15b9b8edcbb..e76c15dea65 100755 --- a/scripts/eachdist.py +++ b/scripts/eachdist.py @@ -1,12 +1,15 @@ #!/usr/bin/env python3 import argparse +import os +import re import shlex import shutil import subprocess import sys from collections import namedtuple from configparser import ConfigParser +from datetime import datetime from inspect import cleandoc from itertools import chain from pathlib import Path, PurePath @@ -236,6 +239,15 @@ def setup_instparser(instparser): "pytestargs", nargs=argparse.REMAINDER, help=extraargs_help("pytest") ) + releaseparser = subparsers.add_parser( + "release", help="Prepares release, used by maintainers and CI", + ) + releaseparser.set_defaults(func=release_args) + releaseparser.add_argument("--version", required=True) + releaseparser.add_argument( + "releaseargs", nargs=argparse.REMAINDER, help=extraargs_help("pytest") + ) + return parser.parse_args(args) @@ -503,6 +515,117 @@ def lint_args(args): ) +def update_changelog(path, version, new_entry): + unreleased_changes = 0 + try: + with open(path) as changelog: + text = changelog.read() + if version in text: + raise AttributeError( + "{} already contans version {}".format(path, version) + ) + with open(path) as changelog: + for line in changelog: + if line.startswith("## Unreleased"): + unreleased_changes = 0 + elif line.startswith("## "): + break + elif len(line.strip()) > 0: + unreleased_changes += 1 + + except FileNotFoundError: + print("file missing: {}".format(path)) + return + + if unreleased_changes > 0: + print("updating: {}".format(path)) + text = re.sub("## Unreleased", new_entry, text) + with open(path, "w") as changelog: + changelog.write(text) + + +def update_changelogs(targets, version): + print("updating CHANGELOG") + today = datetime.now().strftime("%Y-%m-%d") + new_entry = "## Unreleased\n\n## Version {}\n\nReleased {}".format( + version, today + ) + errors = 0 + for target in targets: + try: + update_changelog( + "{}/CHANGELOG.md".format(target), version, new_entry + ) + except Exception as e: + print(str(e)) + errors += 1 + + if errors != 0: + sys.exit(1) + + +def find(name, path): + for root, dirs, files in os.walk(path): + if name in files: + return os.path.join(root, name) + + +def update_version_files(targets, version): + print("updating version.py files") + update_files( + targets, + version, + "version.py", + "__version__ .*", + '__version__ = "{}"'.format(version), + ) + + +def update_dependencies(targets, version): + print("updating dependencies") + update_files( + targets, + version, + "setup.cfg", + r"(opentelemetry-.*)= (.*)", + r"\1= " + version, + ) + + +def update_files(targets, version, filename, search, replace): + errors = 0 + for target in targets: + curr_file = find(filename, target) + if curr_file is None: + print("file missing: {}/{}".format(target, filename)) + continue + + with open(curr_file) as f: + text = f.read() + + if version in text: + print("{} already contans version {}".format(curr_file, version)) + errors += 1 + continue + + with open(curr_file, "w") as f: + f.write(re.sub(search, replace, text)) + + if errors != 0: + sys.exit(1) + + +def release_args(args): + print("preparing release") + + rootpath = find_projectroot() + targets = list(find_targets_unordered(rootpath)) + version = args.version + update_dependencies(targets, version) + update_version_files(targets, version) + update_changelogs(targets, version) + + def test_args(args): clean_remainder_args(args.pytestargs) execute_args( diff --git a/scripts/prepare_release.sh b/scripts/prepare_release.sh index a74bd17a8ab..e75278eb5e5 100755 --- a/scripts/prepare_release.sh +++ b/scripts/prepare_release.sh @@ -21,57 +21,6 @@ if [[ ! "${VERSION}" =~ ^([0-9])(\.*[0-9]{1,5}[a-b]*){1,3}$ ]]; then exit 1 fi -function update_version_file() { - errors=0 - for f in `find . -name version.py`; do - # check if version is already in version.py - grep -q ${VERSION} $f; - rc=$? - if [ $rc == 0 ]; then - errors=1 - echo "${f} already contains ${VERSION}" - continue - fi - # update version.py - perl -i -pe "s/__version__.*/__version__ = \"${VERSION}\"/g" ${f}; - git add ${f}; - echo "Updating ${f}" - done - if [ ${errors} != 0 ]; then - echo "::set-output name=version_updated::0" - exit 0 - fi -} - -function update_changelog() { - errors=0 - RELEASE_DATE=`date +%F` - for f in `find . -name CHANGELOG.md`; do - # check if version is already in CHANGELOG - grep -q ${VERSION} $f; - rc=$? - if [ $rc == 0 ]; then - errors=1 - echo "${f} already contains ${VERSION}" - continue - fi - # check if changelog contains any new details - changes=`sed -n '/## Unreleased/,/^##/p' ${f} | grep -v '^##' | wc -w | awk '{$1=$1;print}'` - if [ ${changes} != "0" ]; then - # update CHANGELOG.md - perl -i -pe 's/## Unreleased.*/## Unreleased\n\n## '${VERSION}'\n\nReleased '${RELEASE_DATE}'/' ${f}; - git add ${f}; - echo "Updating ${f}" - else - echo "Skipping ${f}, no changes detected" - fi - done - if [ ${errors} != 0 ]; then - echo "::set-output name=version_updated::0" - exit 0 - fi -} - # create the release branch git fetch origin master git checkout master @@ -81,8 +30,15 @@ git push origin release/${VERSION} # create a temporary branch to create a PR for updated version and changelogs git checkout -b release/${VERSION}-auto -update_version_file -update_changelog +./scripts/eachdist.py release --version ${VERSION} +rc=$? +if [ $rc != 0 ]; then + echo "::set-output name=version_updated::0" + exit 0 +fi + +git add **/version.py **/setup.cfg **/CHANGELOG.md + git commit -m "updating changelogs and version to ${VERSION}" echo "Time to create a release, here's a sample title:" From fb83500c24183414a114b333edf9b85956a45041 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Wed, 10 Jun 2020 17:14:21 -0700 Subject: [PATCH 2/3] fix lint --- scripts/eachdist.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/scripts/eachdist.py b/scripts/eachdist.py index e76c15dea65..81ff85fff89 100755 --- a/scripts/eachdist.py +++ b/scripts/eachdist.py @@ -556,8 +556,8 @@ def update_changelogs(targets, version): update_changelog( "{}/CHANGELOG.md".format(target), version, new_entry ) - except Exception as e: - print(str(e)) + except Exception as err: # pylint: disable=broad-except + print(str(err)) errors += 1 if errors != 0: @@ -565,9 +565,10 @@ def update_changelogs(targets, version): def find(name, path): - for root, dirs, files in os.walk(path): + for root, _, files in os.walk(path): if name in files: return os.path.join(root, name) + return None def update_version_files(targets, version): @@ -600,16 +601,16 @@ def update_files(targets, version, filename, search, replace): print("file missing: {}/{}".format(target, filename)) continue - with open(curr_file) as f: - text = f.read() + with open(curr_file) as _file: + text = _file.read() if version in text: print("{} already contans version {}".format(curr_file, version)) errors += 1 continue - with open(curr_file, "w") as f: - f.write(re.sub(search, replace, text)) + with open(curr_file, "w") as _file: + _file.write(re.sub(search, replace, text)) if errors != 0: sys.exit(1) From bd1e4ed9147ae4afac5ea02ee308d5e0955b8a68 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Thu, 11 Jun 2020 14:33:25 -0700 Subject: [PATCH 3/3] review feedback --- scripts/eachdist.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/eachdist.py b/scripts/eachdist.py index 81ff85fff89..c8b7f7c3fc6 100755 --- a/scripts/eachdist.py +++ b/scripts/eachdist.py @@ -516,28 +516,28 @@ def lint_args(args): def update_changelog(path, version, new_entry): - unreleased_changes = 0 + unreleased_changes = False try: with open(path) as changelog: text = changelog.read() - if version in text: + if "## Version {}".format(version) in text: raise AttributeError( "{} already contans version {}".format(path, version) ) with open(path) as changelog: for line in changelog: if line.startswith("## Unreleased"): - unreleased_changes = 0 + unreleased_changes = False elif line.startswith("## "): break elif len(line.strip()) > 0: - unreleased_changes += 1 + unreleased_changes = True except FileNotFoundError: print("file missing: {}".format(path)) return - if unreleased_changes > 0: + if unreleased_changes: print("updating: {}".format(path)) text = re.sub("## Unreleased", new_entry, text) with open(path, "w") as changelog: @@ -550,7 +550,7 @@ def update_changelogs(targets, version): new_entry = "## Unreleased\n\n## Version {}\n\nReleased {}".format( version, today ) - errors = 0 + errors = False for target in targets: try: update_changelog( @@ -558,9 +558,9 @@ def update_changelogs(targets, version): ) except Exception as err: # pylint: disable=broad-except print(str(err)) - errors += 1 + errors = True - if errors != 0: + if errors: sys.exit(1) @@ -594,7 +594,7 @@ def update_dependencies(targets, version): def update_files(targets, version, filename, search, replace): - errors = 0 + errors = False for target in targets: curr_file = find(filename, target) if curr_file is None: @@ -606,13 +606,13 @@ def update_files(targets, version, filename, search, replace): if version in text: print("{} already contans version {}".format(curr_file, version)) - errors += 1 + errors = True continue with open(curr_file, "w") as _file: _file.write(re.sub(search, replace, text)) - if errors != 0: + if errors: sys.exit(1)