Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add dev container and tests #19

Merged
merged 11 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
5 changes: 5 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ARG IMAGE="python:3.12"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason not 3.13?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we did discuss this before it was not available at the time of our discussion.
let me check if it's available now

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's available now
https://github.com/devcontainers/images/tree/main/src/python

let me test it tonight.

Copy link
Member Author

@john0isaac john0isaac Dec 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they are lying the only available 3.13 is dev-3.13.
let's keep 3.12 until they release a stable 3.13

See:
https://mcr.microsoft.com/v2/vscode/devcontainers/python/tags/list

FROM --platform=amd64 mcr.microsoft.com/vscode/devcontainers/${IMAGE}
RUN apt-get update \
&& export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends build-essential libssl-dev gdb cmake
39 changes: 39 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"name": "Cookie Cutter - Render Engine",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"build": {
"dockerfile": "Dockerfile",
"context": "..",
"args": {
"IMAGE": "python:3.12"
}
},
"postCreateCommand": ". .devcontainer/setup.sh",
"customizations": {
"vscode": {
"settings": {
"python.formatting.provider": "charliermarsh.ruff",
"python.testing.pytestEnabled": true,
"python.testing.pytestPath": "pytest",
"python.testing.unittestEnabled": false,
"python.editor.formatOnSave": true,
"python.editor.codeActionsOnSave": {"source.fixAll": true},
"python.testing.pytestArgs": [
"tests"
],
".markdownlint-cli2.ignores": [".gitignore"]

},
"extensions": [
"ms-python.python",
"charliermarsh.ruff",
"GitHub.vscode-github-actions",
"yzhang.markdown-all-in-one",
"DavidAnson.vscode-markdownlint",
"ms-vscode.makefile-tools"
]
}
}
}
6 changes: 6 additions & 0 deletions .devcontainer/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
python -m pip install --user --upgrade pip
python -m venv .venv
source .venv/bin/activate
python -m pip install pip-tools
python -m piptools compile --upgrade -o requirements.txt requirements.in
python -m pip install -r requirements-dev.txt
28 changes: 28 additions & 0 deletions .github/workflows/devcontainer-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Check Dev Container

on:
push:
branches: [ main ]
paths:
- ".devcontainer/**"
- ".github/workflows/devcontainer-ci.yaml"
pull_request:
branches: [ main ]
paths:
- ".devcontainer/**"
- ".github/workflows/devcontainer-ci.yaml"

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 20.x
uses: actions/setup-node@v4
with:
node-version: 20.x
- run: npm install -g @devcontainers/cli
- run: devcontainer build --config ./.devcontainer/devcontainer.json --workspace-folder "$(pwd)"
28 changes: 28 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: PyTest
on:
workflow_call:
workflow_dispatch:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
fail-fast: true
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: python -m pip install --upgrade pip -r requirements-dev.txt
- name: Run tests
run: python tests/test_template.py
4 changes: 4 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pip-tools
pytest

-r requirements.txt
1 change: 1 addition & 0 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cookiecutter
50 changes: 50 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile --output-file=requirements.txt requirements.in
#
arrow==1.3.0
# via cookiecutter
binaryornot==0.4.4
# via cookiecutter
certifi==2024.8.30
# via requests
chardet==5.2.0
# via binaryornot
charset-normalizer==3.4.0
# via requests
click==8.1.7
# via cookiecutter
cookiecutter==2.6.0
# via -r requirements.in
idna==3.10
# via requests
jinja2==3.1.4
# via cookiecutter
markdown-it-py==3.0.0
# via rich
markupsafe==3.0.2
# via jinja2
mdurl==0.1.2
# via markdown-it-py
pygments==2.18.0
# via rich
python-dateutil==2.9.0.post0
# via arrow
python-slugify==8.0.4
# via cookiecutter
pyyaml==6.0.2
# via cookiecutter
requests==2.32.3
# via cookiecutter
rich==13.9.4
# via cookiecutter
six==1.17.0
# via python-dateutil
text-unidecode==1.3
# via python-slugify
types-python-dateutil==2.9.0.20241206
# via arrow
urllib3==2.2.3
# via requests
4 changes: 4 additions & 0 deletions tests/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[pytest]
python_files = test_*.py
python_classes = [A-Z]*Test
python_functions = test_*
88 changes: 88 additions & 0 deletions tests/test_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""
Test the Cookiecutter template.
"""
from cookiecutter.generate import generate_context
from cookiecutter.main import cookiecutter
from pathlib import Path
from shlex import split
from subprocess import run
from venv import create

import pytest


@pytest.fixture(scope="session")
def template() -> Path:
""" The template under test.

"""
return Path(__file__).resolve().parents[1]


@pytest.fixture(scope="module")
def tmpdir(tmp_path_factory) -> Path:
""" Test directory.

"""
return tmp_path_factory.mktemp("test_template")


@pytest.fixture(scope="module")
def context(template) -> dict:
""" Template context for testing.

"""
context = generate_context(template.joinpath("cookiecutter.json"))
context["cookiecutter"].update({
"project_slug": "slugify"
})
return context["cookiecutter"]


@pytest.fixture(scope="module")
def project(tmpdir, template, context) -> Path:
""" Create a test project from the Cookiecutter template.

"""
cookiecutter(str(template), no_input=True, output_dir=tmpdir, extra_context=context)
return tmpdir / context["project_slug"]


@pytest.fixture
def python(tmp_path):
""" Create a Python virtual environment for testing.

"""
venv = tmp_path / ".venv"
create(venv, with_pip=True)
return venv / "bin" / "python"


def test_project(project):
""" Verify that the project was created correctly.

"""
# Just a basic sanity test.
assert len(list(project.iterdir())) == 4
return


@pytest.fixture
def install_render_engine_cli(python):
install_cli = "pip install render_engine[cli]"
install_args = split(f"{python} -m {install_cli}")
install_process = run(install_args)
assert install_process.returncode == 0


def test_site_generation(context, project, python, install_render_engine_cli):
generate_site = "render_engine build app:app"
generate_args = split(f"{python} -m {generate_site}")
generate_process = run(generate_args, cwd=project)
assert generate_process.returncode == 0
john0isaac marked this conversation as resolved.
Show resolved Hide resolved


# Make the script executable.

if __name__ == "__main__":
raise SystemExit(pytest.main([__file__]))
Loading