From d1fe0e7c0b59e57ef794fabed63f7fa3ff04bb33 Mon Sep 17 00:00:00 2001 From: Martijn Pieters Date: Sun, 1 Dec 2019 13:14:03 +0000 Subject: [PATCH 1/4] Check towncrier fragment names and show towncrier output when checking docs. --- dodo.py | 50 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/dodo.py b/dodo.py index bc02e93..c47747d 100644 --- a/dodo.py +++ b/dodo.py @@ -8,6 +8,7 @@ from pathlib import Path from doit.action import CmdAction +from doit.exceptions import TaskFailed from doit.tools import Interactive, run_once DOIT_CONFIG = {"default_tasks": ["all"], "minversion": "0.31.0"} @@ -26,15 +27,29 @@ def _path_sortkey(p): return (p.is_dir(), *p.parts) +def is_towncrier_fragment(path): + parts = path.name.split(".") + return ( + len(parts) > 1 + and parts[0].isdigit() + and parts[0].isascii() + and parts[1] in {"feature", "bugfix", "doc", "removal", "misc"} + ) + + # source files THIS = Path(__file__).resolve() HERE = THIS.parent +PYPROJECT = HERE / "pyproject.toml" SRC_PATH = HERE / "src" SRC_FILES = sorted(SRC_PATH.rglob("*.py"), key=_path_sortkey) TESTS_PATH = HERE / "tests" TESTS_FILES = sorted(TESTS_PATH.rglob("*.py"), key=_path_sortkey) DOC_PATH = HERE / "docs" RST_FILES = sorted(DOC_PATH.rglob("*.rst"), key=_path_sortkey) +CHANGELOG_PATH = HERE / "changelog.d" +CHANGELOG_TEMPLATE = CHANGELOG_PATH / "towncrier_template.md" +CHANGELOG_FRAGMENTS = sorted(filter(is_towncrier_fragment, CHANGELOG_PATH.iterdir())) ALL_PY_FILES = sorted( [THIS, *SRC_FILES, *TESTS_FILES, *DOC_PATH.glob("*.py")], key=_path_sortkey @@ -50,8 +65,7 @@ def _path_sortkey(p): DIST_FILES = sorted( [*DIST_PATH.glob("*.tar.gz"), *DIST_PATH.glob("*.whl")], key=_path_sortkey ) - -# File lists +CHANGELOG = HERE / "CHANGELOG.md" def with_poetry(*actions): @@ -149,10 +163,11 @@ def task_tox(): } -def task_docs_spelling(): - """Check documentation spelling""" +def task_docs_checks(): + """Check documentation spelling and towncrier handling""" make_cmd = with_poetry(["make", "spelling"])[0] - return { + yield { + "name": "docs_spelling", "setup": ["devsetup"], "actions": [CmdAction(make_cmd, cwd=DOC_PATH, shell=False)], "file_dep": [ @@ -166,6 +181,27 @@ def task_docs_spelling(): "clean": True, } + def check_towncrier_fragments(changed): + for path in map(Path, changed): + if not (is_towncrier_fragment(path) or path == CHANGELOG_TEMPLATE): + return TaskFailed( + f"{CHANGELOG_PATH.name}/{path.name} is not a valid towncrier " + f"fragment name." + ) + + yield { + "name": "towncrier_fragments", + "actions": [check_towncrier_fragments], + "file_dep": sorted(CHANGELOG_PATH.iterdir()), + } + yield { + "name": "towncrier", + "task_dep": ["docs_checks:towncrier_fragments"], + "setup": ["devsetup"], + "actions": with_poetry(["towncrier", "--draft"]), + "file_dep": [PYPROJECT, CHANGELOG_TEMPLATE, *CHANGELOG_FRAGMENTS], + } + def task_docs(): """Build the documentation""" @@ -191,7 +227,7 @@ def task_build(): "setup": ["devsetup"], "actions": ["poetry build"], "task_dep": ["test", "docs"], - "file_dep": [HERE / "pyproject.toml", *ALL_PY_FILES], + "file_dep": [PYPROJECT, *ALL_PY_FILES], "targets": [DIST_PATH, *DIST_FILES], "clean": True, } @@ -205,4 +241,4 @@ def task_build(): def task_all(): """Run all checks, then build the docs and release""" - return {"actions": [], "task_dep": ["tox", "docs_spelling", "docs", "build"]} + return {"actions": [], "task_dep": ["tox", "docs_checks", "docs", "build"]} From 33ce6839585b0e88fa064aa26e5229170b440d25 Mon Sep 17 00:00:00 2001 From: Martijn Pieters Date: Sun, 1 Dec 2019 13:14:26 +0000 Subject: [PATCH 2/4] Clarify towncrier fragment format expectations --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b163258..5e2ffa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ fix problems like typo corrections or such. To add a new change log entry, please see https://pip.pypa.io/en/latest/development/contributing/#news-entries - we named the news folder "changelog.d". + we named the news folder "changelog.d", and use Markdown to format + entries. WARNING: Don't drop the next directive! --> From cc1f9d23854c37dec000485c6c4009634516a148 Mon Sep 17 00:00:00 2001 From: Martijn Pieters Date: Sun, 1 Dec 2019 13:22:46 +0000 Subject: [PATCH 3/4] Make 'docs' depend on 'docs_checks' --- dodo.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dodo.py b/dodo.py index c47747d..429fc20 100644 --- a/dodo.py +++ b/dodo.py @@ -208,6 +208,7 @@ def task_docs(): make_cmd = with_poetry(["make", "html"])[0] return { "setup": ["devsetup"], + "task_dep": ["docs_checks"], "actions": [CmdAction(make_cmd, cwd=DOC_PATH, shell=False)], "file_dep": [ *SRC_FILES, @@ -241,4 +242,4 @@ def task_build(): def task_all(): """Run all checks, then build the docs and release""" - return {"actions": [], "task_dep": ["tox", "docs_checks", "docs", "build"]} + return {"actions": [], "task_dep": ["tox", "docs", "build"]} From 34d927693db3fe808475e0c120d787e62923e875 Mon Sep 17 00:00:00 2001 From: Martijn Pieters Date: Sun, 1 Dec 2019 14:14:19 +0000 Subject: [PATCH 4/4] Validate the changelog on release - there should be no towncrier fragments left - the currently tagged version should be present in CHANGELOG.md --- .azure-pipelines/stage-deploy.yml | 14 ++++++++++++++ changelog.d/4.doc | 1 + 2 files changed, 15 insertions(+) create mode 100644 changelog.d/4.doc diff --git a/.azure-pipelines/stage-deploy.yml b/.azure-pipelines/stage-deploy.yml index 1a43899..00748f2 100644 --- a/.azure-pipelines/stage-deploy.yml +++ b/.azure-pipelines/stage-deploy.yml @@ -24,6 +24,17 @@ stages: versionSpec: "3.7" architecture: "x64" + - bash: | + RELEASE_VERSION=`git describe --exact-match $(Build.SourceBranch) | cut -b2-` + grep -q "## Aiolimiter $RELEASE_VERSION (.*)$" CHANGELOG.md + displayName: Check for release in the changelog + + - bash: | + if [[ $(git ls-tree -r --name-only $(Build.SourceBranch) changelog.d/ | sort | tail -n+2) ]]; then + exit 1; + fi + displayName: Verify there are no towncrier fragments + - bash: | curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | POETRY_PREVIEW=1 python echo "##vso[task.prependpath]$HOME/.poetry/bin/" @@ -32,6 +43,9 @@ stages: - bash: poetry install displayName: Install dependencies + - bash: if [[ $(ls -A) ]]; then + displayName: + - bash: poetry build displayName: 'Make tarball and universal wheel' diff --git a/changelog.d/4.doc b/changelog.d/4.doc new file mode 100644 index 0000000..f326b74 --- /dev/null +++ b/changelog.d/4.doc @@ -0,0 +1 @@ +Corrected build process to ensure CHANGELOG.md is updated on release.