CircleCI

In this section we are going to use CircleCI as our continuous-integration service. In a few words CircleCI automates your software builds, tests, and deployments. It supports different programming languages and for our particular case, it supports the Crystal language.

In this section we are going to present some configuration examples to see how CircleCI implements some continuous integration concepts.

CircleCI orbs

Before showing some examples, it’s worth mentioning CircleCI orbs. As defined in the official docs:

Orbs define reusable commands, executors, and jobs so that commonly used pieces of configuration can be condensed into a single line of code.

In our case, we are going to use Crystal’s Orb

Build and run specs

Simple example using latest

Let’s start with a simple example. We are going to run the tests using latest Crystal release:

.circleci/config.yml

  1. workflows:
  2. version: 2
  3. build:
  4. jobs:
  5. - crystal/test
  6. orbs:
  7. crystal: manastech/crystal@1.0
  8. version: 2.1

Yeah! That was simple! With Orbs an abstraction layer is built so that the configuration file is more readable and intuitive.

In case we are wondering what the job crystal/test does, we always may see the source code.

Using nightly

Using nightly Crystal release is as easy as:

.circleci/config.yml

  1. workflows:
  2. version: 2
  3. build:
  4. jobs:
  5. - crystal/test:
  6. name: test-on-nightly
  7. executor:
  8. name: crystal/default
  9. tag: nightly
  10. orbs:
  11. crystal: manastech/crystal@1.0
  12. version: 2.1

Using a specific Crystal release

.circleci/config.yml

  1. workflows:
  2. version: 2
  3. build:
  4. jobs:
  5. - crystal/test:
  6. name: test-on-0.30
  7. executor:
  8. name: crystal/default
  9. tag: 0.30.0
  10. orbs:
  11. crystal: manastech/crystal@1.0
  12. version: 2.1

Installing shards packages

You need not worry about it since the crystal/test job runs the crystal/shard-install orb command.

Installing binary dependencies

Our application or maybe some shards may require libraries and packages. This binary dependencies may be installed using the Apt command.

Here is an example installing the libsqlite3 development package:

.circleci/config.yml

  1. workflows:
  2. version: 2
  3. build:
  4. jobs:
  5. - crystal/test:
  6. pre-steps:
  7. - run: apt-get update && apt-get install -y libsqlite3-dev
  8. orbs:
  9. crystal: manastech/crystal@1.0
  10. version: 2.1

Using services

Now, let’s run specs using an external service (for example MySQL):

.circleci/config.yml

  1. executors:
  2. crystal_mysql:
  3. docker:
  4. - image: 'crystallang/crystal:latest'
  5. environment:
  6. DATABASE_URL: 'mysql://root@localhost/db'
  7. - image: 'mysql:5.7'
  8. environment:
  9. MYSQL_DATABASE: db
  10. MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
  11. workflows:
  12. version: 2
  13. build:
  14. jobs:
  15. - crystal/test:
  16. executor: crystal_mysql
  17. pre-steps:
  18. - run:
  19. name: Waiting for service to start (check dockerize)
  20. command: sleep 1m
  21. - checkout
  22. - run:
  23. name: Install MySQL CLI; Import dummy data
  24. command: |
  25. apt-get update && apt-get install -y mysql-client
  26. mysql -h 127.0.0.1 -u root --password="" db < test-data/setup.sql
  27. orbs:
  28. crystal: manastech/crystal@1.0
  29. version: 2.1

Note

The explicit checkout in the pre-steps is to have the test-data/setup.sql file available.

Caching

Caching is enabled by default when using the job crystal/test, because internally it uses the command with-shards-cache