diff --git a/cookiecutter.json b/cookiecutter.json
index 5b3ee1a..efc909c 100644
--- a/cookiecutter.json
+++ b/cookiecutter.json
@@ -1,10 +1,11 @@
{
- "full_name": "Audrey Roy Greenfeld",
- "email": "audreyr@example.com",
- "github_username": "audreyr",
- "project_name": "Python Boilerplate",
+ "full_name": "Mark Sevelj",
+ "email": "mark@example.com",
+ "github_username": "imAsparky",
+ "project_name": "Python 3 Package Boilerplate",
+ "git_project_name": "{{ cookiecutter.project_name.lower().replace(' ', '-').replace('_', '-') }}",
"project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}",
- "project_short_description": "Python Boilerplate contains all the boilerplate you need to create a Python package.",
+ "project_short_description": "Python 3 Package Boilerplate contains all the boilerplate you need to create a Python package.",
"pypi_username": "{{ cookiecutter.github_username }}",
"version": "0.1.0",
"use_pytest": "n",
@@ -13,5 +14,7 @@
"command_line_interface": ["Click", "Argparse", "No command-line interface"],
"create_author_file": "y",
"create_conventional_commits_edit_message": "y",
+ "create_auto_CHANGELOG": "y",
+ "github_access_token": ["secrets.GITHUB_TOKEN", "secrets.CHANGELOG_UPDATE"],
"open_source_license": ["MIT license", "BSD license", "ISC license", "Apache Software License 2.0", "GNU General Public License v3", "Not open source"]
}
diff --git a/docs/source/prompts.rst b/docs/source/prompts.rst
index c5fbaa9..f4adcfe 100644
--- a/docs/source/prompts.rst
+++ b/docs/source/prompts.rst
@@ -26,6 +26,15 @@ project_name
The name of your new Python package project. This is used in documentation,
so spaces and any characters are fine here.
+git_project_name
+~~~~~~~~~~~~~~~~
+The name of the GitHub project repository you have created.
+
+If it is the same as your project_name but with hyphens instead of spaces leave
+this blank. Your GitHub repository name will be generated with hyphens.
+
+If its different enter your project GitHub repository name here.
+
project_slug
~~~~~~~~~~~~
The namespace of your Python package. This should be Python import-friendly.
@@ -67,9 +76,13 @@ project.
Whether to create an authors file.
**create_conventional_commits_edit_message**
- Whether to use a commit message that helps you adhere to the
- `Conventional Commits `_
- specification.
+ Whether to use a commit message that helps you adhere to the
+ `Conventional Commits `_
+ specification.
+
+ If you plan to use the create_auto_CHANGELOG feature, this template will
+ help you keep your messages in the correct format for the auto CHANGELOG
+ feature.
.. important::
@@ -80,6 +93,25 @@ project.
git config --local commit.template .github/.git-commit-template.txt
+**create_auto_CHANGELOG**
+ create_auto_CHANGELOG will use GitHub actions to generate a changelog using
+ a cron job, scheduled daily.
+
+**github_access_token**
+ For new or small repositories, select `secrets.GITHUB_TOKEN`.
+ This is adequate for most small packages.
+
+ For larger repositories, the `GITHUB_TOKEN` may error on the rate limit when
+ generating the CHANGELOG. If so you will need a PAT so
+ select `secrets.CHANGELOG_UPDATE`.
+
+ After generating your GitHub PAT, ensure you use `CHANGELOG_UPDATE` as the
+ repository secret name. Be careful not to share the secret or commit it to
+ the repository accidentally.
+
+ See `Encrypted Secrets `_
+ for more information on generating secrets and repository security.
+
**open_source_license**
Choose a `license `_. Options:
diff --git a/docs/source/tutorial.rst b/docs/source/tutorial.rst
index 7351394..942e304 100644
--- a/docs/source/tutorial.rst
+++ b/docs/source/tutorial.rst
@@ -15,12 +15,53 @@ top of the page at `GitHub Help`_.
.. _`GitHub account`: https://github.com/
.. _`GitHub Help`: https://help.github.com/
+Step 1: Create a GitHub Repo
+----------------------------
+
+We do this step first to make sure that your new package name is available.
+
+Your GitHub package name can use a hyphen -, however, the module name must use
+an underscore _.
+
+Don't worry; we have your back; go right ahead if you would like to use hyphens
+in your package name. We generate your module names correctly using
+underscores from the information gathered when you cookiecutter your new
+project.
+
+.. todo::
+
+ #. Fix the git repo bash commands in Step 1 of the tutorial.
+ #. The git bash commands may be better lower down the list as well.
+
+ See `Issue 69 `_.
+
+.. code-block:: bash
+
+ cd mypackage
+ git init .
+ git add .
+ git config --local commit.template .github/.git-commit-template.txt
+ git commit -m "Initial skeleton."
+ git remote add origin git@github.com:myusername/mypackage.git
+ git push -u origin main
+
+Where ``myusername`` and ``mypackage`` are adjusted for your username and
+package name.
+
+You will need an ssh key to push local changes to your repository.
+
+You can `Generate`_ a new key or `Add`_ an existing one.
-Step 1: Install Cookiecutter
+.. _`Generate`: https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/
+.. _`Add`: https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/
+
+
+Step 2: Install Cookiecutter
----------------------------
First, you need to create and activate a virtualenv for the package project.
-Use your favorite method, or create a virtualenv for your new package like this:
+Use your favourite method, or create a virtualenv for your new package
+like this:
.. code-block:: bash
@@ -34,8 +75,14 @@ Activate your environment:
source bin/activate
+or use the . source shortcut like this
+
+.. code-block:: bash
+
+ . bin/activate
+
On Windows, activate it like this. You may find that using a Command Prompt
-window works better than gitbash.
+Terminal works better than gitbash.
.. code-block:: powershell
@@ -49,59 +96,29 @@ Install cookiecutter:
pip install cookiecutter
-Step 2: Generate Your Package
+Step 3 : Generate Your Package
-----------------------------
Now it's time to generate your Python package.
-Use cookiecutter, pointing it at the cookiecutter-py3-package repo:
+Use cookiecutter, pointing it to the cookiecutter-py3-package repository:
.. code-block:: bash
cookiecutter https://github.com/imAsparky/cookiecutter-py3-package.git
-You'll be asked to enter a bunch of values to set the package up.
-If you don't know what to enter, stick with the defaults.
-
-
-Step 3: Create a GitHub Repo
-----------------------------
-
-Go to your GitHub account and create a new repo named ``mypackage``, where
-``mypackage`` matches the ``[project_slug]`` from your answers to running
-cookiecutter. This is so that Travis CI and pyup.io can find it when we get
-to Step 5.
-
-``If your virtualenv folder is within your project folder, be sure to add the
-virtualenv folder name to your .gitignore file.``
-
-You will find one folder named after the ``[project_slug]``. Move into this
-folder, and then setup git to use your GitHub repo and upload the code:
-
-.. code-block:: bash
-
- cd mypackage
- git init .
- git add .
- git config --local commit.template .github/.git-commit-template.txt
- git commit -m "Initial skeleton."
- git remote add origin git@github.com:myusername/mypackage.git
- git push -u origin main
-
-Where ``myusername`` and ``mypackage`` are adjusted for your username and package name.
+Cookiecutter will ask questions to set your package up.
+If you're unsure or don't know what to enter, stick with the defaults.
-You'll need a ssh key to push the repo. You can `Generate`_ a key or `Add`_ an existing one.
-
-.. _`Generate`: https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/
-.. _`Add`: https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/
Step 4: Install Dev Requirements
--------------------------------
-You should still be in the folder containing the ``requirements_dev.txt`` file.
+You should still be in the root folder, the one containing the
+``requirements_dev.txt`` file.
-Your virtualenv should still be activated. If it isn't, activate it now.
+Check your virtualenv is still activated. If it isn't, activate it now.
Install the new project's local development requirements:
.. code-block:: bash
@@ -149,7 +166,7 @@ Install the new project's local development requirements:
Step 5: Set Up Read the Docs
----------------------------
-`Read the Docs`_ hosts documentation for the open source community. Think of it
+`Read the Docs`_ hosts documentation for the open-source community. Think of it
as Continuous Documentation.
Log into your account at `Read the Docs`_ . If you don't have one, create one
@@ -162,6 +179,7 @@ repository and follow the directions.
Now your documentation will get rebuilt when you make documentation changes to
your package.
+
.. _`Read the Docs`: https://readthedocs.org/
Step 6: Set Up pyup.io
@@ -177,11 +195,19 @@ Click on the green ``Add Repo`` button in the top left corner and select the
repo you created in Step 3. A popup will ask you whether you want to pin your
dependencies. Click on ``Pin`` to add the repo.
-Once your repo is set up correctly, the pyup.io badge will show your current
+When your repository is correctly set up, the pyup.io badge will show your current
update status.
+
.. _`pyup.io`: https://pyup.io/
+
+.. todo::
+
+ Add a tutorial to describe using Test Pypi.
+
+ See `Issue 13 `_.
+
Step 7: Release on PyPI
-----------------------
diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py
index a95e9e2..c5e7ddb 100644
--- a/hooks/post_gen_project.py
+++ b/hooks/post_gen_project.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-"""cookiecutter-p3-package post package generation jobs."""
+"""cookiecutter-py3-package post package generation jobs."""
import os
PROJECT_DIRECTORY = os.path.realpath(os.path.curdir)
@@ -25,3 +25,10 @@ def remove_file(filepath):
if "{{ cookiecutter.create_conventional_commits_edit_message }}" != "y":
remove_file(".github/.git-commit-template.txt")
+
+ if "{{ cookiecutter.create_auto_CHANGELOG }}" != "y":
+ remove_file("CHANGELOG.md")
+ remove_file(".github/workflows/update-changelog.yaml")
+
+ if "{{ cookiecutter.create_auto_CHANGELOG }}" == "y":
+ remove_file("HISTORY.rst")
diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py
index 51485e0..dd1844e 100644
--- a/hooks/pre_gen_project.py
+++ b/hooks/pre_gen_project.py
@@ -9,9 +9,8 @@
if not re.match(MODULE_REGEX, MODULE_NAME):
print(
- "ERROR: The project slug (%s) is not a valid Python module name.\
- Please do not use a - and use _ instead"
- % MODULE_NAME
+ f"ERROR: The project slug {MODULE_NAME} is not a valid Python module\
+ name. Please do not use a - and use _ instead"
)
# Exit to cancel project
diff --git a/tests/test_bake_project.py b/tests/test_bake_project.py
index 037fcb2..d251055 100644
--- a/tests/test_bake_project.py
+++ b/tests/test_bake_project.py
@@ -1,4 +1,4 @@
-"""Test suite for cookiecutter-py3-package."""
+"""cookiecutter-py3-package test suite."""
import datetime
import importlib
@@ -66,7 +66,7 @@ def test_year_compute_in_license_file(cookies):
Check year exists in package license file.
"""
with bake_in_temp_dir(cookies) as result:
- license_file_path = result.project.join('LICENSE')
+ license_file_path = result.project.join("LICENSE")
now = datetime.datetime.now()
assert str(now.year) in license_file_path.read()
@@ -91,13 +91,10 @@ def test_bake_with_defaults(cookies):
assert result.exception is None
found_toplevel_files = [f.basename for f in result.project.listdir()]
- assert 'setup.py' in found_toplevel_files
- assert 'python_boilerplate' in found_toplevel_files
- assert 'tox.ini' in found_toplevel_files
- assert 'tests' in found_toplevel_files
-
-
-
+ assert "setup.py" in found_toplevel_files
+ assert "python_3_package_boilerplate" in found_toplevel_files
+ assert "tox.ini" in found_toplevel_files
+ assert "tests" in found_toplevel_files
def test_bake_and_run_tests(cookies):
@@ -127,8 +124,7 @@ def test_bake_withspecialchars_and_run_tests(cookies):
(expression-not-assigned) pre-commit pylint error.
"""
with bake_in_temp_dir(
- cookies,
- extra_context={'full_name': 'name "quote" name'}
+ cookies, extra_context={"full_name": 'name "quote" name'}
) as result:
assert result.project.isdir()
# run_inside_dir('python setup.py test', str(result.project)) == 0
@@ -144,10 +140,7 @@ def test_bake_with_apostrophe_and_run_tests(cookies):
str(result.project)) == 0" is assigned to nothing
(expression-not-assigned) pre-commit pylint error.
"""
- with bake_in_temp_dir(
- cookies,
- extra_context={'full_name': "O'connor"}
- ) as result:
+ with bake_in_temp_dir(cookies, extra_context={"full_name": "O'connor"}) as result:
assert result.project.isdir()
# run_inside_dir('python setup.py test', str(result.project)) == 0
@@ -156,24 +149,21 @@ def test_bake_without_author_file(cookies):
"""
Test cookiecutter created the package without an author file.
"""
- with bake_in_temp_dir(
- cookies,
- extra_context={'create_author_file': 'n'}
- ) as result:
+ with bake_in_temp_dir(cookies, extra_context={"create_author_file": "n"}) as result:
found_toplevel_files = [f.basename for f in result.project.listdir()]
- assert 'AUTHORS.rst' not in found_toplevel_files
- doc_files = [f.basename for f in result.project.join('docs').listdir()]
- assert 'authors.rst' not in doc_files
+ assert "AUTHORS.rst" not in found_toplevel_files
+ doc_files = [f.basename for f in result.project.join("docs").listdir()]
+ assert "authors.rst" not in doc_files
# Assert there are no spaces in the toc tree
- docs_index_path = result.project.join('docs/index.rst')
+ docs_index_path = result.project.join("docs/index.rst")
with open(str(docs_index_path)) as index_file:
- assert 'contributing\n history' in index_file.read()
+ assert "contributing\n history" in index_file.read()
# Check that
- manifest_path = result.project.join('MANIFEST.in')
+ manifest_path = result.project.join("MANIFEST.in")
with open(str(manifest_path)) as manifest_file:
- assert 'AUTHORS.rst' not in manifest_file.read()
+ assert "AUTHORS.rst" not in manifest_file.read()
def test_make_help(cookies):
@@ -183,12 +173,8 @@ def test_make_help(cookies):
with bake_in_temp_dir(cookies) as result:
# The supplied Makefile does not support win32
if sys.platform != "win32":
- output = check_output_inside_dir(
- 'make help',
- str(result.project)
- )
- assert b"check code coverage quickly with the default Python" in \
- output
+ output = check_output_inside_dir("make help", str(result.project))
+ assert b"check code coverage quickly with the default Python" in output
def test_bake_selecting_license(cookies):
@@ -196,21 +182,19 @@ def test_bake_selecting_license(cookies):
Test cookiecutter created the package with the correct license.
"""
license_strings = {
- 'MIT license': 'MIT ',
- 'BSD license': 'Redistributions of source code must retain the ' +
- 'above copyright notice, this',
- 'ISC license': 'ISC License',
- 'Apache Software License 2.0':
- 'Licensed under the Apache License, Version 2.0',
- 'GNU General Public License v3': 'GNU GENERAL PUBLIC LICENSE',
+ "MIT license": "MIT ",
+ "BSD license": "Redistributions of source code must retain the "
+ + "above copyright notice, this",
+ "ISC license": "ISC License",
+ "Apache Software License 2.0": "Licensed under the Apache License, Version 2.0",
+ "GNU General Public License v3": "GNU GENERAL PUBLIC LICENSE",
}
for license, target_string in license_strings.items():
with bake_in_temp_dir(
- cookies,
- extra_context={'open_source_license': license}
+ cookies, extra_context={"open_source_license": license}
) as result:
- assert target_string in result.project.join('LICENSE').read()
- assert license in result.project.join('setup.py').read()
+ assert target_string in result.project.join("LICENSE").read()
+ assert license in result.project.join("setup.py").read()
def test_bake_not_open_source(cookies):
@@ -218,13 +202,12 @@ def test_bake_not_open_source(cookies):
Test cookiecutter created the package as not open source.
"""
with bake_in_temp_dir(
- cookies,
- extra_context={'open_source_license': 'Not open source'}
+ cookies, extra_context={"open_source_license": "Not open source"}
) as result:
found_toplevel_files = [f.basename for f in result.project.listdir()]
- assert 'setup.py' in found_toplevel_files
- assert 'LICENSE' not in found_toplevel_files
- assert 'License' not in result.project.join('README.rst').read()
+ assert "setup.py" in found_toplevel_files
+ assert "LICENSE" not in found_toplevel_files
+ assert "License" not in result.project.join("README.rst").read()
def test_using_pytest(cookies):
@@ -237,16 +220,13 @@ def test_using_pytest(cookies):
str(result.project)) == 0" is assigned to nothing
(expression-not-assigned) pre-commit pylint error.
"""
- with bake_in_temp_dir(
- cookies,
- extra_context={'use_pytest': 'y'}
- ) as result:
+ with bake_in_temp_dir(cookies, extra_context={"use_pytest": "y"}) as result:
assert result.project.isdir()
test_file_path = result.project.join(
- 'tests/test_python_boilerplate.py'
+ "tests/test_python_3_package_boilerplate.py"
)
lines = test_file_path.readlines()
- assert "import pytest" in ''.join(lines)
+ assert "import pytest" in "".join(lines)
# Test the new pytest target
# run_inside_dir('pytest', str(result.project)) == 0
@@ -258,125 +238,104 @@ def test_not_using_pytest(cookies):
with bake_in_temp_dir(cookies) as result:
assert result.project.isdir()
test_file_path = result.project.join(
- 'tests/test_python_boilerplate.py'
+ "tests/test_python_3_package_boilerplate.py"
)
lines = test_file_path.readlines()
- assert "import unittest" in ''.join(lines)
- assert "import pytest" not in ''.join(lines)
-
-
-# def test_project_with_hyphen_in_module_name(cookies):
-# result = cookies.bake(
-# extra_context={'project_name': 'something-with-a-dash'}
-# )
-# assert result.project is not None
-# project_path = str(result.project)
-#
-# # when:
-# travis_setup_cmd = ('python travis_pypi_setup.py'
-# ' --repo audreyr/cookiecutter-pypackage'
-# ' --password invalidpass')
-# run_inside_dir(travis_setup_cmd, project_path)
-#
-# # then:
-# result_travis_config = yaml.load(
-# open(os.path.join(project_path, ".travis.yml"))
-# )
-# assert "secure" in result_travis_config["deploy"]["password"],\
-# "missing password config in .travis.yml"
+ assert "import unittest" in "".join(lines)
+ assert "import pytest" not in "".join(lines)
def test_bake_with_no_console_script(cookies):
"""
Test cookiecutter created the package without console script files.
"""
- context = {'command_line_interface': "No command-line interface"}
+ context = {"command_line_interface": "No command-line interface"}
result = cookies.bake(extra_context=context)
project_path, project_slug, project_dir = project_info(result)
found_project_files = os.listdir(project_dir)
assert "cli.py" not in found_project_files
- setup_path = os.path.join(project_path, 'setup.py')
- with open(setup_path, 'r') as setup_file:
- assert 'entry_points' not in setup_file.read()
+ setup_path = os.path.join(project_path, "setup.py")
+ with open(setup_path, "r") as setup_file:
+ assert "entry_points" not in setup_file.read()
def test_bake_with_console_script_files(cookies):
"""
Test cookiecutter created the package with console script files.
"""
- context = {'command_line_interface': 'click'}
+ context = {"command_line_interface": "click"}
result = cookies.bake(extra_context=context)
project_path, project_slug, project_dir = project_info(result)
found_project_files = os.listdir(project_dir)
assert "cli.py" in found_project_files
- setup_path = os.path.join(project_path, 'setup.py')
- with open(setup_path, 'r') as setup_file:
- assert 'entry_points' in setup_file.read()
+ setup_path = os.path.join(project_path, "setup.py")
+ with open(setup_path, "r") as setup_file:
+ assert "entry_points" in setup_file.read()
def test_bake_with_argparse_console_script_files(cookies):
"""
Test cookiecutter created the package with argparse console script files.
"""
- context = {'command_line_interface': 'argparse'}
+ context = {"command_line_interface": "argparse"}
result = cookies.bake(extra_context=context)
project_path, project_slug, project_dir = project_info(result)
found_project_files = os.listdir(project_dir)
assert "cli.py" in found_project_files
- setup_path = os.path.join(project_path, 'setup.py')
- with open(setup_path, 'r') as setup_file:
- assert 'entry_points' in setup_file.read()
+ setup_path = os.path.join(project_path, "setup.py")
+ with open(setup_path, "r") as setup_file:
+ assert "entry_points" in setup_file.read()
def test_bake_with_console_script_cli(cookies):
"""
Test cookiecutter created the package with console script cli files.
"""
- context = {'command_line_interface': 'click'}
+ context = {"command_line_interface": "click"}
result = cookies.bake(extra_context=context)
project_path, project_slug, project_dir = project_info(result)
- module_path = os.path.join(project_dir, 'cli.py')
- module_name = '.'.join([project_slug, 'cli'])
+ module_path = os.path.join(project_dir, "cli.py")
+ module_name = ".".join([project_slug, "cli"])
spec = importlib.util.spec_from_file_location(module_name, module_path)
cli = importlib.util.module_from_spec(spec)
spec.loader.exec_module(cli)
runner = CliRunner()
noarg_result = runner.invoke(cli.main)
assert noarg_result.exit_code == 0
- noarg_output = ' '.join([
- 'Replace this message by putting your code into',
- project_slug])
+ noarg_output = " ".join(
+ ["Replace this message by putting your code into", project_slug]
+ )
assert noarg_output in noarg_result.output
- help_result = runner.invoke(cli.main, ['--help'])
+ help_result = runner.invoke(cli.main, ["--help"])
assert help_result.exit_code == 0
- assert 'Show this message' in help_result.output
+ assert "Show this message" in help_result.output
def test_bake_with_argparse_console_script_cli(cookies):
"""
Test cookiecutter created the package with argparse console script files.
"""
- context = {'command_line_interface': 'argparse'}
+ context = {"command_line_interface": "argparse"}
result = cookies.bake(extra_context=context)
project_path, project_slug, project_dir = project_info(result)
- module_path = os.path.join(project_dir, 'cli.py')
- module_name = '.'.join([project_slug, 'cli'])
+ module_path = os.path.join(project_dir, "cli.py")
+ module_name = ".".join([project_slug, "cli"])
spec = importlib.util.spec_from_file_location(module_name, module_path)
cli = importlib.util.module_from_spec(spec)
spec.loader.exec_module(cli)
runner = CliRunner()
noarg_result = runner.invoke(cli.main)
assert noarg_result.exit_code == 0
- noarg_output = ' '.join([
- 'Replace this message by putting your code into',
- project_slug])
+ noarg_output = " ".join(
+ ["Replace this message by putting your code into", project_slug]
+ )
assert noarg_output in noarg_result.output
- help_result = runner.invoke(cli.main, ['--help'])
+ help_result = runner.invoke(cli.main, ["--help"])
assert help_result.exit_code == 0
- assert 'Show this message' in help_result.output
+ assert "Show this message" in help_result.output
@pytest.mark.parametrize("use_black,expected", [("y", True), ("n", False)])
@@ -384,23 +343,67 @@ def test_black(cookies, use_black, expected):
"""
Test cookiecutter created the package with black configured.
"""
- with bake_in_temp_dir(
- cookies,
- extra_context={'use_black': use_black}
- ) as result:
+ with bake_in_temp_dir(cookies, extra_context={"use_black": use_black}) as result:
assert result.project.isdir()
- requirements_path = result.project.join('requirements_dev.txt')
+ requirements_path = result.project.join("requirements_dev.txt")
assert ("black" in requirements_path.read()) is expected
- makefile_path = result.project.join('Makefile')
+ makefile_path = result.project.join("Makefile")
assert ("black --check" in makefile_path.read()) is expected
+
+def test_bake_with_conventional_commits_message(cookies):
+ """
+ Test cookiecutter created the package with a conventional commits message.
+ """
+ with bake_in_temp_dir(
+ cookies, extra_context={"create_conventional_commits_edit_message": "y"}
+ ) as result:
+
+ git_with_files = [f.basename for f in result.project.join(".github").listdir()]
+ assert ".git-commit-template.txt" in git_with_files
+
+
def test_bake_without_conventional_commits_message(cookies):
+ """
+ Test cookiecutter created the package without conventional commits message.
+ """
with bake_in_temp_dir(
cookies, extra_context={"create_conventional_commits_edit_message": "n"}
) as result:
- git_files = [f.basename for f in result.project.join(".github").listdir()]
- print("git files ", git_files)
- assert ".git-commit-template.txt" not in git_files
+ git_without_files = [
+ f.basename for f in result.project.join(".github").listdir()
+ ]
+ assert ".git-commit-template.txt" not in git_without_files
+
+
+def test_bake_with_automatic_CHANGELOG(cookies):
+ """
+ Test cookiecutter created the package with a auto changelog generation.
+ """
+ with bake_in_temp_dir(
+ cookies, extra_context={"create_auto_CHANGELOG": "y"}
+ ) as result:
+
+ change_log_with_files = [f.basename for f in result.project.listdir()]
+ assert "CHANGELOG.md" in change_log_with_files
+ assert "HISTORY.rst" not in change_log_with_files
+
+ auto_workflow_with_files = [
+ f.basename for f in result.project.join(".github/workflows").listdir()
+ ]
+ assert "update-changelog.yaml" in auto_workflow_with_files
+
+
+def test_bake_without_automatic_CHANGELOG(cookies):
+ with bake_in_temp_dir(
+ cookies, extra_context={"create_auto_CHANGELOG": "n"}
+ ) as result:
+ change_log_without_files = [f.basename for f in result.project.listdir()]
+ assert "CHANGELOG.md" not in change_log_without_files
+ auto_workflow_without_files = [
+ f.basename for f in result.project.join(".github/workflows").listdir()
+ ]
+ assert "update-changelog.yaml" not in auto_workflow_without_files
diff --git a/tox.ini b/tox.ini
index 05ff6e0..4a6d29d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,8 +1,13 @@
-
[tox]
-envlist = py36, py37,py38, py39, py38 pypy, docs
skipsdist = true
skip_missing_interpreters = true
+envlist =
+ py36
+ py37
+ py38
+ py39
+ py38 pypy
+ docs
[testenv:docs]
basepython=python
@@ -25,12 +30,10 @@ PLATFORM =
macos-latest: macos
windows-latest: windows
-
[testenv]
setenv =
PYTHONPATH = {toxinidir}
deps =
-r{toxinidir}/requirements_dev.txt
commands =
- python -m pip install --upgrade pip
- pytest
+ pytest -v {posargs:tests}
diff --git a/{{cookiecutter.project_slug}}/.github/workflows/update-changelog.yaml b/{{cookiecutter.project_slug}}/.github/workflows/update-changelog.yaml
new file mode 100644
index 0000000..3efda91
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/.github/workflows/update-changelog.yaml
@@ -0,0 +1,36 @@
+name: Auto-generate CHANGELOG
+on:
+ # release:
+ # types: [created, edited]
+
+ # cron job is set for daily update at utc time
+ schedule:
+ - cron: "0 23 * * *"
+ # push:
+ # branches:
+ # - main
+ workflow_dispatch:
+
+jobs:
+ generate-changelog:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - uses: BobAnkh/auto-generate-changelog@master
+ with:
+ REPO_NAME: "{{cookiecutter.github_username}}/\
+ {{cookiecutter.git_project_name}}"
+ ACCESS_TOKEN: ${{cookiecutter.github_access_token}}
+ PATH: "/CHANGELOG.md"
+ COMMIT_MESSAGE: "docs(CHANGELOG): update release notes:docs"
+ TYPE: "chore:Chore,\
+ feat:Feature,\
+ fix:Bug Fixes,\
+ docs:Documentation,\
+ perf:Performance Improvements,\
+ refactor:Refactor,\
+ style:Styling,\
+ test:Tests,\
+ WIP:In Progress"
diff --git a/{{cookiecutter.project_slug}}/CHANGELOG.md b/{{cookiecutter.project_slug}}/CHANGELOG.md
new file mode 100644
index 0000000..a0cf709
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/CHANGELOG.md
@@ -0,0 +1 @@
+# CHANGELOG
diff --git a/{{cookiecutter.project_slug}}/MANIFEST.in b/{{cookiecutter.project_slug}}/MANIFEST.in
index 11708e4..924c364 100644
--- a/{{cookiecutter.project_slug}}/MANIFEST.in
+++ b/{{cookiecutter.project_slug}}/MANIFEST.in
@@ -1,6 +1,12 @@
{% if cookiecutter.create_author_file == 'y' -%}
include AUTHORS.rst
{% endif -%}
+
+{% if cookiecutter.create_auto_CHANGELOG == 'y' -%}
+include CHANGELOG.md
+{% endif -%}
+
+
include CONTRIBUTING.rst
include HISTORY.rst
include LICENSE