Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ Please also list any relevant details for your test configuration

**Test Configuration**:

- Compiler/interpreter version:
- Python version:
- Cookiecutter version:
- OS Version:

## Further comments
Expand Down
4 changes: 3 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@
- Template action for python's auto release.
- Updated project description and files.
- Auto-releases and tagged releases now will pick body from this file.
- Upgrade project documentation.

## Changed

- Interface and variable selection.
- Simplified config. process with less options.

### Fixed

-
- Fixes along the actions, both templated and the ones for this very repository.
58 changes: 30 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,11 @@ $ cookiecutter https://github.com/ferreteleco/cookie-github.git
$ cookiecutter -f https://github.com/ferreteleco/cookie-github.git
```

IMPORTANT: PR and Issue templates option overwrites every time, so if they are wanted, should be
**IMPORTANT**: PR and Issue templates option overwrites every time, so if they are wanted, should be
marked as true in the last call to cookiecutter. The CI specific options are managed differently and
this is not an issue (it can be set to true or false in successive calls without erasing previous
this is not an issue (it can be set to true or false in successive calls without erasing previous
calls generated data).


**NOTE:** alternatively, you can use [Cookieninja](https://github.com/cookieninja-generator/cookieninja),
forked and more updated version of Cookiecutter with backward compatibility.

Expand All @@ -59,31 +58,34 @@ forked and more updated version of Cookiecutter with backward compatibility.
Variables allow to customize your project. After running one of the previous cookiecutter commands,
you will be prompted to fill in the following values:

- **add_issue_templates:** this flags controls wether or not to add issue templates in the generated
folder.
- **add_PR_template:** this flags controls wether or not to add a PR template in the generated
folder.
- **add_ci_action_unit_tests:** this variable controls whether or not to create an action to
run unit tests in the repository. The available actions are:
- cpp, which creates an action for Catch2 based unit tests, built using CMake.
- python, which creates an action for Python code unit tests, executed with pytest over a
project built with Poetry.
- none, which does not generate any action.
- **add_ci_action_auto_release:** this variable controls whether or not to create an action to
generate dev releases (pre-releases, tagged with "latest" tag), triggered on pushes to master
branch. The available actions are:
- python, which creates an action for Python releases, building assets after pytest test
execution in a project built with Poetry.
- none, which does not generate any action.
- **add_ci_action_tagged_release:** this variable controls whether or not to create an action to
generate tagged releases (releases, semver tagged), triggered on "v*.*.*" tags pushed. The
available actions are:
- python, which creates an action for Python releases, building assets after pytest test
execution in a project built with Poetry.
- none, which does not generate any action.

**NOTE:** Each added action will be accompanied of a markdown checklist, stating the changes /
configuration required to fine tune it.
- **add_issue_templates:** this flag controls wether or not to add issue templates in the generated
folder. Defaults to true.
- **add_PR_template:** this flag controls wether or not to add a PR template in the generated
folder. Defaults to true.
- **target_language:** this flag controls the target language for which to generate CI actions.
Possible values are: none, python, cpp and generic. Defaults to none.
- ***none***. No actions generated so far.
- ***python***. It adds a composite actions for reduce duplicated code in actions, and workflows
for:
- running unit tests: executed with pytest over a project built with Poetry.
- generate Pre-releases: action to generate dev releases (pre-releases, tagged with "latest"
tag), triggered on pushes to master branch and building assets after pytest test execution
in a project built with Poetry.
- generate tagged releases: action to generate tagged releases (releases, semver tagged),
triggered on "*.*.*" tags pushed to the repository and building assets after pytest test
execution in a project built with Poetry.
- ***cpp***. It adds workflows for:
- running unit tests: which creates an action for Catch2 based unit tests, built using
CMake.
- ***generic***. It adds workflows for:
- generate Pre-releases: action to generate dev releases (pre-releases, tagged with "latest"
tag), triggered on pushes to master branch.
- generate tagged releases: action to generate tagged releases (releases, semver tagged),
triggered on "*.*.*" tags pushed to the repository.
- **ci_runner**: Target runner(s) in which to generate the action. More info in [GitHub-hosted](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners) runners and [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/using-self-hosted-runners-in-a-workflow). Defaults to ubuntu-20.04.

**NOTE:** Each added language actions will be accompanied of a markdown checklist, stating the
changes / configuration required to fine tune it.

## Contributing

Expand Down
14 changes: 4 additions & 10 deletions cookiecutter.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,12 @@
true,
false
],
"add_ci_action_unit_tests": [
"target_language": [
"none",
"python",
"cpp",
"none"
],
"add_ci_auto_release": [
"python",
"none"
],
"add_ci_tagged_release": [
"python",
"none"
"generic"
],
"ci_runner": "ubuntu-20.04",
"__github_folder": ".github"
}
139 changes: 41 additions & 98 deletions hooks/post_gen_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from shutil import rmtree, copytree


class color:
class Color:
"""Simple colors for print without external libraries."""

PURPLE = "\033[95m"
Expand All @@ -28,124 +28,62 @@ def change_line_endings_crlf_to_lf():
path.write_bytes(lf_data)


def remove_unwanted_templates():
if not {{cookiecutter.add_issue_templates}}:
def remove_issue_templates_if_selected(delete_flag: bool):
"""Removes the generated issue templates file if selected to do so in project config."""

if delete_flag:
LOG.info("Skipping issue templates files generation ...")
path = Path("./ISSUE_TEMPLATE")
rmtree(path)

if not {{cookiecutter.add_PR_template}}:

def remove_pr_templates_if_selected(delete_flag: bool):
"""Removes the generated PR template file if selected to do so in project config."""

if delete_flag:
LOG.info("Skipping PR templates file generation ...")
path = Path("./pull_request_template.md")
path.unlink()


def add_ci_action_unit_tests():
"""Adds a CI action for running unit tests, if applicable"""
def add_ci_actions_for_language(language: str):
"""Adds CI action(s) for the target language, if applicable."""

target_language = "{{cookiecutter.add_ci_action_unit_tests}}"

if target_language.lower() != "none":
LOG.info(
"Adding action for running unit tests (workflows folder) with default config..."
)
if language != "none":
LOG.info("Adding %s actions with default config...", language)

destination = Path("workflows")
ci_test_workflow_files_path = Path("_", "workflows", "ci-unit", target_language)
copytree(ci_test_workflow_files_path, destination, dirs_exist_ok=True)
if target_language.lower() == "python":
destination = Path(f"actions/ci-setup-{target_language.lower()}")
ci_test_workflow_files_path = Path(
"_", "actions", f"ci-setup-{target_language.lower()}"
)
copytree(ci_test_workflow_files_path, destination, dirs_exist_ok=True)
ci_workflow_files_path = Path("_", language, "workflows")
copytree(ci_workflow_files_path, destination, dirs_exist_ok=True)

print("\n\n#############################################################")
print("# #")
print(
"\n\n######################################################################"
)
print("# #")
print(
f"# {color.BOLD}{color.BLUE}Please review gen. checklist in order to adjust CI UT basic action{color.END} #"
)
print("# #")
print(
"######################################################################\n\n"
f"# {Color.BOLD}{Color.BLUE}Please review gen. checklist in order to adjust CI config{Color.END} #"
)
print("# #")
print("#############################################################\n\n")

else:
LOG.info("Skipping CI action for running unit tests file generation")

LOG.info("Skipping CI Actions files generation (no language specified)")

def add_ci_action_auto_release():
"""Adds a CI action for generating auto releases, if applicable"""

target_language = "{{cookiecutter.add_ci_auto_release}}"
def add_composite_actions_for_language(language: str):
"""Adds CI composite action(s) for the target language, if applicable."""

if target_language.lower() != "none":
destination = Path("actions")
if language == "python":
ci_composite_actions_files_path = Path("_", language, "actions")
copytree(ci_composite_actions_files_path, destination, dirs_exist_ok=True)
elif language == "none":
LOG.info(
"Adding action for running auto releases (workflows folder) with default config..."
)

destination = Path("workflows")
ci_auto_release_workflow_files_path = Path(
"_", "workflows", "ci-auto-release", target_language
)
copytree(ci_auto_release_workflow_files_path, destination, dirs_exist_ok=True)

print(
"\n\n################################################################################"
)
print(
"# #"
)
print(
f"# {color.BOLD}{color.BLUE}Please review gen. checklist in order to adjust CI auto release basic action{color.END} #"
)
print(
"# #"
)
print(
"################################################################################\n\n"
"Skipping CI composite Actions files generation (no language specified)"
)

else:
LOG.info("Skipping CI action for generating auto releases file generation")


def add_ci_action_tagged_release():
"""Adds a CI action for generating auto releases, if applicable"""

target_language = "{{cookiecutter.add_ci_auto_release}}"

if target_language.lower() != "none":
LOG.info(
"Adding action for running tagged releases (workflows folder) with default config..."
)

destination = Path("workflows")
ci_tagged_release_workflow_files_path = Path(
"_", "workflows", "ci-tagged-release", target_language
)
copytree(ci_tagged_release_workflow_files_path, destination, dirs_exist_ok=True)

print(
"\n\n###################################################################################"
"Skipping CI composite Actions files generation (not implemented for %s)",
language,
)
print(
"# #"
)
print(
f"# {color.BOLD}{color.BLUE}Please review gen. checklist in order to adjust CI tagged basic action{color.END} #"
)
print(
"# #"
)
print(
"###################################################################################\n\n"
)

else:
LOG.info("Skipping CI action for generating tagged releases file generation")


def clean():
Expand All @@ -157,9 +95,14 @@ def clean():
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG, format="%(message)s")
LOG = logging.getLogger("post_gen_project")
remove_unwanted_templates()
add_ci_action_unit_tests()
add_ci_action_auto_release()
add_ci_action_tagged_release()

ISSUES_DELETE_FLAG = not {{cookiecutter.add_issue_templates}}
remove_issue_templates_if_selected(ISSUES_DELETE_FLAG)
PR_DELETE_FLAG = not {{cookiecutter.add_PR_template}}
remove_pr_templates_if_selected(PR_DELETE_FLAG)

TARGET_LANGUAGE = "{{cookiecutter.target_language}}".lower()
add_ci_actions_for_language(TARGET_LANGUAGE)
add_composite_actions_for_language(TARGET_LANGUAGE)
clean()
change_line_endings_crlf_to_lf()
5 changes: 2 additions & 3 deletions tests/test_basic_cookiecutter_operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ def test_bake_folder_pr_template_only():
extra_context = {
"add_issue_templates": False,
"add_PR_template": True,
"add_ci_action_unit_tests": "none",
"add_ci_auto_release": "none",
"add_ci_tagged_release": "none",
"target_language": "none",
"ci-runner": "ubuntu-20.04",
}
result = run_cookiecutter(temp_path, extra_context=extra_context)

Expand Down
14 changes: 6 additions & 8 deletions tests/test_custom_solutions.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,22 @@ def test_bake_folder_existing():
extra_context = {
"add_issue_templates": False,
"add_PR_template": True,
"add_ci_action_unit_tests": "python",
"add_ci_auto_release": "none",
"add_ci_tagged_release": "none",
"target_language": "python",
"ci-runner": "ubuntu-20.04",
}
result = run_cookiecutter(temp_path, extra_context=extra_context)

assert result["exit_code"] == 0
assert result["project_dir"].stem == ".github"
assert result["project_dir"].is_dir()
# 5, because .gitattributes is also generated
assert len(list(result["project_dir"].rglob("*.*"))) == 5

assert len(list(result["project_dir"].rglob("*.*"))) == 7

extra_context_2 = {
"add_issue_templates": True,
"add_PR_template": True,
"add_ci_action_unit_tests": "cpp",
"add_ci_auto_release": "none",
"add_ci_tagged_release": "none",
"target_language": "cpp",
"ci-runner": "ubuntu-20.04",
}
result_2 = run_cookiecutter(
temp_path, extra_context=extra_context_2, overwrite_contents_if_exist=True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,9 @@ env:

jobs:
run_unit_tests:
############################################################################
# Please fill in with the Runner(s) in which to execute this action
# Ref. https://docs.github.com/en/actions/hosting-your-own-runners/using-self-hosted-runners-in-a-workflow
# Ref. https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners ############################################################################
runs-on: ubuntu-22.04
############################################################################

name: Unit Tests
runs-on: {{ cookiecutter.ci_runner }}

container:
image: {{ '${{ env.TARGET_DOCKER_IMAGE }}' }}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# GitHub Actions configuration checklist (CPP)

Be sure to properly fine-tune the generated actions before committing it to the remote repository.

## ci-tests-cpp

- [ ] The intended branch and triggers are correct (default: *on PR to master branch*).
- [ ] The target name for the test executable has been configured.
- [ ] The target Docker image where to run the test has been specified (defaults to *ubuntu:jammy*).
- [ ] The credentials for acquiring the Docker image (if needed) have been configured via
secrets and required section in action file uncommented.

Note that, for a PR to be blocked if Unit Testing action fails, status checks must be enabled on the
target branch.

In GitHub's repository settings >> Branches >> Branch protection rules >> Enable 'Require status
checks to pass before merging'.
Loading