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 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"):

$ ./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:

$ ./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 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 :<tag>

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.

See also

Local CI – run this pipeline locally against the same .gitlab-ci.yml, without touching shared runner minutes.