mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2024-11-10 19:57:09 +03:00
Adding GitHub-Action CI Option (#2837)
This commit is contained in:
parent
55aa86878b
commit
b064e09f12
|
@ -56,7 +56,8 @@
|
||||||
"ci_tool": [
|
"ci_tool": [
|
||||||
"None",
|
"None",
|
||||||
"Travis",
|
"Travis",
|
||||||
"Gitlab"
|
"Gitlab",
|
||||||
|
"Github"
|
||||||
],
|
],
|
||||||
"keep_local_envs_in_vcs": "y",
|
"keep_local_envs_in_vcs": "y",
|
||||||
"debug": "n"
|
"debug": "n"
|
||||||
|
|
|
@ -119,6 +119,7 @@ ci_tool:
|
||||||
1. None
|
1. None
|
||||||
2. `Travis CI`_
|
2. `Travis CI`_
|
||||||
3. `Gitlab CI`_
|
3. `Gitlab CI`_
|
||||||
|
4. `Github Actions`_
|
||||||
|
|
||||||
keep_local_envs_in_vcs:
|
keep_local_envs_in_vcs:
|
||||||
Indicates whether the project's ``.envs/.local/`` should be kept in VCS
|
Indicates whether the project's ``.envs/.local/`` should be kept in VCS
|
||||||
|
@ -176,3 +177,4 @@ debug:
|
||||||
|
|
||||||
.. _GitLab CI: https://docs.gitlab.com/ee/ci/
|
.. _GitLab CI: https://docs.gitlab.com/ee/ci/
|
||||||
|
|
||||||
|
.. _Github Actions: https://docs.github.com/en/actions
|
||||||
|
|
|
@ -123,6 +123,10 @@ def remove_dotgitlabciyml_file():
|
||||||
os.remove(".gitlab-ci.yml")
|
os.remove(".gitlab-ci.yml")
|
||||||
|
|
||||||
|
|
||||||
|
def remove_dotgithub_folder():
|
||||||
|
shutil.rmtree(".github")
|
||||||
|
|
||||||
|
|
||||||
def append_to_project_gitignore(path):
|
def append_to_project_gitignore(path):
|
||||||
gitignore_file_path = ".gitignore"
|
gitignore_file_path = ".gitignore"
|
||||||
with open(gitignore_file_path, "a") as gitignore_file:
|
with open(gitignore_file_path, "a") as gitignore_file:
|
||||||
|
@ -395,6 +399,9 @@ def main():
|
||||||
if "{{ cookiecutter.ci_tool }}".lower() != "gitlab":
|
if "{{ cookiecutter.ci_tool }}".lower() != "gitlab":
|
||||||
remove_dotgitlabciyml_file()
|
remove_dotgitlabciyml_file()
|
||||||
|
|
||||||
|
if "{{ cookiecutter.ci_tool }}".lower() != "github":
|
||||||
|
remove_dotgithub_folder()
|
||||||
|
|
||||||
if "{{ cookiecutter.use_drf }}".lower() == "n":
|
if "{{ cookiecutter.use_drf }}".lower() == "n":
|
||||||
remove_drf_starter_files()
|
remove_drf_starter_files()
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# this is a very simple script that tests the docker configuration for cookiecutter-django
|
# this is a very simple script that tests the docker configuration for cookiecutter-django
|
||||||
# it is meant to be run from the root directory of the repository, eg:
|
# it is meant to be run from the root directory of the repository, eg:
|
||||||
# sh tests/test_docker.sh
|
# sh tests/test_bare.sh
|
||||||
|
|
||||||
set -o errexit
|
set -o errexit
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,7 @@ SUPPORTED_COMBINATIONS = [
|
||||||
{"ci_tool": "None"},
|
{"ci_tool": "None"},
|
||||||
{"ci_tool": "Travis"},
|
{"ci_tool": "Travis"},
|
||||||
{"ci_tool": "Gitlab"},
|
{"ci_tool": "Gitlab"},
|
||||||
|
{"ci_tool": "Github"},
|
||||||
{"keep_local_envs_in_vcs": "y"},
|
{"keep_local_envs_in_vcs": "y"},
|
||||||
{"keep_local_envs_in_vcs": "n"},
|
{"keep_local_envs_in_vcs": "n"},
|
||||||
{"debug": "y"},
|
{"debug": "y"},
|
||||||
|
@ -138,6 +139,7 @@ def check_paths(paths):
|
||||||
@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id)
|
@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id)
|
||||||
def test_project_generation(cookies, context, context_override):
|
def test_project_generation(cookies, context, context_override):
|
||||||
"""Test that project is generated and fully rendered."""
|
"""Test that project is generated and fully rendered."""
|
||||||
|
|
||||||
result = cookies.bake(extra_context={**context, **context_override})
|
result = cookies.bake(extra_context={**context, **context_override})
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert result.exception is None
|
assert result.exception is None
|
||||||
|
@ -225,6 +227,42 @@ def test_gitlab_invokes_flake8_and_pytest(
|
||||||
pytest.fail(e)
|
pytest.fail(e)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
["use_docker", "expected_test_script"],
|
||||||
|
[
|
||||||
|
("n", "pytest"),
|
||||||
|
("y", "docker-compose -f local.yml exec -T django pytest"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_github_invokes_flake8_and_pytest(
|
||||||
|
cookies, context, use_docker, expected_test_script
|
||||||
|
):
|
||||||
|
context.update({"ci_tool": "Github", "use_docker": use_docker})
|
||||||
|
result = cookies.bake(extra_context=context)
|
||||||
|
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert result.exception is None
|
||||||
|
assert result.project.basename == context["project_slug"]
|
||||||
|
assert result.project.isdir()
|
||||||
|
|
||||||
|
with open(f"{result.project}/.github/workflows/ci.yml", "r") as github_yml:
|
||||||
|
try:
|
||||||
|
github_config = yaml.safe_load(github_yml)
|
||||||
|
flake8_present = False
|
||||||
|
for action_step in github_config["jobs"]["flake8"]["steps"]:
|
||||||
|
if action_step.get("run") == "flake8":
|
||||||
|
flake8_present = True
|
||||||
|
assert flake8_present
|
||||||
|
|
||||||
|
expected_test_script_present = False
|
||||||
|
for action_step in github_config["jobs"]["pytest"]["steps"]:
|
||||||
|
if action_step.get("run") == expected_test_script:
|
||||||
|
expected_test_script_present = True
|
||||||
|
assert expected_test_script_present
|
||||||
|
except yaml.YAMLError as e:
|
||||||
|
pytest.fail(e)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("slug", ["project slug", "Project_Slug"])
|
@pytest.mark.parametrize("slug", ["project slug", "Project_Slug"])
|
||||||
def test_invalid_slug(cookies, context, slug):
|
def test_invalid_slug(cookies, context, slug):
|
||||||
"""Invalid slug should failed pre-generation hook."""
|
"""Invalid slug should failed pre-generation hook."""
|
||||||
|
|
7
{{cookiecutter.project_slug}}/.github/dependabot.yml
vendored
Normal file
7
{{cookiecutter.project_slug}}/.github/dependabot.yml
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
# Update Github actions in workflows
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
95
{{cookiecutter.project_slug}}/.github/workflows/ci.yml
vendored
Normal file
95
{{cookiecutter.project_slug}}/.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
# Enable Buildkit and let compose use it to speed up image building
|
||||||
|
env:
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
|
COMPOSE_DOCKER_CLI_BUILD: 1
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: [ "master" ]
|
||||||
|
paths-ignore: [ "docs/**" ]
|
||||||
|
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
paths-ignore: [ "docs/**" ]
|
||||||
|
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
flake8:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Checkout Code Repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up Python 3.8
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: 3.8
|
||||||
|
|
||||||
|
- name: Install flake8
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install flake8
|
||||||
|
|
||||||
|
- name: Lint with flake8
|
||||||
|
run: flake8
|
||||||
|
|
||||||
|
# With no caching at all the entire ci process takes 4m 30s to complete!
|
||||||
|
pytest:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Checkout Code Repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
{% if cookiecutter.use_docker == 'y' -%}
|
||||||
|
|
||||||
|
- name: Build the Stack
|
||||||
|
run: docker-compose -f local.yml build
|
||||||
|
|
||||||
|
- name: Make DB Migrations
|
||||||
|
run: docker-compose -f local.yml run --rm django python manage.py migrate
|
||||||
|
|
||||||
|
- name: Run the Stack
|
||||||
|
run: docker-compose -f local.yml up -d
|
||||||
|
|
||||||
|
- name: Run Django Tests
|
||||||
|
run: docker-compose -f local.yml exec -T django pytest
|
||||||
|
|
||||||
|
- name: Tear down the Stack
|
||||||
|
run: docker-compose down
|
||||||
|
|
||||||
|
{%- else %}
|
||||||
|
|
||||||
|
- name: Set up Python 3.8
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: 3.8
|
||||||
|
|
||||||
|
- name: Get pip cache dir
|
||||||
|
id: pip-cache-location
|
||||||
|
run: |
|
||||||
|
echo "::set-output name=dir::$(pip cache dir)"
|
||||||
|
|
||||||
|
{% raw %}
|
||||||
|
- name: Cache pip Project Dependencies
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
# Get the location of pip cache dir
|
||||||
|
path: ${{ steps.pip-cache-location.outputs.dir }}
|
||||||
|
# Look to see if there is a cache hit for the corresponding requirements file
|
||||||
|
key: ${{ runner.os }}-pip-${{ hashFiles('**/local.txt') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-pip-
|
||||||
|
{% endraw %}
|
||||||
|
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -r requirements/local.txt
|
||||||
|
|
||||||
|
- name: Test with pytest
|
||||||
|
run: pytest
|
||||||
|
|
||||||
|
{%- endif %}
|
Loading…
Reference in New Issue
Block a user