Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document release process in CONTRIBUTING.md and make it slightly easier #2050

Merged
54 changes: 54 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,60 @@ begin contributing to to the project.
1. On GitHub, send a New pull request to the main repository's master branch. GitHub
pull requests are the expected method of code collaboration on this project.

Release Process
---------------
1. Pre-Release Steps
1. Checkout the master branch and pull down the latest changes
```bash
git checkout master
# Discard all local changes
git restore .
# Merge changes from upstream
git pull upstream master
```
1. Build master to ensure it is in a good state and ready for release
```bash
tox -e clean
tox
```
1. Ensure no commits are made on ni/nimi-python/master until the release is complete
1. Create and checkout a branch for release-related changes
1. Update [CHANGELOG.md](./CHANGELOG.md)
* Delete empty (i.e. No changes) sub-sections under "Unreleased" section
* Change the "Unreleased" header to the version of the release
* Change [Unreleased] in TOC to the version of the release
* Commit to branch
1. Update release versions
* `python3 tools/build_release.py --update --release`
* For each module, this will drop the .devN from our versions in config_addon.py and update the LATEST_RELEASE versions to match.
* Commit to branch
1. Clean and build to update generated files with new version
* `python3 tools/build_release.py --build`
* Commit to branch
1. Create a pull request
* It should contain all the changes made so far
* Get the pull request reviewed but DO NOT merge to master yet
1. Release Steps
1. Wait until the pull request has been approved
1. Upload the releases to PyPI
* `python3 tools/build_release.py --upload`
* You will need to type in your PyPI credentials
1. Merge the pull request to origin/master
1. Create a release on GitHub using the portion from the changelog for this release for the description
* Add the ZIP files under `generated/examples` for each module as a release artifact.
1. Post-Release Steps
1. Create and checkout another branch for post-release changes
1. Update the module versions
* `python3 tools/build_release.py --update`
* This will update the version to X.X.(N+1).dev0
* Commit to branch
1. Clean and build to update generated files with new version
* `python3 tools/build_release.py --build`
* Commit to branch
1. Update changelog
* Copy Unreleased section from bottom of changelog to the top and add a link to it in the TOC
* Commit to branch
1. Create a pull request containing post-release changes and get it merged

Developer Certificate of Origin (DCO)
-------------------------------------
Expand Down
44 changes: 4 additions & 40 deletions tools/build_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,44 +27,8 @@ def main():
usage = """Release script
Prereqs
* Be able to build locally
* `pip install --upgrade twine tox` into whichever Python 2.7 you use to build

Steps
* Build master to ensure it is in a good state and ready for release
* Ensure no commits are made on master until the release is complete
* Create and checkout a branch for release-related changes
* Update CHANGELOG.md
* Delete empty (i.e. No changes) sub-sections under "Unreleased" section
* Change the "Unreleased" header to the version of the release
* Change [Unreleased] in TOC to the version of the release
* Commit to branch
* Update contents of src/<driver>/LATEST_RELEASE with the versions of each module being released by dropping the '.dev0' suffix.
* `python3 tools/build_release.py --update --release`
* This will update all the versions to remove any '.devN'
* Commit to branch
* `python3 tools/build_release.py --build`
* Clean and build to update generated files with new version
* Commit to branch
* Create a pull request
* It should contain all the changes made so far
* Get the pull request reviewed but DO NOT merge to master yet
* `python3 tools/build_release.py --upload`
* Upload to PyPI - you will need to type in your credentials
* Merge the pull request to origin/master
* Create a release on GitHub using the portion from the changelog for this release for the description
* Add the ZIP files under `generated/examples` for each module as a release artifact.
* Create and checkout another branch for post-release changes
* `python3 tools/build_release.py --update`
* This will update the version to X.X.(N+1).dev0
* Commit to branch
* `python3 tools/build_release.py --build`
* Clean and Build to update generated files
* Commit to branch
* Update changelog
* Copy Unreleased section from bottom of changelog to the top and add a link to it in the TOC
* Commit to branch
* Create a pull request containing post-release changes and get it merged

* `pip install --upgrade twine tox` into whichever Python you use to build
Steps: see "Release Process" section of CONTRIBUTING.md
"""
parser = argparse.ArgumentParser(description=usage, formatter_class=CustomFormatter)

Expand Down Expand Up @@ -107,8 +71,8 @@ def main():
logging.info('Updating versions')

for d in drivers_to_update:
logging.info(pp.pformat(python_cmd + ['tools/updateReleaseInfo.py', '--src-file', f'src/{d}/metadata/config_addon.py', ] + passthrough_params))
check_call(python_cmd + ['tools/updateReleaseInfo.py', '--src-file', f'src/{d}/metadata/config_addon.py', ] + passthrough_params)
logging.info(pp.pformat(python_cmd + ['tools/updateReleaseInfo.py', '--src-folder', f'src/{d}', ] + passthrough_params))
check_call(python_cmd + ['tools/updateReleaseInfo.py', '--src-folder', f'src/{d}', ] + passthrough_params)

if args.build:
logging.info('Clean and build')
Expand Down
18 changes: 14 additions & 4 deletions tools/updateReleaseInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import argparse
from configure_logging import configure_logging
import logging
import os
import pprint
import re

Expand All @@ -12,11 +13,11 @@
def main():
# Setup the required arguments for this script
usage = """
Update version when it is a dev version. I.e. X.Y.Z.devN to X.Y.Z.dev(N+1)
Update version in files. Example: X.Y.Z.devN to X.Y.Z
"""
parser = argparse.ArgumentParser(description=usage)
file_group = parser.add_argument_group("Input and Output files")
file_group.add_argument("--src-file", action="store", required=True, help="Source file")
file_group.add_argument("--src-folder", action="store", required=True, help="Source folder")
file_group.add_argument("--release", action="store_true", default=False, help="This is a release build, so only remove '.devN'. Error if not there")

verbosity_group = parser.add_argument_group("Verbosity, Logging & Debugging")
Expand All @@ -34,7 +35,8 @@ def main():

logging.info(pp.pformat(args))

with open(args.src_file) as content_file:
metadata_file = os.path.join(args.src_folder, "metadata", "config_addon.py")
with open(metadata_file) as content_file:
contents = content_file.read()

module_dev_version_re = re.compile(r"'module_version': '(\d+\.\d+\.\d+)\.dev(\d+)'")
Expand All @@ -43,6 +45,7 @@ def main():
if args.release:
logging.info('Dev version found, updating {0}.dev{1} to {0}'.format(m.group(1), int(m.group(2))))
contents = module_dev_version_re.sub(f"'module_version': '{m.group(1)}'", contents)
new_version = m.group(1)
else:
logging.info('Dev version found, updating {0}.dev{1} to {0}.dev{2}'.format(m.group(1), int(m.group(2)), int(m.group(2)) + 1))
contents = module_dev_version_re.sub(f"'module_version': '{m.group(1)}.dev{int(m.group(2)) + 1}'", contents)
Expand All @@ -54,9 +57,16 @@ def main():
contents = module_version_re.sub(f"'module_version': '{m.group(1)}{int(m.group(2)) + 1}.dev0'", contents)

if not args.preview:
with open(args.src_file, 'w') as content_file:
with open(metadata_file, 'w') as content_file:
content_file.write(contents)

if args.release and "nifake" not in args.src_folder:
latest_release_file = os.path.join(args.src_folder, "LATEST_RELEASE")
logging.info(f'Updating version in {latest_release_file} to {new_version}.')
if not args.preview:
with open(latest_release_file, 'w') as content_file:
content_file.write(f'{new_version}\n')


if __name__ == '__main__':
main()
Expand Down
Loading