diff --git a/BUILD.rst b/BUILD.rst index 81c463b..5c8e90d 100644 --- a/BUILD.rst +++ b/BUILD.rst @@ -1,42 +1,173 @@ Releasing StatusChecker ======================= -1. Execute tests using different Python implementations and versions. + +Using Invoke +~~~~~~~~~~~~ + +Invoke tasks are defined in the ``_ file and they are executed from +the command line like:: + + inv[oke] task [options] + +Run ``invoke`` without arguments for help. All tasks can be listed using +``invoke --list`` and each task's usage with ``invoke --help task``. + +Preparation +----------- + +1. Check that you are on the master branch and have nothing left to commit, + pull, or push:: + + git branch + git status + git pull --rebase + git push + +2. Clean up:: + + invoke clean + +3. Execute tests using different Python implementations and versions. See ``_ for instructions. -2. Set ``$VERSION`` shell variable to ease copy-pasting further commands:: +4. Set version information to a shell variable to ease copy-pasting further + commands. Add ``aN``, ``bN`` or ``rcN`` postfix if creating a pre-release:: + + VERSION= + + For example, ``VERSION=3.0.1`` or ``VERSION=3.1a2``. + +Release notes +------------- + +1. Set GitHub user information into shell variables to ease copy-pasting the + following command:: + + GITHUB_USERNAME= + GITHUB_PASSWORD= + + Alternatively, supply the credentials when running that command. + +2. Generate a template for the release notes:: + + invoke release-notes -w -v $VERSION -u $GITHUB_USERNAME -p $GITHUB_PASSWORD + + The ``-v $VERSION`` option can be omitted if `version is already set + `__. Omit the ``-w`` option if you just want to get release + notes printed to the console, not written to a file. + + When generating release notes for a preview release like ``3.0.2rc1``, + the list of issues is only going to contain issues with that label + (e.g. ``rc1``) or with a label of an earlier preview release (e.g. + ``alpha1``, ``beta2``). + +2. Fill the missing details in the generated release notes template. + +3. Make sure that issues have correct information: + + - All issues should have type (bug, enhancement or task) and priority set. + Notice that issues with the task type are automatically excluded from + the release notes. + - Issue priorities should be consistent. + - Issue titles should be informative. Consistency is good here too, but + no need to overdo it. + + If information needs to be added or edited, its better to edit it in the + issue tracker than in the generated release notes. This allows re-generating + the list of issues later if more issues are added. - VERSION=x.y +4. Add, commit and push:: -3. Update ``__version__`` in ``_:: + git add docs/releasenotes/robotstatuschecker-$VERSION.rst + git commit -m "Release notes for $VERSION" docs/releasenotes/robotstatuschecker-$VERSION.rst + git push + +5. Update later if necessary. Writing release notes is typically the biggest + task when generating releases, and getting everything done in one go is + often impossible. + + +Set version +----------- + +1. Set version information in ``_:: + + invoke set-version $VERSION + +2. Commit and push changes:: - inv set-version 1.5.0 - git diff # verify changes - git commit -m "Updated __version__ to $VERSION" robotstatuschecker.py + git commit -m "Updated version to $VERSION" robotstatuschecker.py git push -4. Tag:: - git tag -a $VERSION -m "Release $VERSION" && git push --tags -5. Create distribution:: +Tagging +------- + +1. Create an annotated tag and push it:: + + git tag -a v$VERSION -m "Release $VERSION" + git push --tags + +2. Add short release notes to GitHub's `releases page + `_ + with a link to the full release notes. + +Creating distributions +---------------------- + +1. Checkout the earlier created tag if necessary:: + + git checkout v$VERSION - python setup.py sdist register upload + This isn't necessary if continuing right after tagging_. -6. Verify that `PyPI pages `_ - look good. +2. Cleanup (again). This removes temporary files as well as ``build`` and + ``dist`` directories:: -7. Test that installation works:: + invoke clean - pip install robotstatuschecker --upgrade +3. Create source distribution and universal (i.e. Python 2 and 3 compatible) + `wheel `_:: -8. ``__version__`` back to ``devel``:: + python setup.py sdist bdist_wheel --universal + ls -l dist - inv set-version devel - git diff # verify changes - git commit -m "__version__ back to devel" robotstatuschecker.py + Distributions can be tested locally if needed. + +4. Upload distributions to PyPI:: + + twine upload dist/* + +5. Verify that project the page at `PyPI + `_ + looks good. + +6. Test installation (add ``--pre`` with pre-releases):: + + pip install --upgrade robotframework-seleniumlibrary + +Post actions +------------ + +1. Back to master if needed:: + + git checkout master + +2. Set dev version based on the previous version:: + + invoke set-version dev + git commit -m "Back to dev version" src/SeleniumLibrary/__init__.py git push -9. Advertise on mailing lists, `Twitter `_, + For example, ``1.2.3`` is changed to ``1.2.4.dev1`` and ``2.0.1a1`` + to ``2.0.1a2.dev1``. + +3. Close the `issue tracker milestone + `_. + Create also new milestone for the next release unless one exists already. + +4. Advertise on mailing lists, `Twitter `_, `LinkedIn `_, and elsewhere as needed. diff --git a/tasks.py b/tasks.py index 50f5839..0d27bf0 100644 --- a/tasks.py +++ b/tasks.py @@ -1,3 +1,4 @@ +import sys from pathlib import Path from invoke import task @@ -45,3 +46,43 @@ def set_version(ctx, version): def print_version(ctx): """Print the current project version.""" print(Version(path=VERSION_PATH, pattern=VERSION_PATTERN)) + + +@task +def release_notes(ctx, version=None, username=None, password=None, write=False): + """Generates release notes based on issues in the issue tracker. + Args: + version: Generate release notes for this version. If not given, + generated them for the current version. + username: GitHub username. + password: GitHub password. + write: When set to True, write release notes to a file overwriting + possible existing file. Otherwise just print them to the + terminal. + Username and password can also be specified using ``GITHUB_USERNAME`` and + ``GITHUB_PASSWORD`` environment variable, respectively. If they aren't + specified at all, communication with GitHub is anonymous and typically + pretty slow. + """ + version = Version(version, VERSION_PATH, VERSION_PATTERN) + folder = RELEASE_NOTES_PATH.parent.resolve() + folder.mkdir(parents=True, exist_ok=True) + file = RELEASE_NOTES_PATH if write else sys.stdout + generator = ReleaseNotesGenerator( + REPOSITORY, RELEASE_NOTES_TITLE, RELEASE_NOTES_INTRO + ) + generator.generate(version, username, password, file) + + +@task +def init_labels(ctx, username=None, password=None): + """Initialize project by setting labels in the issue tracker. + Args: + username: GitHub username. + password: GitHub password. + Username and password can also be specified using ``GITHUB_USERNAME`` and + ``GITHUB_PASSWORD`` environment variable, respectively. + Should only be executed once when taking ``rellu`` tooling to use or + when labels it uses have changed. + """ + initialize_labels(REPOSITORY, username, password) \ No newline at end of file