From 76c7d6858cb2a0f1a574892b15d8e9dceb548c50 Mon Sep 17 00:00:00 2001 From: Benjamin Bengfort Date: Tue, 1 Oct 2024 17:36:18 -0500 Subject: [PATCH 1/4] Testing and CI --- .dockerignore | 2 +- .github/pull_request_template.md | 27 +++++++++++ .github/workflows/codeql.yaml | 43 ++++++++++++++++++ .github/workflows/containers.yaml | 74 +++++++++++++++++++++++++++++++ .github/workflows/tests.yaml | 71 +++++++++++++++++++++++++++++ 5 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/codeql.yaml create mode 100644 .github/workflows/containers.yaml create mode 100644 .github/workflows/tests.yaml diff --git a/.dockerignore b/.dockerignore index 798f400..2035dfd 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,7 +6,7 @@ .python-version Dockerfile .dockerignore -LICENSE.txt +LICENSE README.md # Byte-compiled / optimized / DLL files diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..4a1bb85 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,27 @@ +### Scope of changes + +Describe the problem you're trying to solve and the fix/solution that you've implemented in this PR. + +### Type of change + +- [ ] bug fix +- [ ] new feature +- [ ] documentation +- [ ] other (describe) + +### Acceptance criteria + +Describe how reviewers can test this change to be sure that it works correctly. Add a checklist if possible. + +### Author checklist + +- [ ] I have manually tested the change and/or added automation in the form of unit tests or integration tests +- [ ] I have updated the dependencies list +- [ ] I have added new test fixtures as needed to support added tests +- [ ] I have added or updated the documentation +- [ ] Check this box if a reviewer can merge this pull request after approval (leave it unchecked if you want to do it yourself) + +### Reviewer(s) checklist + +- [ ] Any new user-facing content that has been added for this PR has been QA'ed to ensure correct grammar, spelling, and understandability. +- [ ] To the best of my ability, I believe that this PR represents a good solution to the specified problem and that it should be merged into the main code base. diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml new file mode 100644 index 0000000..598f0d4 --- /dev/null +++ b/.github/workflows/codeql.yaml @@ -0,0 +1,43 @@ +name: "CodeQL" +on: + push: + branches: + - main + pull_request: + # The branches below must be a subset of the branches above + branches: + - main + schedule: + # At 14:16 on Fridays + - cron: '16 14 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: + - javascript + - python + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" \ No newline at end of file diff --git a/.github/workflows/containers.yaml b/.github/workflows/containers.yaml new file mode 100644 index 0000000..8bc625b --- /dev/null +++ b/.github/workflows/containers.yaml @@ -0,0 +1,74 @@ +name: Containers +on: + push: + branches: + - main + tags: + - 'v*' + pull_request: + branches: + - main + +jobs: + # Parlance Image Build + parlance: + name: Parlance + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Setup Environment + id: vars + run: | + echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT + echo "revision=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + + - name: Docker Metadata + id: meta + uses: docker/metadata-action@v5 + with: + # list of Docker images to use as basenames for tags + # this should be configured for each container built + images: | + rotationalio/parlance + gcr.io/rotationalio-habanero/parlance + tags: | + type=semver,pattern={{raw}} + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=sha,prefix=,suffix=,format=short + + - name: Setup QEMU + uses: docker/setup-qemu-action@v3 + + - name: Setup Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }} + + - name: Login to GCR + if: github.event_name != 'pull_request' + uses: docker/login-action@v2 + with: + registry: gcr.io + username: _json_key + password: ${{ secrets.GCR_SERVICE_ACCOUNT }} + + - name: Build and Push + id: docker_build + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + build-args: | + GIT_REVISION=${{ steps.vars.outputs.revision }} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..81eeadb --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,71 @@ +name: Tests +on: + push: + branches: + - main + tags: + - 'v*' + pull_request: + +jobs: + lint: + name: Flake8 + runs-on: ubuntu-latest + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12.x' + + - name: Install Flake8 + run: | + python3 -m pip install --upgrade pip + python3 -m pip install flake8 + + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Lint Python Code + run: flake8 . + + test: + name: Django Tests + runs-on: ubuntu-latest + services: + postgres: + image: postgres:15 + env: + POSTGRES_USER: django + POSTGRES_PASSWORD: supersecret + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + + steps: + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12.x' + + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Install Test Dependencies + run: | + pip install -U pip + pip install factory_boy==3.3.1 pytest==8.3.3 pytest-cov==5.0.0 \ + pytest-django==4.9.0 pytest-env==1.1.5 pytest-flakes==4.0.5 + + - name: Install Dependencies + run: pip install -r requirements.txt + + - name: Execute Tests + env: + DJANGO_SETTINGS_MODULE: parlance.settings.testing + PARLANCE_DATABASE_URL: postgres://django:supersecret@127.0.0.1:5432/parlance_test + PARLANCE_SECRET_KEY: supersecretsquirrel + run: pytest \ No newline at end of file From 47cfcd859ba3c59fdb59b2b1283c164c48a36033 Mon Sep 17 00:00:00 2001 From: Benjamin Bengfort Date: Tue, 1 Oct 2024 17:40:37 -0500 Subject: [PATCH 2/4] revert envvar names --- .env.template | 6 +++--- parlance/settings/base.py | 19 +++++++++---------- pytest.ini | 23 +++++++++++++++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 pytest.ini diff --git a/.env.template b/.env.template index 0605d36..9554bee 100644 --- a/.env.template +++ b/.env.template @@ -1,5 +1,5 @@ DJANGO_SETTINGS_MODULE="parlance.settings.development" -PARLANCE_DEBUG=True -PARLANCE_SECRET_KEY="devjnz9&&+zo3i!j3)z_c-7xl&ti&26x02vokwx#uqlulu(wl_1ujparlance" -PARLANCE_DATABASE_URL="postgres://django@localhost:5432/parlance" \ No newline at end of file +DJANGO_DEBUG=True +SECRET_KEY="devjnz9&&+zo3i!j3)z_c-7xl&ti&26x02vokwx#uqlulu(wl_1ujparlance" +DATABASE_URL="postgres://django@localhost:5432/parlance" \ No newline at end of file diff --git a/parlance/settings/base.py b/parlance/settings/base.py index 46ed687..db353a5 100644 --- a/parlance/settings/base.py +++ b/parlance/settings/base.py @@ -77,7 +77,7 @@ def parse_bool(val): ########################################################################## # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = environ_setting("PARLANCE_SECRET_KEY", required=True) +SECRET_KEY = environ_setting("SECRET_KEY", required=True) ########################################################################## @@ -87,8 +87,7 @@ def parse_bool(val): # Database # https://docs.djangoproject.com/en/5.1/ref/settings/#databases DATABASES = { - "default": dj_database_url.parse( - environ_setting("PARLANCE_DATABASE_URL", required=True, default=""), + "default": dj_database_url.config( conn_max_age=600, conn_health_checks=True, test_options={"NAME": "parlance_testing"}, @@ -107,7 +106,7 @@ def parse_bool(val): ########################################################################## # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = parse_bool(environ_setting("PARLANCE_DEBUG", default=True)) +DEBUG = parse_bool(environ_setting("DJANGO_DEBUG", default=True)) # Specify hosts in production settings ALLOWED_HOSTS = [] @@ -223,12 +222,12 @@ def parse_bool(val): ## Logging and Error Reporting ########################################################################## -ADMINS = [("Parlance Admin", environ_setting("PARLANCE_ADMIN_EMAIL", ""))] +ADMINS = [("Parlance Admin", environ_setting("ADMIN_EMAIL", ""))] -SERVER_EMAIL = environ_setting("PARLANCE_SERVER_EMAIL", default="") +SERVER_EMAIL = environ_setting("SERVER_EMAIL", default="") EMAIL_USE_TLS = True -EMAIL_HOST = environ_setting("PARLANCE_EMAIL_HOST", default="") -EMAIL_HOST_USER = environ_setting("PARLANCE_EMAIL_HOST_USER", default="") -EMAIL_HOST_PASSWORD = environ_setting("PARLANCE_EMAIL_HOST_PASSWORD", default="") -EMAIL_PORT = environ_setting("PARLANCE_EMAIL_PORT", default=587) +EMAIL_HOST = environ_setting("EMAIL_HOST", default="") +EMAIL_HOST_USER = environ_setting("EMAIL_HOST_USER", default="") +EMAIL_HOST_PASSWORD = environ_setting("EMAIL_HOST_PASSWORD", default="") +EMAIL_PORT = environ_setting("EMAIL_PORT", default=587) EMAIL_SUBJECT_PREFIX = "[PARLANCE] " diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..d30dd41 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,23 @@ +[pytest] +DJANGO_SETTINGS_MODULE = parlance.settings.testing +addopts = --cov=. --flakes +python_files = tests.py test_*.py *_tests.py +norecursedirs = .git _build assets theme tmp + +env = + SECRET_KEY=supersecretsquirrel + +filterwarnings = + ignore::DeprecationWarning + ignore::PendingDeprecationWarning + ignore:No directory at.*:UserWarning + +flakes-ignore = + __init__.py UnusedImport + __init__.py ImportStarUsed + test_*.py ImportStarUsed + test_*.py ImportStarUsage + parlance/settings/*.py ImportStarUsage + parlance/settings/*.py ImportStarUsed + parlance/urls.py ImportStarUsed + parlance/urls.py ImportStarUsage \ No newline at end of file From 7195bd447c7c4aa644c3e5b3f53f45667496efc6 Mon Sep 17 00:00:00 2001 From: Benjamin Bengfort Date: Tue, 1 Oct 2024 17:42:19 -0500 Subject: [PATCH 3/4] fix import --- parlance/settings/container.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parlance/settings/container.py b/parlance/settings/container.py index 2517b99..7bbe91b 100644 --- a/parlance/settings/container.py +++ b/parlance/settings/container.py @@ -18,7 +18,7 @@ ########################################################################## from .base import * # noqa -from base import PROJECT +from .base import PROJECT ########################################################################## From ba7dfcdcfaecc8520ec42d7933f4c60a6a73fbf3 Mon Sep 17 00:00:00 2001 From: Benjamin Bengfort Date: Tue, 1 Oct 2024 17:46:01 -0500 Subject: [PATCH 4/4] fix container build again --- README.md | 5 ++++- parlance/settings/container.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 36f6c35..175c027 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ # Parlance -**An LLM evaluation tool that uses a model-to-model qualitative comparison metric.** +[![Tests](https://github.com/rotationalio/parlance/actions/workflows/tests.yaml/badge.svg)](https://github.com/rotationalio/parlance/actions/workflows/tests.yaml) +[![Containers](https://github.com/rotationalio/parlance/actions/workflows/containers.yaml/badge.svg)](https://github.com/rotationalio/parlance/actions/workflows/containers.yaml) +[![CodeQL](https://github.com/rotationalio/parlance/actions/workflows/codeql.yaml/badge.svg)](https://github.com/rotationalio/parlance/actions/workflows/codeql.yaml) +**An LLM evaluation tool that uses a model-to-model qualitative comparison metric.** ## Getting Started diff --git a/parlance/settings/container.py b/parlance/settings/container.py index 7bbe91b..7021efc 100644 --- a/parlance/settings/container.py +++ b/parlance/settings/container.py @@ -34,5 +34,5 @@ ] ## Static files served by WhiteNoise -STATIC_ROOT = PROJECT / "static" +STATIC_ROOT = PROJECT / "assets" STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"