Revamp the release script: drop invoke and use tox directly
Following the lead from tox, use a simple Python script instead of depending on ``invoke``. Other changes: * Some colors using ``colorama``. * Run ``pre-commit`` before the final commit to ensure everything is neatly formatted. * Drop generating local tag: legacy from the time we used ``devpi`` as staging area, currently we no longer use it, and we should push a tag from the last HEAD of the PR always to ensure it is correct.
This commit is contained in:
parent
0565a7a4e1
commit
a0b0c37feb
|
@ -18,19 +18,11 @@ taking a lot of time to make a new one.
|
||||||
|
|
||||||
Ensure your are in a clean work tree.
|
Ensure your are in a clean work tree.
|
||||||
|
|
||||||
#. Install development dependencies in a virtual environment with::
|
#. Using ``tox``, generate docs, changelog, announcements::
|
||||||
|
|
||||||
$ pip3 install -U -r tasks/requirements.txt
|
$ tox -e release -- <VERSION>
|
||||||
|
|
||||||
#. Generate docs, changelog, announcements, and a **local** tag::
|
|
||||||
|
|
||||||
$ invoke generate.pre-release <VERSION>
|
|
||||||
|
|
||||||
#. Execute pre-commit on all files to ensure the docs are conformant and commit your results::
|
|
||||||
|
|
||||||
$ pre-commit run --all-files
|
|
||||||
$ git commit -am "Fix files with pre-commit"
|
|
||||||
|
|
||||||
|
This will generate a commit with all the changes ready for pushing.
|
||||||
|
|
||||||
#. Open a PR for this branch targeting ``master``.
|
#. Open a PR for this branch targeting ``master``.
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
"""
|
"""
|
||||||
Invoke development tasks.
|
Invoke development tasks.
|
||||||
"""
|
"""
|
||||||
|
import argparse
|
||||||
|
from colorama import init, Fore
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from subprocess import check_output, check_call
|
from subprocess import check_output, check_call, call
|
||||||
|
|
||||||
import invoke
|
|
||||||
|
|
||||||
|
|
||||||
@invoke.task(help={"version": "version being released"})
|
def announce(version):
|
||||||
def announce(ctx, version):
|
|
||||||
"""Generates a new release announcement entry in the docs."""
|
"""Generates a new release announcement entry in the docs."""
|
||||||
# Get our list of authors
|
# Get our list of authors
|
||||||
stdout = check_output(["git", "describe", "--abbrev=0", "--tags"])
|
stdout = check_output(["git", "describe", "--abbrev=0", "--tags"])
|
||||||
|
@ -38,7 +37,7 @@ def announce(ctx, version):
|
||||||
"../doc/en/announce/release-{}.rst".format(version)
|
"../doc/en/announce/release-{}.rst".format(version)
|
||||||
)
|
)
|
||||||
target.write_text(text, encoding="UTF-8")
|
target.write_text(text, encoding="UTF-8")
|
||||||
print("[generate.announce] Generated {}".format(target.name))
|
print(f"{Fore.CYAN}[generate.announce] {Fore.RESET}Generated {target.name}")
|
||||||
|
|
||||||
# Update index with the new release entry
|
# Update index with the new release entry
|
||||||
index_path = Path(__file__).parent.joinpath("../doc/en/announce/index.rst")
|
index_path = Path(__file__).parent.joinpath("../doc/en/announce/index.rst")
|
||||||
|
@ -50,69 +49,63 @@ def announce(ctx, version):
|
||||||
if line != new_line:
|
if line != new_line:
|
||||||
lines.insert(index, new_line)
|
lines.insert(index, new_line)
|
||||||
index_path.write_text("\n".join(lines) + "\n", encoding="UTF-8")
|
index_path.write_text("\n".join(lines) + "\n", encoding="UTF-8")
|
||||||
print("[generate.announce] Updated {}".format(index_path.name))
|
print(
|
||||||
|
f"{Fore.CYAN}[generate.announce] {Fore.RESET}Updated {index_path.name}"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
"[generate.announce] Skip {} (already contains release)".format(
|
f"{Fore.CYAN}[generate.announce] {Fore.RESET}Skip {index_path.name} (already contains release)"
|
||||||
index_path.name
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
|
|
||||||
check_call(["git", "add", str(target)])
|
check_call(["git", "add", str(target)])
|
||||||
|
|
||||||
|
|
||||||
@invoke.task()
|
def regen():
|
||||||
def regen(ctx):
|
|
||||||
"""Call regendoc tool to update examples and pytest output in the docs."""
|
"""Call regendoc tool to update examples and pytest output in the docs."""
|
||||||
print("[generate.regen] Updating docs")
|
print(f"{Fore.CYAN}[generate.regen] {Fore.RESET}Updating docs")
|
||||||
check_call(["tox", "-e", "regen"])
|
check_call(["tox", "-e", "regen"])
|
||||||
|
|
||||||
|
|
||||||
@invoke.task()
|
def fix_formatting():
|
||||||
def make_tag(ctx, version):
|
"""Runs pre-commit in all files to ensure they are formatted correctly"""
|
||||||
"""Create a new, local tag for the release, only if the repository is clean."""
|
print(
|
||||||
from git import Repo
|
f"{Fore.CYAN}[generate.fix linting] {Fore.RESET}Fixing formatting using pre-commit"
|
||||||
|
)
|
||||||
repo = Repo(".")
|
call(["pre-commit", "run", "--all-files"])
|
||||||
if repo.is_dirty():
|
|
||||||
print("Current repository is dirty. Please commit any changes and try again.")
|
|
||||||
raise invoke.Exit(code=2)
|
|
||||||
|
|
||||||
tag_names = [x.name for x in repo.tags]
|
|
||||||
if version in tag_names:
|
|
||||||
print("[generate.make_tag] Delete existing tag {}".format(version))
|
|
||||||
repo.delete_tag(version)
|
|
||||||
|
|
||||||
print("[generate.make_tag] Create tag {}".format(version))
|
|
||||||
repo.create_tag(version)
|
|
||||||
|
|
||||||
|
|
||||||
@invoke.task(help={"version": "version being released"})
|
def pre_release(version):
|
||||||
def pre_release(ctx, version):
|
|
||||||
"""Generates new docs, release announcements and creates a local tag."""
|
"""Generates new docs, release announcements and creates a local tag."""
|
||||||
announce(ctx, version)
|
announce(version)
|
||||||
regen(ctx)
|
regen()
|
||||||
changelog(ctx, version, write_out=True)
|
changelog(version, write_out=True)
|
||||||
|
fix_formatting()
|
||||||
|
|
||||||
msg = "Preparing release version {}".format(version)
|
msg = "Preparing release version {}".format(version)
|
||||||
check_call(["git", "commit", "-a", "-m", msg])
|
check_call(["git", "commit", "-a", "-m", msg])
|
||||||
|
|
||||||
make_tag(ctx, version)
|
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print("[generate.pre_release] Please push your branch and open a PR.")
|
print(f"{Fore.CYAN}[generate.pre_release] {Fore.GREEN}All done!")
|
||||||
|
print()
|
||||||
|
print(f"Please push your branch and open a PR.")
|
||||||
|
|
||||||
|
|
||||||
@invoke.task(
|
def changelog(version, write_out=False):
|
||||||
help={
|
|
||||||
"version": "version being released",
|
|
||||||
"write_out": "write changes to the actual changelog",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
def changelog(ctx, version, write_out=False):
|
|
||||||
if write_out:
|
if write_out:
|
||||||
addopts = []
|
addopts = []
|
||||||
else:
|
else:
|
||||||
addopts = ["--draft"]
|
addopts = ["--draft"]
|
||||||
check_call(["towncrier", "--yes", "--version", version] + addopts)
|
check_call(["towncrier", "--yes", "--version", version] + addopts)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
init(autoreset=True)
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("version", help="Release version")
|
||||||
|
options = parser.parse_args()
|
||||||
|
pre_release(options.version)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -1,10 +0,0 @@
|
||||||
"""
|
|
||||||
Invoke tasks to help with pytest development and release process.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import invoke
|
|
||||||
|
|
||||||
from . import generate
|
|
||||||
|
|
||||||
|
|
||||||
ns = invoke.Collection(generate)
|
|
|
@ -1,6 +0,0 @@
|
||||||
-e .
|
|
||||||
gitpython
|
|
||||||
invoke
|
|
||||||
towncrier
|
|
||||||
tox
|
|
||||||
wheel
|
|
14
tox.ini
14
tox.ini
|
@ -176,6 +176,20 @@ commands =
|
||||||
coverage report -m
|
coverage report -m
|
||||||
coveralls
|
coveralls
|
||||||
|
|
||||||
|
[testenv:release]
|
||||||
|
decription = do a release, required posarg of the version number
|
||||||
|
basepython = python3.6
|
||||||
|
skipsdist = True
|
||||||
|
usedevelop = True
|
||||||
|
passenv = *
|
||||||
|
deps =
|
||||||
|
colorama
|
||||||
|
gitpython
|
||||||
|
pre-commit
|
||||||
|
towncrier
|
||||||
|
wheel
|
||||||
|
commands = python scripts/release.py {posargs}
|
||||||
|
|
||||||
[pytest]
|
[pytest]
|
||||||
minversion = 2.0
|
minversion = 2.0
|
||||||
plugins = pytester
|
plugins = pytester
|
||||||
|
|
Loading…
Reference in New Issue