diff --git a/cookiecutter.json b/cookiecutter.json index 682061476..4a580036d 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -56,7 +56,8 @@ "ci_tool": [ "None", "Travis", - "Gitlab" + "Gitlab", + "Github" ], "keep_local_envs_in_vcs": "y", "debug": "n" diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst index ec52e2183..458edf048 100644 --- a/docs/project-generation-options.rst +++ b/docs/project-generation-options.rst @@ -119,6 +119,7 @@ ci_tool: 1. None 2. `Travis CI`_ 3. `Gitlab CI`_ + 4. `Github CI`_ keep_local_envs_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/ +.. _Github CI: https://docs.github.com/en/actions diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index fae73e110..3336a62ac 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -123,6 +123,14 @@ def remove_dotgitlabciyml_file(): os.remove(".gitlab-ci.yml") +def remove_dotgithubciyml_file(): + os.remove(".github-ci.yml") + + +# def remove_dotgithub_folder(): +# shutil.rmtree(".github") + + def append_to_project_gitignore(path): gitignore_file_path = ".gitignore" with open(gitignore_file_path, "a") as gitignore_file: @@ -395,6 +403,12 @@ def main(): if "{{ cookiecutter.ci_tool }}".lower() != "gitlab": remove_dotgitlabciyml_file() + if "{{ cookiecutter.ci_tool }}".lower() != "github": + remove_dotgithubciyml_file() + + # if "{{ cookiecutter.ci_tool }}".lower() != "github": + # remove_dotgithub_folder() + if "{{ cookiecutter.use_drf }}".lower() == "n": remove_drf_starter_files() diff --git a/tests/test_bare.sh b/tests/test_bare.sh index 28f9b7bfb..cc1f1c36e 100755 --- a/tests/test_bare.sh +++ b/tests/test_bare.sh @@ -1,7 +1,7 @@ #!/bin/sh # 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: -# sh tests/test_docker.sh +# sh tests/test_bare.sh set -o errexit diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py index f9bfcd539..172f50ec9 100755 --- a/tests/test_cookiecutter_generation.py +++ b/tests/test_cookiecutter_generation.py @@ -96,6 +96,7 @@ SUPPORTED_COMBINATIONS = [ {"ci_tool": "None"}, {"ci_tool": "Travis"}, {"ci_tool": "Gitlab"}, + {"ci_tool": "Github"}, {"keep_local_envs_in_vcs": "y"}, {"keep_local_envs_in_vcs": "n"}, {"debug": "y"}, @@ -225,6 +226,34 @@ def test_gitlab_invokes_flake8_and_pytest( pytest.fail(e) + +@pytest.mark.parametrize( + ["use_docker", "expected_test_script"], + [ + ("n", "pytest"), + ("y", "docker-compose -f local.yml run 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/.github-ci.yml", "r") as github_yml: + try: + github_config = yaml.safe_load(github_yml) + assert github_config["flake8"]["script"] == ["flake8"] + assert github_config["pytest"]["script"] == [expected_test_script] + except yaml.YAMLError as e: + pytest.fail(e) + + @pytest.mark.parametrize("slug", ["project slug", "Project_Slug"]) def test_invalid_slug(cookies, context, slug): """Invalid slug should failed pre-generation hook.""" diff --git a/{{cookiecutter.project_slug}}/.github-ci.yml b/{{cookiecutter.project_slug}}/.github-ci.yml new file mode 100644 index 000000000..0dcbd2f3a --- /dev/null +++ b/{{cookiecutter.project_slug}}/.github-ci.yml @@ -0,0 +1,95 @@ +name: Github-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: + lint: + 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 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)" + + - 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- + + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements/local.txt + + - name: Test with pytest + run: pytest + + + {%- endif %} diff --git a/{{cookiecutter.project_slug}}/.github/workflows/.github-ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/.github-ci.yml new file mode 100644 index 000000000..0dcbd2f3a --- /dev/null +++ b/{{cookiecutter.project_slug}}/.github/workflows/.github-ci.yml @@ -0,0 +1,95 @@ +name: Github-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: + lint: + 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 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)" + + - 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- + + - name: Install Dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements/local.txt + + - name: Test with pytest + run: pytest + + + {%- endif %}