diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2cfdb2cb2..0e327e88a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: args: [] - id: mypy name: mypy, for Py2 - exclude: docs|tests + exclude: noxfile.py|docs|tests args: ["-2"] - repo: https://github.com/pre-commit/pygrep-hooks diff --git a/docs/html/development/release-process.rst b/docs/html/development/release-process.rst index a01ce71df..fc73657bd 100644 --- a/docs/html/development/release-process.rst +++ b/docs/html/development/release-process.rst @@ -101,6 +101,12 @@ Creating a new release setuptools) to ``Lib/ensurepip/_bundled``, removing the existing version, and adjusting the versions listed in ``Lib/ensurepip/__init__.py``. + +.. note:: + + Steps 3 to 6 are automated in ``nox -s release -- YY.N`` command. + + Creating a bug-fix release -------------------------- diff --git a/noxfile.py b/noxfile.py index 3ddd0c8aa..d990fa571 100644 --- a/noxfile.py +++ b/noxfile.py @@ -23,6 +23,9 @@ REQUIREMENTS = { "common-wheels": "tools/requirements/tests-common_wheels.txt", } +AUTHORS_FILE = "AUTHORS.txt" +VERSION_FILE = "src/pip/__init__.py" + def get_author_list(): """Get the list of authors from Git commits. @@ -78,6 +81,11 @@ def should_update_common_wheels(): return need_to_repopulate +def update_version_file(new_version): + with open(VERSION_FILE, "w", encoding="utf-8") as f: + f.write('__version__ = "{}"\n'.format(new_version)) + + # ----------------------------------------------------------------------------- # Development Commands # These are currently prototypes to evaluate whether we want to switch over @@ -174,7 +182,7 @@ def generate_authors(session): # Write our authors to the AUTHORS file session.log("Writing AUTHORS") - with io.open("AUTHORS.txt", "w", encoding="utf-8") as fp: + with io.open(AUTHORS_FILE, "w", encoding="utf-8") as fp: fp.write(u"\n".join(authors)) fp.write(u"\n") @@ -186,3 +194,50 @@ def generate_news(session): # You can pass 2 possible arguments: --draft, --yes session.run("towncrier", *session.posargs) + + +@nox.session +def release(session): + assert len(session.posargs) == 1, "A version number is expected" + new_version = session.posargs[0] + parts = new_version.split('.') + # Expect YY.N or YY.N.P + assert 2 <= len(parts) <= 3, parts + # Only integers + parts = list(map(int, parts)) + session.log("Generating commits for version {}".format(new_version)) + + session.log("Checking that nothing is staged") + # Non-zero exit code means that something is already staged + session.run("git", "diff", "--staged", "--exit-code", external=True) + + session.log(f"Updating {AUTHORS_FILE}") + generate_authors(session) + if subprocess.run(["git", "diff", "--exit-code"]).returncode: + session.run("git", "add", AUTHORS_FILE, external=True) + session.run( + "git", "commit", "-m", f"Updating {AUTHORS_FILE}", + external=True, + ) + else: + session.log(f"No update needed for {AUTHORS_FILE}") + + session.log("Generating NEWS") + session.install("towncrier") + session.run("towncrier", "--yes", "--version", new_version) + + session.log("Updating version") + update_version_file(new_version) + session.run("git", "add", VERSION_FILE, external=True) + session.run("git", "commit", "-m", f"Release {new_version}", external=True) + + session.log("Tagging release") + session.run( + "git", "tag", "-m", f"Release {new_version}", new_version, + external=True, + ) + + next_dev_version = f"{parts[0]}.{parts[1] + 1}.dev0" + update_version_file(next_dev_version) + session.run("git", "add", VERSION_FILE, external=True) + session.run("git", "commit", "-m", "Back to development", external=True) diff --git a/tests/conftest.py b/tests/conftest.py index b832ab8ca..7a54373b8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,6 +2,7 @@ import compileall import fnmatch import io import os +import re import shutil import subprocess import sys @@ -246,7 +247,10 @@ def virtualenv_template(request, tmpdir_factory, pip_src, install_egg_link(venv, 'setuptools', setuptools_install) pip_editable = Path(str(tmpdir_factory.mktemp('pip'))) / 'pip' shutil.copytree(pip_src, pip_editable, symlinks=True) - assert compileall.compile_dir(str(pip_editable), quiet=1) + # noxfile.py is Python 3 only + assert compileall.compile_dir( + str(pip_editable), quiet=1, rx=re.compile("noxfile.py$"), + ) subprocess.check_call([venv.bin / 'python', 'setup.py', '-q', 'develop'], cwd=pip_editable)