Skip to content

chore(deps): upgrade to Django 5.2 LTS and bump Django-coupled dependencies - #963

Merged
nimish-ks merged 2 commits into
mainfrom
chore--bump-django
Aug 7, 2026
Merged

chore(deps): upgrade to Django 5.2 LTS and bump Django-coupled dependencies#963
nimish-ks merged 2 commits into
mainfrom
chore--bump-django

Conversation

@rohan-chaturvedi

Copy link
Copy Markdown
Member

🔍 Overview

Django 4.2.30 has reached end-of-life. This PR bumps Django to 5.2 LTS.

5.2 was chosen over 6.x deliberately — it's the next LTS (longest support runway) and our Python 3.12 already meets its 3.10+ floor, whereas 6.0 is a larger jump for a shorter support window (EOL ~April 2027). Skipping 5.0/5.1 is safe here because the codebase uses almost none of the APIs removed along the way (audited; see below).

💡 Proposed Changes

Django + Django-coupled dependency bumps (backend/requirements.txt):

Package Before After Reason
Django 4.2.30 5.2.17 Next LTS, security-supported to Apr 2028
djangorestframework 3.15.2 3.16.1 First release with Django 5.2 support
graphene-django 3.2.0 3.2.3 3.2.0 registers the removed models.NullBooleanField at import → crashes on boot under 5.1+
django-cors-headers 3.14.0 4.9.0 3.14 predates Django 5.x
django-rq 3.0.0 3.1 Smallest 5.2-safe step (avoids the rq>=2.6.1 floor introduced in 3.2)
dj-rest-auth 7.0.1 7.1.1 First release with Django 5.2 support
django-allauth 65.4.1 65.7.0 First release with Django 5.2 support
django-filter 23.1 removed Verified unused — no imports, not in INSTALLED_APPS, no graphene lazy-filter usage

Code fix for a removed APIdjango.utils.timezone.utc (removed in Django 5.0) → stdlib datetime.timezone.utc (aliased dt_timezone, matching the existing pattern in api/views/identities/aws/iam.py):

  • backend/backend/schema.py — 4 call sites in the log date-range resolvers
  • backend/api/views/audit.py — 2 call sites in the public audit-log view

No model, GraphQL schema, or migration changes.

🖼️ Screenshots or Demo

N/A — backend dependency upgrade with no UI or API-contract changes.

📝 Release Notes

  • Chore / maintenance: upgraded the backend to Django 5.2 LTS and refreshed Django-coupled dependencies to restore a security-supported baseline. No user-facing behavior or API changes.
  • Deployment note: dependencies are installed into the Docker image at build time, so deployments must rebuild the backend and worker images to pick up the new pins (a plain restart is not enough).

❓ Open Questions

  • django-allauth pin level. Pinned conservatively at 65.7.0 (minimum with 5.2 support, least-breaking). Latest is 65.19.0 and works with the new dj-rest-auth 7.1.1 — but 65.14.2+ stopped trusting X-Forwarded-For for rate-limit IP detection, so behind nginx we'd need ALLAUTH_TRUSTED_PROXY_COUNT or ALLAUTH_TRUSTED_CLIENT_IP_HEADER (e.g. X-Real-IP). Keep the minimal bump, or go latest + add proxy config?
  • Deferred optional cleanups (non-blocking, left out to keep the diff focused): naive datetime.utcnow() in ee/integrations/secrets/dynamic/aws/utils.py, unique_togetherUniqueConstraint on OrganisationSSOProvider (would add a migration), and the now-unused pytz pin.

🧪 Testing

  • Automated: pytest1087 passed, 1 failed. The single failure (tests/utils/test_secret.py::test_file_read_permission_error) is a pre-existing tests-as-root artifact — the dev container runs as uid=0, and root bypasses the chmod(0o000) the test relies on, so the fallback path never triggers. It is independent of the Django version and does not reproduce when tests run as non-root (e.g. CI).
  • manage.py check: 0 issues — GraphQL schema imports cleanly (no NullBooleanField crash), no Relay-ordering or model problems.
  • Migrations: migrate --check exits 0, nothing pending — the existing migration graph loads under 5.2 with no new migrations.
  • Runtime smoke: backend (runserver) and rqworker both rebuilt and running Django 5.2.17; server responds HTTP 200; worker pool + scheduler start cleanly (0 restarts).
  • Targeted — duplicate-secret handling (check_for_duplicates_blind, the gate behind POST /secrets/ → 409): verified under 5.2 that same-key/same-path is flagged as a duplicate while a different key, or the same key at a different path, is not (path-scoping intact).

🎯 Reviewer Focus

  • backend/requirements.txt — the version bumps and the django-filter removal.
  • The timezone.utcdt_timezone.utc change in backend/backend/schema.py and backend/api/views/audit.py (the only code change — confirm the log date-range filters behave identically).

➕ Additional Context

  • Each Django-coupled dependency was checked against its changelog / PyPI classifiers for the minimum release that adds Django 5.2 support; bumps are intentionally minimal to reduce blast radius.
  • The two hard blockers on 5.2 were the graphene-django NullBooleanField import crash (a 5.1 removal) and the django.utils.timezone.utc removal (5.0) — both addressed here.

✨ How to Test the Changes Locally

# Rebuild both images so the new pins are installed (deps are baked in at build time)
docker compose -f dev-docker-compose.yml build backend rqworker
docker compose -f dev-docker-compose.yml up -d backend rqworker

# Confirm the running version (both should print 5.2.17)
docker compose -f dev-docker-compose.yml exec backend  python -c "import django; print(django.get_version())"
docker compose -f dev-docker-compose.yml exec rqworker python -c "import django; print(django.get_version())"

# System checks + migration state
docker compose -f dev-docker-compose.yml exec backend python manage.py check
docker compose -f dev-docker-compose.yml exec backend python manage.py migrate --check

# Test suite (expect 1087 passed, 1 pre-existing root-only failure)
docker compose -f dev-docker-compose.yml exec backend pytest tests/ -q

Then click through auth (email login + each OAuth provider), the console UI (apps / environments / secrets), and the audit + secret log date-range filters, and trigger a sync — see the PR discussion for the full manual checklist.

💚 Did You...

  • Ensure linting passes (code style checks)? — trivial import-only code change; no dedicated linter run in this PR
  • Update dependencies and lockfiles (if required) — requirements.txt is the pinned manifest; updated
  • Update migrations (if required) — none required; no model changes, migrate --check clean
  • Regenerate graphql schema and types (if required) — not required; no GraphQL type changes
  • Verify the app builds locally? — backend + worker images rebuilt; both run on Django 5.2.17
  • Manually test the changes on different browsers/devices? — backend-only; API-level smoke done, browser auth/UI pass recommended before merge

@rohan-chaturvedi rohan-chaturvedi self-assigned this Aug 7, 2026
@rohan-chaturvedi rohan-chaturvedi added dependencies Pull requests that update a dependency file backend labels Aug 7, 2026
@nimish-ks
nimish-ks merged commit a048439 into main Aug 7, 2026
15 checks passed
@nimish-ks
nimish-ks deleted the chore--bump-django branch August 7, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants