Development =========== Development is performed locally using the same Django application and PostgreSQL database technology used in deployed environments. The development environment is intentionally kept relatively simple. Production services are replaced with local alternatives where practical so that routine development does not require access to production infrastructure or credentials. Local Development ----------------- The application requires Python, PostgreSQL, and Git for local development. After cloning the repository, create and activate a Python virtual environment and install the project dependencies. .. code-block:: console python -m venv venv source venv/bin/activate pip install -r requirements.txt Create a local PostgreSQL database and configure the development environment to use it. Apply the database migrations: .. code-block:: console python manage.py migrate Create a Wagtail administrator account if needed: .. code-block:: console python manage.py createsuperuser The development server can then be started with: .. code-block:: console python manage.py runserver The Wagtail administration interface is available at ``/admin/`` in the local development environment. Settings -------- Django settings are separated by environment. Shared application configuration is maintained in the base settings, while development and production settings provide environment-specific behavior. The development environment uses local alternatives for services that do not need to be exercised during routine development. For example, uploaded files can use filesystem storage rather than Amazon S3, and outgoing email can use Django's console email backend rather than Amazon SES. Production credentials are not required for normal local development. Dependencies ------------ Python dependencies are maintained in the project's dependency configuration and committed to source control. Dependencies are added deliberately rather than automatically introducing a package for functionality that can be implemented clearly within the application. When dependencies are updated, application tests are run before the changes are deployed. Framework and library upgrades are treated as application changes and move through the same review and deployment process as other code changes. Testing ------- Automated tests are used to verify application behavior and reduce the risk of regressions as the site changes. Tests create their own predictable data and do not depend on copies of the production database. Where application behavior depends on an external service, that dependency can be mocked or isolated so tests do not make requests to production systems. Tests are run locally during development and as part of the source-control workflow before changes are deployed. The complete test suite can be run with: .. code-block:: console python manage.py test Tests are intended to verify application behavior rather than implementation details wherever practical. This allows internal code to change without requiring unrelated tests to be rewritten. Front-End Development --------------------- The site's front end uses Bootstrap with a relatively small amount of custom CSS and JavaScript. Custom styles and scripts are maintained directly in the application's static files. The project does not currently require Sass compilation, a JavaScript bundler, or a Node-based front-end build process. Reusable presentation is primarily implemented through Django templates and Wagtail content blocks. Changes to shared components should generally be made in the component template or stylesheet rather than repeated on individual pages. Front-end changes should be reviewed at multiple viewport sizes and with keyboard navigation. Changes affecting interactive components should also be checked for appropriate focus behavior and accessible state information. Documentation ------------- Technical documentation is maintained with Sphinx in the ``docs/`` directory of the repository. Documentation should be updated as part of the same change that alters the behavior it describes. This is particularly important for architectural decisions, configuration, deployment procedures, external services, and other information that may not be apparent from reading the application code. To build the documentation locally: .. code-block:: console cd docs make html Generated documentation can be rebuilt from a clean state with: .. code-block:: console make clean make html The generated HTML is served with the application at ``/docs/``. Development Practices --------------------- Changes are developed in Git branches rather than directly on the main branch. A typical change follows a small number of steps: #. Create a branch for the change. #. Implement the change locally. #. Add or update tests where appropriate. #. Update documentation when behavior or architecture has changed. #. Run the test suite. #. Push the branch to GitHub and create a pull request. Temporary Heroku Review Apps can be created from pull requests when a change benefits from testing in a deployed environment. They are useful for review and integration testing but are not required for every change. After a change has been reviewed and merged, the deployment workflow takes over. Staging, production promotion, and environment-specific deployment behavior are documented separately in :doc:`deployment`. Working Principles ------------------ Local development should be safe to perform without access to production data or production credentials. Code, tests, and documentation are treated as parts of the same application. A change is not fully represented in source control if the behavior changes but the relevant tests or documentation are knowingly left behind. Development tooling is added when it solves a recurring problem. The project does not require every tool that might be useful on a larger application, and keeping the local development environment understandable is itself a maintenance consideration.