Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
**/node_modules
**/.venv
**/.tox
**/.coverage
**/*.egg-info
Expand Down
20 changes: 7 additions & 13 deletions .taskcluster.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,17 @@ tasks:
script:
- bash
- '-xec'
- tox
- >
curl -LsSf https://astral.sh/uv/install.sh | sh
uv run --extra=dev tox
jobs:
include:
- name: tests python 3.10 django 4.x
version: "3.10"
- name: tests python 3.13
version: "3.13"
env:
TOXENV: py310
- name: tests python 3.11 django 4.x
version: "3.11"
env:
TOXENV: py311
- name: tests python 3.12 (no django)
version: "3.12"
env:
TOXENV: py312
TOXENV: py313
- name: linting
version: "3.9"
version: "3.13"
script:
- bash
- '-xec'
Expand Down
42 changes: 8 additions & 34 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:18-alpine as frontend
FROM node:18-alpine AS frontend

COPY server/frontend /src
RUN chown -R node:node /src
Expand All @@ -8,56 +8,30 @@ WORKDIR /src
RUN npm install
RUN npm run production

FROM python:3.10-alpine as backend
FROM ghcr.io/astral-sh/uv:python3.13-alpine AS backend

RUN apk add --no-cache build-base git mariadb-dev && pip install tomli

# Install dependencies before copying src, so pip is only run when needed
# Also install build dependencies that are otherwise missed in wheel cache
# (from pyproject.toml [build-system].requires)
COPY ./requirements.txt ./pyproject.toml /src/
RUN cd /src && \
python -c "import tomli; from itertools import chain; pyp=tomli.load(open('pyproject.toml','rb')); deps=pyp['project']['dependencies']; extras=pyp['project']['optional-dependencies']; print('\0'.join(chain(deps, extras['docker'], extras['server'])))" | xargs -0 pip wheel -q -c requirements.txt --wheel-dir /var/cache/wheels && \
pip wheel -q --wheel-dir /var/cache/wheels wheel setuptools_scm[toml]

FROM python:3.10-alpine
RUN apk add --no-cache build-base git mariadb-dev

RUN adduser -D worker && \
apk add --no-cache bash git mariadb-client mariadb-connector-c openssh-client-default && \
pip install tomli && \
rm -rf /var/log/*

COPY --from=backend /var/cache/wheels /var/cache/wheels

COPY ./requirements.txt ./pyproject.toml /src/
USER worker
RUN cd /src && \
python -c "import tomli; from itertools import chain; pyp=tomli.load(open('pyproject.toml','rb')); deps=pyp['project']['dependencies']; extras=pyp['project']['optional-dependencies']; print('\0'.join(chain(deps, extras['docker'], extras['server'])))" | xargs -0 pip install --no-cache-dir --no-index --find-links /var/cache/wheels -q -c requirements.txt

# Embed full source code
USER root
COPY . /src/
RUN cd /src && uv sync --locked --extra=server --extra=docker

# Retrieve previous Javascript build
COPY --from=frontend /src/dist/ /src/server/frontend/dist/
RUN mkdir -p /data/fuzzing-tc-config && chown -R worker:worker /src /data/fuzzing-tc-config

# Install FM
# Note: the extras must be duplicated above in the Python
# script to pre-install dependencies.
USER worker
ENV PATH "${PATH}:/home/worker/.local/bin"
RUN pip install --no-cache-dir --no-index --find-links /var/cache/wheels --no-deps -q /src[docker,server]

# Use a custom settings file that can be overwritten
ENV DJANGO_SETTINGS_MODULE "server.settings_docker"
ENV DJANGO_SETTINGS_MODULE="server.settings_docker"

WORKDIR /src/server

# Collect staticfiles, including Vue.js build
RUN python manage.py collectstatic --no-input
RUN uv run --extra=server --extra=docker manage.py collectstatic --no-input

# Run with gunicorn, using container's port 80
ENV PORT 80
ENV PORT=80
EXPOSE 80
CMD ["gunicorn", "--bind", "0.0.0.0:80", "--error-logfile", "-", "--access-logfile", "-", "--capture-output", "server.wsgi"]
CMD ["uv", "run", "--extra", "server", " --extra", "docker", "gunicorn", "--bind", "0.0.0.0:80", "--error-logfile", "-", "--access-logfile", "-", "--capture-output", "server.wsgi"]
21 changes: 0 additions & 21 deletions conftest.py

This file was deleted.

62 changes: 46 additions & 16 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "WebCompatManager"
requires-python = ">=3.10"
requires-python = ">=3.13"
authors = [
{name = "Christian Holler", email = "choller@mozilla.com"},
{name = "Jesse Schwartzentruber", email = "jschwartzentruber@mozilla.com"},
Expand All @@ -13,13 +13,12 @@ description = "A WebCompat management tools collection"
keywords = ["test", "testing"]
classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Topic :: Software Development :: Testing",
]
license = {text = "MPL 2.0"}
license = "MPL-2.0"
maintainers = [
{name = "Mozilla Fuzzing Team", email = "fuzzing@mozilla.com"},
]
Expand All @@ -28,27 +27,43 @@ dependencies = [
"jsonpath-ng",
"jsonschema>=4.18.0",
"python-dateutil",
"setuptools==80.9.0"
]

[project.optional-dependencies]
dev = ["pre-commit", "tox", "ruff==0.6.5"]
dev = [
"pre-commit",
"tox",
"tox-uv",
"ruff==0.6.5"
]
docker = [
"gunicorn~=22.0.0",
"mozilla-django-oidc~=4.0.1",
"mysqlclient~=2.2.4",
]
server = [
"celery~=5.3.5",
"crispy-bootstrap3",
"django~=4.2.7",
"django-crispy-forms~=2.1",
"django-enumfields~=2.1.1",
"django-notifications-hq~=1.8.3",
"djangorestframework~=3.15.1",
"google-cloud-bigquery",
"pyyaml",
"redis[hiredis]",
"whitenoise~=6.6.0",
"celery==5.6.2",
"crispy-bootstrap3==2024.1",
"django==6.0.1",
"django-crispy-forms==2.5",
"django-enumfields==2.1.1",
"djangorestframework==3.16.1",
"google-cloud-bigquery==3.40.0",
"pyyaml==6.0.3",
"redis[hiredis]==7.1.0",
"whitenoise==6.11.0",
]
test = [
"mypy",
"pytest",
"pytest-cov",
"pytest-mock",
"django-types",
"types-requests",
"djangorestframework-types",
"types-python-dateutil",
"types-jsonschema"
]

[project.urls]
Expand Down Expand Up @@ -92,8 +107,9 @@ norecursedirs = [

[tool.ruff]
fix = true
target-version = "py310"
target-version = "py313"
extend-exclude = ["**/migrations/*.py"]
line-length = 120

[tool.ruff.lint]
select = [
Expand Down Expand Up @@ -133,3 +149,17 @@ where = ["src"]
include = ["webcompat", "webcompat.schemas"]

[tool.setuptools_scm]

[tool.tox]

[tool.tox.env_run_base]
runner = "uv-venv-lock-runner"
extras = ["server", "test"]
passenv = ["TOXENV", "CI", "TRAVIS", "TRAVIS_*", "CODECOV_*", "TWINE_*"]
commands = [["pytest", "-v", "--cov", "{toxinidir}", "--cov-report", "term-missing", "{posargs}"]]

[tool.tox.env.codecov]
commands = [["codecov"]]

[tool.tox.env.mypy]
commands = [["mypy", "--install-types", "--non-interactive", "{posargs}"]]
Loading