Skip to content


CI, or continuous integration, is the process of merging code into a shared mainline version. For us this means merging our local changes into the remote repository after checking for errors.

I aim for three checks in CI,

  1. the code is correctly formatted according to an autoformatter,
  2. the code is correctly structured, there are no syntax issues, and there isn't any unused code,
  3. the code passes all the tests.

Which I'll refer to as the formatting, linting, and testing stages of CI.

Activating CI resources

Gitlab CI/CD logo

We need compute resources to run these stages, so lets make use of Gitlab-CI's shared runners by adding shared_runners_enabled = true to the infrastructure/ file (note only the relevant resource is shown),

resource "gitlab_project" "tozo" {
  shared_runners_enabled     = true

with ... representing the existing code. This allows us to write a .gitlab-ci.yml file that runs CI jobs on every push to the remote repository master.

It is also useful to schedule jobs e.g. the dependency checker, to run periodically via this addition to the infrastructure/ file,

resource "gitlab_pipeline_schedule" "tozo" {
  project     =
  description = "Schedule checks against the codebase"
  ref         = "main"
  cron        = "0 9 1 * *"

which will trigger the check at 9am on the 1st day of each month, see crontab guru for more.


Remember to re-run

terraform apply
and re-encrypt the state,

ansible-vault encrypt terraform.tfstate --output=terraform.tfstate.vault

after making changes to the infrastructure.