diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..bcc75aa --- /dev/null +++ b/.dockerignore @@ -0,0 +1,27 @@ +*.pyc +*.pyo +*.mo +*.db +*.css.map +*.egg-info +*.sql.gz +.cache +.project +.idea +.pydevproject +.idea/workspace.xml +.DS_Store +.git/ +.github/ +.tox/ +.sass-cache +.vagrant/ +__pycache__ +dist +docs +env +venv/ +logs +stats +Dockerfile +test.Dockerfile \ No newline at end of file diff --git a/.github/workflows/ci-pytest.yml b/.github/workflows/ci-pytest.yml new file mode 100644 index 0000000..3a9b5b5 --- /dev/null +++ b/.github/workflows/ci-pytest.yml @@ -0,0 +1,27 @@ +name: CI - Pytest + +on: + workflow_dispatch: + pull_request: + types: [opened, reopened, edited, synchronize] + +env: + CATCHPY_DOTENV_PATH: docker_dotenv.env + +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Build Docker images + run: | + docker compose -f docker-compose-test.yml build + - name: Run Docker Compose containers + run: | + docker compose -f docker-compose-test.yml up -d + - name: Run Pytest unit tests within Compose + run: | + docker compose -f docker-compose-test.yml exec web bash -c "tox" + - name: Stop Docker Compose containers + if: always() + run: docker compose -f docker-compose.yml down \ No newline at end of file diff --git a/.gitignore b/.gitignore index 5976d7b..8103f47 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ catch/settings/local.py # static root public/ + +venv \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 159b98d..c668ef0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ -FROM python:3 +FROM python:3.11 ENV PYTHONUNBUFFERED 1 +RUN apt-get update + RUN mkdir /code WORKDIR /code ADD . /code diff --git a/README.rst b/README.rst index 43b3793..da041c9 100644 --- a/README.rst +++ b/README.rst @@ -69,13 +69,13 @@ the ``Authorize`` button at the top right of the page. Not So Quick Start ------------------ -For those who want to set up a local instance of catchpy, for tests or -developement. +For those who want to set up a local instance of Catchpy, for tests or +development. -Setting up catchpy locally requires: +Setting up Catchpy locally requires: - - postgres 9.6 or higher - - python 3.5 or higher + - Postgres 9.6 or higher + - Python 3.8 or higher (Django 4.2 requirement) :: @@ -135,14 +135,14 @@ Run unit tests unit tests require: - - a postgres 9.6 or higher running (and its config in + - Postgres 9.6 or higher (config in ``catchpy/settings/test.py``); this is hard to fake because it requires postgres jsonb data type - the fortune program, ex: ``brew install fortune`` if you're in macos. ``fortune`` is used to create content in test annotations. -tests are located under each django app: +tests are located under each Django app: :: @@ -156,6 +156,12 @@ tests are located under each django app: CATCHPY_DOTENV_PATH=/path/to/dotenv/file tox +Github Actions CI +--------------- +Github Actions is configured to run unit tests on every new PR. The tests are configured in +``.github/workflows/ci-pytest.yml``. The workflow is configured to run tests on Python3.8-3.12 using +``tox``. + ---eop diff --git a/anno/crud.py b/anno/crud.py index a2ab324..0dac202 100644 --- a/anno/crud.py +++ b/anno/crud.py @@ -638,6 +638,7 @@ def delete_annos( failure = [] success = [] for a in selected: + serialization = a.serialized try: if true_delete and a.anno_deleted: a.delete() @@ -648,7 +649,7 @@ def delete_annos( failure.append(a.serialized) logger.error("failed to delete annotation({}): {}".format(a.anno_id, e)) else: - success.append(a.serialized) + success.append(serialization) return { "failed": len(failure), diff --git a/catchpy/requirements/base.txt b/catchpy/requirements/base.txt index 088481f..94b24fd 100644 --- a/catchpy/requirements/base.txt +++ b/catchpy/requirements/base.txt @@ -1,12 +1,12 @@ -Django==3.2.18 -iso8601==1.1.0 -jsonschema==4.17.3 -psycopg2==2.9.5 -PyJWT==2.6.0 +Django~=4.2 +iso8601~=2.0.0 +jsonschema==4.18.4 +psycopg>=3.1.8 +PyJWT==2.8.0 PyLD==2.0.3 python-dateutil==2.8.2 python-dotenv==1.0.0 -pytz==2022.7.1 -requests==2.28.2 +pytz==2023.3 +requests~=2.31.0 django-log-request-id==2.1.0 -django-cors-headers==3.14.0 +django-cors-headers~=4.2.0 diff --git a/catchpy/settings/test.py b/catchpy/settings/test.py index 5af22a6..14da3fe 100644 --- a/catchpy/settings/test.py +++ b/catchpy/settings/test.py @@ -17,17 +17,4 @@ "level": "INFO", "handlers": ["console"], "propagate": True, -} - -DATABASES = { - "default": { - "ENGINE": "django.db.backends.postgresql", - "NAME": "catchpy2", - "USER": "catchpy", - "PASSWORD": "catchpy", - "HOST": "dbserver.vm", - "PORT": "5432", - "ATOMIC_REQUESTS": False, - "CONN_MAX_AGE": 500, # permanent connections - }, -} +} \ No newline at end of file diff --git a/docker-compose-test.yml b/docker-compose-test.yml new file mode 100644 index 0000000..a7f26dd --- /dev/null +++ b/docker-compose-test.yml @@ -0,0 +1,33 @@ +version: '3' +services: + db: + image: postgres:15 + ports: + - "8001:5432" + environment: + POSTGRES_USER: catchpy + POSTGRES_PASSWORD: catchpy + POSTGRES_DB: catchpy + web: + build: + context: . + dockerfile: test.Dockerfile + image: hx/catchpy:test + command: ["./wait-for-it.sh", "db:5432", "--", "python", "manage.py", "runserver", "0.0.0.0:8000"] + volumes: + - .:/code + ports: + - "8000:8000" + depends_on: + - db + environment: + CATCHPY_DOTENV_PATH: "/code/docker_dotenv.env" + networks: + default: + public: + aliases: + - catchpy.localhost + +networks: + public: + diff --git a/setup.py b/setup.py index b74fcee..97d2074 100755 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ def get_version(*file_paths): "Django", "iso8601", "jsonschema", - "psycopg2", + "psycopg", "pyjwt", "pyld", "python-dateutil", @@ -64,12 +64,13 @@ def get_version(*file_paths): classifiers=[ 'Development Status :: 3 - Alpha', 'Framework :: Django', - 'Framework :: Django :: 1.11', + 'Framework :: Django :: 4.2', 'Intended Audience :: Developers', 'Natural Language :: English', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ], ) diff --git a/test.Dockerfile b/test.Dockerfile new file mode 100644 index 0000000..8503cd0 --- /dev/null +++ b/test.Dockerfile @@ -0,0 +1,29 @@ +FROM python:3.11 +ENV PYTHONUNBUFFERED 1 + +RUN apt-get update + +# Include fortune library for quote generation for text annotations +RUN apt-get install fortune-mod -y +ENV PATH "$PATH:/usr/games" + +# Install all other versions of Python we want to test with tox +RUN git clone https://github.com/pyenv/pyenv /root/.pyenv +RUN for PYTHON_VERSION in 3.8.17 3.9.17 3.10.12 3.11.4 3.12.0b4; do \ + set -ex \ + && /root/.pyenv/bin/pyenv install ${PYTHON_VERSION} \ + && /root/.pyenv/versions/${PYTHON_VERSION}/bin/python -m pip install --upgrade pip \ + ; done + +# Add to PATH, in order of lowest precedence to highest. +ENV PATH /root/.pyenv/versions/3.8.17/bin:${PATH} +ENV PATH /root/.pyenv/versions/3.9.17/bin:${PATH} +ENV PATH /root/.pyenv/versions/3.10.12/bin:${PATH} +ENV PATH /root/.pyenv/versions/3.12.0b4/bin:${PATH} +ENV PATH /root/.pyenv/versions/3.11.4/bin:${PATH} + +RUN mkdir /code +WORKDIR /code +ADD . /code + +RUN pip install -r catchpy/requirements/test.txt \ No newline at end of file diff --git a/tox.ini b/tox.ini index b71169b..5f81f56 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,10 @@ [tox] -envlis = py35, py36 - +env_list = + py38 + py39 + py310 + py311 + py312 [testenv] deps =