-
.env.example — append the var with a placeholder value matching the host-surface convention. Hostnames here point at localhost. Example: MY_NEW_VAR=test (for secrets) or MY_NEW_VAR=http://localhost:1234 (for endpoints).
-
.env.docker.example — append the same var, but with the container-surface value. Hostnames here point at docker-compose service names (e.g. redis://result:6379 instead of redis://localhost:6379). Example: MY_NEW_VAR=test (secrets are usually the same) or MY_NEW_VAR=http://floci:4566 (endpoints differ).
-
vinta_schedule_api/settings/base.py (or the appropriate per-env settings file) — read the var via python-decouple-typed:
from decouple import config
MY_NEW_VAR = config("MY_NEW_VAR", cast=str)
MY_NEW_VAR = config("MY_NEW_VAR", default="fallback")
MY_NEW_VAR_TIMEOUT = config("MY_NEW_VAR_TIMEOUT", cast=int, default=30)
MY_NEW_VAR_ENABLED = config("MY_NEW_VAR_ENABLED", cast=bool, default=False)
Place the setting in the section that fits its purpose (third-party integration block, security block, etc.). If multiple settings files use it (base.py + production.py differ), put it in base.py and override in the more specific file only when needed.
-
render.yaml — add the var under the appropriate envVarGroup. For secrets, set sync: false (Render hides the value from public manifest). For values shared across services, use the existing groups (python-services, integrations-credentials); create a new group only if the var belongs to a new logical bundle.
envVarGroups:
- name: integrations-credentials
envVars:
- key: MY_NEW_VAR
sync: false
- key: MY_NEW_OPTIONAL
value: "default"
-
.github/workflows/main.yml — append the var to every step that runs manage.py, pytest, ruff, or check --deploy with a placeholder value safe for CI. Pattern: under each env: block for those steps, add:
MY_NEW_VAR: 'FAKE_VAR_FOR_CI'
For secrets that must be real in CI (e.g. an integration test that hits a sandbox), wire from ${{ secrets.MY_NEW_VAR }} and add the secret in the repo settings.
-
ai-tools/AGENTS.md — append the var name to the Environment Variables section's listing. No value, just the name. Production-only vars go to the production-vars sentence below the main code fence.
-
Consumer code — import settings (from django.conf import settings) and read settings.MY_NEW_VAR. Never os.environ / os.getenv outside vinta_schedule_api/settings/.
-
Tests — if the var has integration-test consequences, add fixtures in conftest.py that override it (@pytest.fixture(autouse=True) + settings.MY_NEW_VAR = "..." via pytest-django's settings fixture, or monkeypatch.setenv for env-level overrides). For unit tests, pytest.ini's --ds=vinta_schedule_api.settings.test keeps test-time defaults predictable; add the var to vinta_schedule_api/settings/test.py if its test default differs from base.py.