Skip to content

Commit

Permalink
Script-assisted release process proposal (AcademySoftwareFoundation#1421
Browse files Browse the repository at this point in the history
)

* clean up verify license
* fix licenses in place
* add license to examples
* freeze ci version script
* lint pass
* add make targets for making a release and starting a new dev cycle
* update fetch_contributors so that it updates the CONTRIBUTORS.md
* adding in bump version number script
* dev1 stripping/appending script
* add confirmation to makefile
* omit the otio-version json from the packages
* rename bump version target to be specific to minor version bumps
* add shuffle verison map
* add dev-suffix target
* add test-core

Co-authored-by: ssteinbach <[email protected]>
Signed-off-by: Michele Spina <[email protected]>
  • Loading branch information
2 people authored and MichaelPlug committed Aug 5, 2023
1 parent b0420a1 commit ff718cf
Show file tree
Hide file tree
Showing 11 changed files with 655 additions and 34 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ exclude contrib/opentimelineio_contrib/adapters/Makefile
exclude Makefile
exclude */.DS_Store
exclude .clang-format
exclude OTIO_VERSION.json
global-exclude *.pyc

prune maintainers
Expand Down
97 changes: 97 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ CLANG_FORMAT_PROG := $(shell command -v clang-format 2> /dev/null)
# AUTOPEP8_PROG := $(shell command -v autopep8 2> /dev/null)
TEST_ARGS=

GIT = git
GITSTATUS := $(shell git diff-index --quiet HEAD . 1>&2 2> /dev/null; echo $$?)


ifeq ($(VERBOSE), 1)
TEST_ARGS:=-v
endif
Expand Down Expand Up @@ -187,6 +191,7 @@ version-map:
@python src/py-opentimelineio/opentimelineio/console/autogen_version_map.py -i src/opentimelineio/CORE_VERSION_MAP.last.cpp --dryrun

version-map-update:
@echo "updating the CORE_VERSION_MAP..."
@python src/py-opentimelineio/opentimelineio/console/autogen_version_map.py -i src/opentimelineio/CORE_VERSION_MAP.last.cpp -o src/opentimelineio/CORE_VERSION_MAP.cpp

# generate documentation in html
Expand All @@ -198,3 +203,95 @@ doc-cpp:
@cd doxygen ; doxygen config/dox_config ; cd ..
@echo "wrote doxygen output to: doxygen/output/html/index.html"

# release related targets
confirm-release-intent:
ifndef OTIO_DO_RELEASE
$(error \
"If you are sure you want to perform a release, set OTIO_DO_RELEASE=1")
endif
@echo "Starting release process..."

check-git-status:
ifneq ($(GITSTATUS), 0)
$(error \
"Git repository is dirty, cannot create release. Run 'git status' \
for more info")
endif
@echo "Git status is clean, ready to proceed with release."

verify-license:
@echo "Verifying licenses in files..."
@python maintainers/verify_license.py -s .

fix-license:
@python maintainers/verify_license.py -s . -f

freeze-ci-versions:
@echo "freezing CI versions..."
@python maintainers/freeze_ci_versions.py -f

unfreeze-ci-versions:
@echo "unfreezing CI versions..."
@python maintainers/freeze_ci_versions.py -u

# needs to happen _before_ version-map-update so that version in
# CORE_VERSION_MAP does not have the .dev1 suffix at release time
remove-dev-suffix:
@echo "Removing .dev1 suffix"
@python maintainers/remove_dev_suffix.py -r

check-github-token:
ifndef OTIO_RELEASE_GITHUB_TOKEN
$(error \
OTIO_RELEASE_GITHUB_TOKEN is not set, unable to update contributors)
endif

update-contributors: check-github-token
@echo "Updating CONTRIBUTORS.md..."
@python maintainers/fetch_contributors.py \
--repo AcademySoftwareFoundation/OpenTimelineIO \
--token $(OTIO_RELEASE_GITHUB_TOKEN)

dev-python-install:
@python setup.py install

# make target for preparing a release candidate
release: \
confirm-release-intent \
check-git-status \
check-github-token \
verify-license \
freeze-ci-versions \
remove-dev-suffix \
format \
dev-python-install \
version-map-update \
test-core \
update-contributors
@echo "Release is ready. Commit, push and open a PR!"

# targets for creating a new version (after making a release, to start the next
# development cycle)
bump-otio-minor-version:
@python maintainers/bump_version_number.py -i minor

shuffle-core-version-map:
@cp -f src/opentimelineio/CORE_VERSION_MAP.cpp \
src/opentimelineio/CORE_VERSION_MAP.last.cpp
@echo "set the current version map as the next one"

add-dev-suffix:
@echo "Adding .dev1 suffix"
@python maintainers/remove_dev_suffix.py -a

# make target for starting a new version (after a release is completed)
start-dev-new-minor-version: \
check-git-status \
unfreeze-ci-versions \
bump-otio-minor-version \
shuffle-core-version-map \
add-dev-suffix \
dev-python-install \
version-map-update \
test-core
@echo "New version made. Commit, push and open a PR!"
1 change: 1 addition & 0 deletions OTIO_VERSION.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version": ["0", "15", "0"]}
2 changes: 2 additions & 0 deletions examples/sample_plugin/otio_counter/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the OpenTimelineIO project
import pkg_resources

from opentimelineio.plugins import manifest
Expand Down
2 changes: 2 additions & 0 deletions examples/sample_plugin/otio_counter/adapter.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the OpenTimelineIO project
import opentimelineio as otio

"""
Expand Down
2 changes: 2 additions & 0 deletions examples/sample_plugin/setup.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the OpenTimelineIO project
from setuptools import setup

"""
Expand Down
158 changes: 158 additions & 0 deletions maintainers/bump_version_number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#!/usr/bin/env python
#
# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the OpenTimelineIO project

__doc__ = """Manage and apply the version in the OTIO_VERSION.json file"""

import argparse
import sys
import json

OTIO_VERSION_JSON_PATH = "OTIO_VERSION.json"


def version():
with open(OTIO_VERSION_JSON_PATH, 'r') as fi:
return json.load(fi)['version']


def _parsed_args():
parser = argparse.ArgumentParser(
description='Fetch a list of contributors for a given GitHub repo.'
)

op_grp = parser.add_mutually_exclusive_group(required=True)
op_grp.add_argument(
"-i",
"--increment",
type=str,
default=None,
choices=("major", "minor", "patch"),
help="Increment either the major or minor version number."
)
op_grp.add_argument(
"-s",
"--set",
type=str,
default=None,
nargs=3,
help="Set the version string, in the form of MAJOR MINOR PATCH"
)
op_grp.add_argument(
"-q",
"--query",
default=False,
action="store_true",
help="Query/print the current version without changing it"
)
parser.add_argument(
"-d",
"--dryrun",
default=False,
action="store_true",
help="Perform actions but modify no files on disk."
)
return parser.parse_args()


def main():
args = _parsed_args()

major, minor, patch = (int(v) for v in version())

if args.increment == "major":
major += 1
minor = 0
patch = 0
elif args.increment == "minor":
minor += 1
patch = 0
elif args.increment == "patch":
patch += 1
elif args.set:
major, minor, patch = args.set
elif args.query:
print(".".join(str(v) for v in (major, minor, patch)))
return

print("Setting version to: {}.{}.{}".format(major, minor, patch))

# update the OTIO_VERSION file
with open(OTIO_VERSION_JSON_PATH, "w") as fo:
fo.write(
json.dumps({"version": [str(v) for v in (major, minor, patch)]})
)
print("Updated {}".format(OTIO_VERSION_JSON_PATH))

# update the CMakeLists.txt
with open("CMakeLists.txt", 'r') as fi:
cmake_input = fi.read()

cmake_output = []
key_map = {"MAJOR": major, "MINOR": minor, "PATCH": patch}
for ln in cmake_input.split("\n"):
for label, new_value in key_map.items():
if "set(OTIO_VERSION_{} \"".format(label) in ln:
cmake_output.append(
"set(OTIO_VERSION_{} \"{}\")".format(label, new_value)
)
break
else:
cmake_output.append(ln)

with open("CMakeLists.txt", 'w') as fo:
fo.write("\n".join(cmake_output))
print("Updated {}".format("CMakeLists.txt"))

# update the setup.py
with open("setup.py", 'r') as fi:
setup_input = fi.read()

setup_output = []
for ln in setup_input.split("\n"):
if "\"version\": " in ln:

setup_output.append(
" \"version\": \"{}.{}.{}{}\",".format(
major,
minor,
patch,
(".dev1" in ln) and ".dev1" or ""
)
)
else:
setup_output.append(ln)

with open("setup.py", 'w') as fo:
fo.write("\n".join(setup_output))
print("Updated {}".format("setup.py"))


def add_suffix(content, version):
if version not in content:
sys.stderr.write(
"Version {} not found, suffix may have already been "
"added.\n".format(version)
)
return False

print("adding suffix, version will be: {}".format(version + ".dev1"))
content.replace(version, version + ".dev1")
return True


def remove_suffix(content, version):
if version + '.dev1' not in content:
sys.stderr.write(
"Version+Suffix {} not found, suffix may have already been "
"removed.\n".format(version + '.dev1')
)
return False

content.replace(version + ' .dev1', version)
return True


if __name__ == "__main__":
main()
Loading

0 comments on commit ff718cf

Please sign in to comment.