CI == Continuous integration is held by Gitlab server which provides limited (CPU time/month) platform for auto-triggering the integration. Integration can be run manually or automatically after each push with new commits. Settings -------- Settings is saved inside ``.gitlab-ci.yml`` file. The file is placed in the project root. The CI configuration is placed inside and the documentation to Gitlab CI is `here `_. As helping service server ``docker:dind`` image, which is Docker in a Docker. The image provides docker daemon which is then set via ``DOCKER_HOST`` environment variable to the CI engine. Stages ------ Three stages run sequentially: ``code`` -> ``test`` -> ``build``. * The ``code`` stage runs static checks and is the fastest gate. * The ``test`` stage builds the application image and runs the Django test suite (see :doc:`/architecture/testing`). * The ``build`` stage publishes the image to the registry. Jobs in this stage only run on ``master``, on tagged commits, or via manual trigger -- branch pushes do not produce a published image. The workflow rules in ``.gitlab-ci.yml`` further restrict pipelines to merge requests, ``master``, and tags. Jobs ---- ``vulture`` ~~~~~~~~~~~ Dead-code detector. Runs ``vulture`` against ``app/richy`` with ``--min-confidence 100``, excluding ``node_modules`` and migrations. Any reported dead code fails the job. ``ruff`` ~~~~~~~~ Lints the entire repository with ``ruff check``. ``typos`` ~~~~~~~~~ Spell-checks the repository with `typos `_. Configuration lives in ``_typos.toml``. ``tests`` ~~~~~~~~~ Builds the dev image, brings up the ``compose.ci.yaml`` stack, and runs every test in the project **except** those tagged ``@tag("network")``: .. code-block:: bash $ ./manage.py test --no-input -v 3 --exclude-tag=network This is the hard gate -- any failure fails the pipeline and blocks merge. The 15-minute timeout is conservative; typical runs are much shorter. ``tests:network`` ~~~~~~~~~~~~~~~~~ Same image and compose stack as ``tests``, but runs **only** the network-tagged tests: .. code-block:: bash $ ./manage.py test --no-input -v 3 --tag=network The job is marked ``allow_failure: true`` so a failure surfaces as a yellow warning in the MR UI but does not block the pipeline or the ``build`` stage. The 5-minute timeout caps worst-case CI cost when upstream services tarpit requests from the CI's data-center egress IP. See :doc:`/architecture/testing` for the design rationale and what makes a test "network". ``build`` ~~~~~~~~~ Builds and pushes the application image to GitLab's container registry (``registry.gitlab.com/imn1/richy``). Runs only on: * ``master`` -- pushed as ``:nightly`` * tag ``stable`` -- pushed as ``:latest`` * version tags matching ``[0-9.]+`` -- pushed as ``:`` ``build_branch`` ~~~~~~~~~~~~~~~~ Same as ``build`` but runs on non-master branches and is **manual** (``when: manual``, ``allow_failure: true``). Useful for producing a testable image from a feature branch without merging to master. The image tag is derived from the branch name (slashes replaced with dashes). ``build_docker_hub`` ~~~~~~~~~~~~~~~~~~~~ Mirrors the ``build`` job to Docker Hub (``n1cz/richy``) under the same triggering rules. Authenticates via the ``DOCKER_IO_USER`` / ``DOCKER_IO_PASSWORD`` CI variables. .. seealso:: :doc:`local_ci` -- run this pipeline locally against the same ``.gitlab-ci.yml``, without touching shared runner minutes.