Rust + Diesel + GitLab + CI
The folks over at GitLab give away some free compute power to allow users to have CI builds of their project. It is very straightforward to get Rust projects to build within a CI environment. This post is going to take that build process one small step further, we’re going to build a Rust project that uses the Diesel ORM. This adds a step of complexity since to compile a Diesel project you need to have a postgresql database accessible if you’re using the
Note: diesel has instructions for using
diesel print-schema instead of using
infer_schema!() in version 1.3.x.
It has been proposed to move away from . A redditor commented that
infer_schema!(), but that issues was closed because
infer_schema!() is still useful
infer_schema!() has been deprecated in diesel 1.3.
The Following assumes you already have rust installed, if not see the awesome project rustup.
First The Very Basics
Create an example project in GitLab then create the rust project using
cargo new hello_ci
Within that project directory create the CI rule file named
.gitlab-ci.yml with the following:
# Use Rust docker image, see: https://hub.docker.com/_/rust/ image: rust:latest # Defines stages which are to be executed stages: - build # Run `cargo build` for the project with stable Rust run-build: stage: build image: rust:latest script: - rustc --version && cargo --version - cargo build --release --jobs 1
Make sure to add the file to your git project, and push to GitLab.
git add .gitlab-ci.yml git commit -am "Adding CI file" git push
Once the project has been pushed, GitLab will kick off a build automatically. See the example screenshots, and note, to see the CI features in GitLab, expand the
CI / CD menu on the left panel and select
Jobs. And don’t worry, if something goes wrong, GitLab will kindly email you.
Adding in a Little Diesel
Now that the trivial case is completed, let’s take a look at adding in Diesel to the project. Let’s use the diesel getting_started_1 project as an example.
In order to build a project that uses Diesel (and uses
infer_schema!()) we need to have a postgresql database accessible. You could use the standard Rust Docker image and then install/configure postgresql then configure postgres to trust local connection, then create the bare DB with psql and then build your project, but that’s, like, kind of a pain. I know this process because I went down that rat-hole first. Fortunately there’s a more elegent solution, GitLab’s services with Postgres.
You just need to configure the GitLab postgres service for your project with the following snippet in your
services: - postgres:latest variables: POSTGRES_DB: diesel_example_db_1 POSTGRES_USER: runner POSTGRES_PASSWORD: ""
POSTGRES_DB is the name of the database and
POSTGRES_USER is the name of the database user … makes sense.
runner appears to be the standard
POSTGRES_USER, however it can be anything. In general, these can be anything as long as your consistent with your
DATABASE_URL variable further down in the build section of your
You’re also going to need
diesel_cli installed into your build container. That can be added to the container using the
before_script section of the CI config file.
before_script: - cargo install diesel_cli
Putting it all together the whole
# Use Rust docker image, see: https://hub.docker.com/_/rust/ image: rust:latest # postgres ci: https://docs.gitlab.com/ee/ci/services/postgres.html services: - postgres:latest variables: POSTGRES_DB: diesel_example_db_1 POSTGRES_USER: runner POSTGRES_PASSWORD: "" before_script: - cargo install diesel_cli # Defines stages which are to be executed stages: - build # Run `cargo test` for the project with stable Rust run-build: when: manual stage: build image: rust:latest variables: DATABASE_URL: "postgres://runner@postgres/diesel_example_db_1" script: # - diesel migration run - rustc --version && cargo --version - cargo build --release --verbose --jobs 1
Note that I have defined
when: manual which means you need to manual start the Pipeline in the UI instead of having it kicked off as part of the push. I usually set my CI builds to manual since GitLab is giving this compute time away for free, I don’t want to be an abuser of the service, see GitLab issue 23366. note: a reddit commenter pointed out the linked bug is more about too many artifacts instead of actually compute usage. And that there are limitations to the free CI service where a user is allotted a certain number of CI minutes, 2000 for a free plan.
Related and Recommended Reading
I got some nice tidbits from the following post.
This post will also teach you how to improve build times on GitLab’s CI.
My Example project that is configured to use GitLab’s CI,