Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
3 changes: 3 additions & 0 deletions .envs/.local/.celery
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CELERY_BROKER_URL=redis://scram-redis-1:6379/2
CELERY_RESULT_BACKEND=redis://scram-redis-1:6379/2
SCRAM_API_URL=http://django:8000/
3 changes: 3 additions & 0 deletions .envs/.local/.celery-secondary
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CELERY_BROKER_URL=redis://scram-redis-2:6379/2
CELERY_RESULT_BACKEND=redis://scram-redis-2:6379/2
SCRAM_API_URL=http://django-secondary:8000/
5 changes: 5 additions & 0 deletions .github/workflows/behave.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ jobs:
- name: Upload Coverage to Coveralls
if: matrix.python-version == '3.12'
uses: coverallsapp/github-action@v2
with:
parallel: true
flag-name: behave

- name: Upload Coverage to GitHub
if: matrix.python-version == '3.12'
Expand All @@ -83,6 +86,8 @@ jobs:
uses: 5monkeys/cobertura-action@v14
with:
minimum_coverage: "50"
report_name: "Django Pytest/Behave Coverage"


- name: Check Docker state (post-test)
if: always()
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/coverage-finish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Finish Coverage

on:
workflow_run:
workflows: ["Run pytest", "Run behave"]
types:
- completed

jobs:
finish:
runs-on: ubuntu-latest
permissions:
contents: read
needs: [behave, pytest]
steps:
- name: Finish Coveralls
uses: coverallsapp/github-action@v2
with:
parallel-finished: true
28 changes: 27 additions & 1 deletion .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ jobs:
run: |
python -m pip install --upgrade pip
python -m pip install uv
uv pip install --system -r requirements/local.txt --prerelease=allow
# https://github.com/pytest-dev/pytest-github-actions-annotate-failures/pull/68 isn't yet in a release
uv pip install --system -r requirements/local.txt --prerelease=allow
uv pip install --system git+https://github.com/pytest-dev/pytest-github-actions-annotate-failures.git@6e66cd895fe05cd09be8bad58f5d79110a20385f

- name: Apply migrations
Expand All @@ -82,3 +82,29 @@ jobs:
DATABASE_URL: "postgres://scram:@localhost:5432/test_scram_${{ matrix.python-version }}"
REDIS_HOST: "localhost"
run: pytest

- name: Install Scheduler Dependencies
run: |
cd scheduler
uv sync

- name: Run Scheduler Tests
run: |
cd scheduler
uv run pytest

- name: Upload Coverage to Coveralls
if: matrix.python-version == '3.12'
uses: coverallsapp/github-action@v2
with:
file: ./scheduler/coverage.xml
parallel: true
flag-name: scheduler

- name: Display Scheduler Coverage Metrics for scheduler tests
if: matrix.python-version == '3.12'
uses: 5monkeys/cobertura-action@v14
with:
report_name: "Pytest Scheduler Coverage"
path: ./scheduler/coverage.xml
minimum_coverage: "80"
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ pass-reset: compose.override.yml
pytest: compose.override.yml
@docker compose run --rm django coverage run -m pytest

## pytest-scheduler: runs scheduler package tests with coverage
.Phony: pytest-scheduler
pytest-scheduler:
@cd scheduler && uv run pytest

## run: brings up the containers as described in compose.override.yml
.Phony: run
run: compose.override.yml
Expand Down
51 changes: 51 additions & 0 deletions compose.override.local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,57 @@ services:
deploy:
replicas: 1

celery-worker:
volumes:
- ./scheduler/src/scheduler/:/app/scheduler:ro
env_file:
- ./.envs/.local/.celery

celery-worker-secondary:
volumes:
- ./scheduler/src/scheduler/:/app/scheduler:ro
env_file:
- ./.envs/.local/.celery-secondary
deploy:
replicas: 1

celery-beat:
command:
["celery", "-A", "scheduler.app:scram_api_scheduler", "beat", "--loglevel=info"]
env_file:
- ./.envs/.local/.celery
environment:
- DISABLE_PROCESS_UPDATES=False

celery-beat-secondary:
command:
["celery", "-A", "scheduler.app:scram_api_scheduler", "beat", "--loglevel=info"]
env_file:
- ./.envs/.local/.celery-secondary
environment:
- DISABLE_PROCESS_UPDATES=False
deploy:
replicas: 1

flower:
env_file:
- ./.envs/.local/.celery
command:
["celery", "-A", "scheduler.app:scram_api_scheduler", "flower", "--port=5555"]
ports:
- "5555:5555"

flower-secondary:
env_file:
- ./.envs/.local/.celery-secondary
command:
["celery", "-A", "scheduler.app:scram_api_scheduler", "flower", "--port=5555"]
ports:
- "5556:5555"
deploy:
replicas: 1


networks:
default:
ipam:
Expand Down
23 changes: 23 additions & 0 deletions compose.override.production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,29 @@ services:
env_file:
- ./.envs/.production/.translator


celery-worker:
volumes:
- ./scheduler/src/scheduler/:/app/scheduler:ro
env_file:
- ./.envs/.production/.celery

celery-beat:
command:
["celery", "-A", "scheduler.app:scram_api_scheduler", "beat", "--loglevel=info"]
env_file:
- ./.envs/.production/.celery


flower:
env_file:
- ./.envs/.production/.celery
command:
["celery", "-A", "scheduler.app:scram_api_scheduler", "flower", "--port=5555"]
ports:
- "5555:5555"


networks:
default:
enable_ipv6: true
Expand Down
102 changes: 98 additions & 4 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@ services:
condition: service_healthy
redis:
condition: service_healthy
celery-worker:
condition: service_healthy
networks:
default: {}
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
command: /start
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/process_updates/"]
test: ["CMD", "curl", "-f", "http://localhost:8000/health/"]
interval: 30s
timeout: 30s
timeout: 2s
start_period: 30s
retries: 5
deploy:
Expand All @@ -35,15 +37,17 @@ services:
condition: service_healthy
django:
condition: service_healthy
celery-worker-secondary:
condition: service_healthy
networks:
default: {}
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
command: /start
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/process_updates/"]
test: ["CMD", "curl", "-f", "http://localhost:8000/health/"]
interval: 30s
timeout: 30s
timeout: 2s
start_period: 30s
retries: 5
deploy:
Expand Down Expand Up @@ -129,3 +133,93 @@ services:
- net.ipv6.conf.all.disable_ipv6=0
deploy:
replicas: ${TRANSLATOR_REPLICAS:-0}

celery-worker:
build:
context: .
dockerfile: ./compose/production/celery/Dockerfile
depends_on:
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "celery", "-A", "scheduler.app:scram_api_scheduler", "inspect", "ping"]
interval: 30s
timeout: 10s
start_period: 30s
retries: 3
restart: unless-stopped

celery-worker-secondary:
build:
context: .
dockerfile: ./compose/production/celery/Dockerfile
depends_on:
redis:
condition: service_healthy
healthcheck:
test: ["CMD", "celery", "-A", "scheduler.app:scram_api_scheduler", "inspect", "ping"]
interval: 30s
timeout: 10s
start_period: 30s
retries: 3
restart: unless-stopped
deploy:
replicas: ${CELERY_WORKER_REPLICAS:-0}

celery-beat:
build:
context: .
dockerfile: ./compose/production/celery/Dockerfile
depends_on:
redis:
condition: service_healthy
celery-worker:
condition: service_healthy
restart: unless-stopped

celery-beat-secondary:
build:
context: .
dockerfile: ./compose/production/celery/Dockerfile
depends_on:
redis:
condition: service_healthy
celery-worker-secondary:
condition: service_healthy
restart: unless-stopped
deploy:
replicas: ${CELERY_BEAT_REPLICAS:-0}

flower:
build:
context: .
dockerfile: ./compose/production/celery/Dockerfile
depends_on:
redis:
condition: service_healthy
celery-worker:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5555/healthcheck"]
interval: 30s
timeout: 5s
retries: 3
restart: unless-stopped

flower-secondary:
build:
context: .
dockerfile: ./compose/production/celery/Dockerfile
depends_on:
redis:
condition: service_healthy
celery-worker-secondary:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5555/healthcheck"]
interval: 30s
timeout: 5s
retries: 3
restart: unless-stopped
deploy:
replicas: ${FLOWER_REPLICAS:-0}
47 changes: 47 additions & 0 deletions compose/production/celery/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Use a Python image with uv pre-installed
FROM ghcr.io/astral-sh/uv:python3.14-bookworm-slim

# Setup a non-root user
RUN groupadd --system --gid 999 nonroot \
&& useradd --system --gid 999 --uid 999 --create-home nonroot

# Install the project into `/app`
WORKDIR /app

# Enable bytecode compilation
ENV UV_COMPILE_BYTECODE=1

# Copy from the cache instead of linking since it's a mounted volume
ENV UV_LINK_MODE=copy

# Omit development dependencies
ENV UV_NO_DEV=1

# Ensure installed tools can be executed out of the box
ENV UV_TOOL_BIN_DIR=/usr/local/bin

COPY ./scheduler/pyproject.toml ./scheduler/uv.lock* ./

# Install the project's dependencies using the lockfile and settings
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=scheduler/uv.lock,target=uv.lock \
--mount=type=bind,source=scheduler/pyproject.toml,target=pyproject.toml \
uv sync --locked --no-install-project

# Then, add the rest of the project source code and install it
# Installing separately from its dependencies allows optimal layer caching
COPY ./scheduler/src /app/

RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked

# Place executables in the environment at the front of the path
ENV PATH="/app/.venv/bin:$PATH"

# Reset the entrypoint, don't invoke `uv`
ENTRYPOINT []

RUN chown -R nonroot:nonroot /app
USER nonroot

CMD ["celery", "-A", "scheduler.app:scram_api_scheduler", "worker", "--loglevel=info", "-E"]
14 changes: 13 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
[project]
name = "SCRAM"
version = "1.5.1"

# ==== pytest ====
[tool.pytest.ini_options]
addopts = "--ds=config.settings.test --reuse-db"
addopts = [
"--ds=config.settings.test",
"--reuse-db",
"--ignore=scheduler"
]
minversion = "6.0"
python_files = [
"tests.py",
Expand Down Expand Up @@ -139,3 +147,7 @@ module = "*.migrations.*"

[tool.django-stubs]
django_settings_module = "config.settings.test"


[tool.uv.workspace]
exclude = ["scheduler"]
Loading
Loading