CircleCI - одно из самых популярных и удобных решений для непрерывной интеграции. Он поддерживает множество языков программирования и инструментов, включая Elixir и Erlang / OTP.
CircleCI полностью бесплатен, когда речь идет о репозиториях GitHub с открытым исходным кодом, но он также предоставляет бесплатные 1500 минут в месяц для любых частных репозиториев.
Начиная с версии 2.0 CircleCI может создавать задания на основе любых образов из DockerHub. Эта функция позволяет создавать любой язык программирования или платформу, которые можно разместить в образе Docker.
Представьте, что у вас есть стандартное приложение Elixir Phoenix / Ecto. Вам нужно запустить его на последних версиях Elixir и Erlang / OTP и запустить тесты в базе данных PostgreSQL.
Начнем с создания файла конфигурации CircleCI в .circleci/config.yml
:
version: 2 # use CircleCI 2.0 instead of CircleCI Classic
jobs: # basic units of work in a run
build: # runs not using Workflows must have a `build` job as entry point
parallelism: 1 # run only one instance of this job in parallel
docker: # run the steps with Docker
- image: circleci/elixir:1.6 # ...with this image as the primary container; this is where all `steps` will run
environment: # environment variables for primary container
MIX_ENV: test
SHELL: /bin/bash
- image: mdillon/postgis:9.6-alpine # database image
environment: # environment variables for database
POSTGRES_DB: app_test
steps: # commands that comprise the `build` job
- checkout # check out source code to working directory
- run: mix local.hex --force # install Hex locally (without prompt)
- run: mix local.rebar --force # fetch a copy of rebar (without prompt)
Как видите, мы объявляем build
задание на непрерывную интеграцию. В основном мы будем использовать Elixir 1.6 с PostgreSQL 9.6 для запуска тестов в базе данных app_test
. После этого мы проверим базу исходного кода, чтобы внести наши последние изменения в сборку. mix local
задач также необходимы, чтобы использовать любую из задач Смешать позже.
Запуск тестов и качество кода
Все мы хотим выполнить все стандартные этапы непрерывной интеграции, такие как:
- Получить зависимости и скомпилировать приложение
- Запустить инструменты и проверки качества кода (подробнее об этом можно прочитать здесь)
- Выполните все тесты, чтобы убедиться, что наша сборка успешна и безошибочна.
- Запускайте тяжелые и громоздкие инструменты статического анализа
Также мы хотим сделать наши сборки максимально быстрыми, поэтому нам обязательно нужно кеширование. Давайте продолжим нашу конфигурацию и выполним шаги, описанные выше:
- restore_cache: # restores saved mix cache
keys: # list of cache keys, in decreasing specificity
- v1-mix-cache-{{ .Branch }}-{{ checksum "mix.lock" }}
- v1-mix-cache-{{ .Branch }}
- v1-mix-cache
- restore_cache: # restores saved build cache
keys:
- v1-build-cache-{{ .Branch }}
- v1-build-cache
- restore_cache: # restores saved plt cache
keys:
- dialyzer-cache
- run: mix do deps.get, compile # get updated dependencies & compile them
- save_cache: # generate and store cache so `restore_cache` works
key: v1-mix-cache-{{ .Branch }}-{{ checksum "mix.lock" }}
paths: "deps"
- save_cache: # make another less specific cache
key: v1-mix-cache-{{ .Branch }}
paths: "deps"
- save_cache: # you should really save one more cache just in case
key: v1-mix-cache
paths: "deps"
- save_cache: # don't forget to save a *build* cache, too
key: v1-build-cache-{{ .Branch }}
paths: "_build"
- save_cache: # and one more build cache for good measure
key: v1-build-cache
paths: "_build"
- run: mix do format --check-formatted, credo --strict, security
- run: mix do xref deprecated --include-siblings, xref unreachable --include-siblings, xref graph --format stats
- run: # special utility that stalls main process until DB is ready
name: Wait for DB
command: dockerize -wait tcp://localhost:5432 -timeout 1m
- run: mix do ecto.migrations, ecto.load
- run: mix test # run all tests in project
- run: mix dialyzer --halt-exit-status
- save_cache:
key: dialyzer-cache
paths: "_build/test/dialyxir*.plt"
- store_test_results: # upload test results for display in Test Summary
path: _build/test/lib/app/results.xml
Теперь вы можете запускать новые сборки, зарегистрировавшись в CircleCI, поскольку он будет запускать конфигурацию и шаги из вашей конфигурации. Каждая фиксация в любой ветке запускает задание сборки, и вы будете знать, если что-то не так с вашим кодом.
Развертывание
Однако наличия только одного задания на сборку недостаточно даже для простейшего процесса CI. Чаще всего нам нужно сделать выпуск постановки / производства на Ликеро-водочном заводе.
Давайте продолжим заполнение нашего файла конфигурации, добавив новое deploy
задание:
deploy:
docker:
- image: circleci/elixir:1.6
environment: # environment variables for primary container
SHELL: /bin/bash
MIX_ENV: staging
steps:
- checkout # check out source code to working directory
- run: mix local.hex --force # install Hex locally (without prompt)
- run: mix local.rebar --force # fetch a copy of rebar (without prompt)
- run: mix do deps.get, compile # get updated dependencies & compile them
# set MIX_ENV to prod or staging value according to the source branch
- run:
name: Update MIX_ENV environment variable
command: |
echo "export MIX_ENV=$(if [ '$CIRCLE_BRANCH' '==' 'master' ]; then echo 'prod'; else echo 'staging'; fi)" >> $BASH_ENV
source $BASH_ENV
- run: cd deps/argon2_elixir && make clean && make && cd -
- run: MIX_ENV=staging mix release --env $MIX_ENV
- run: tar -zcvf $CIRCLE_SHA1.tar.gz bin appspec.yml VERSION _build/$MIX_ENV/rel/app/releases/$(cat VERSION)/app.tar.gz
Этого будет достаточно, чтобы создать отдельное задание развертывания, которое будет запускаться в отдельном образе Docker. Однако нам нужно будет запускать его только в ветвях разработки и master, чтобы соответственно загружать промежуточные / производственные выпуски. Мы можем добиться этого, используя рабочий процесс CircleCI и предоставляя простую конфигурацию внизу нашего файла конфигурации:
workflows:
version: 2
build-and-deploy:
jobs:
- build
- deploy:
requires:
- build
filters:
branches:
only:
- develop
- master
После этого вы можете загрузить собранный релиз на любой сервер или любую платформу, какую захотите. Вы можете использовать Edeliver, Ansible, Chef, Docker - выбор за вами.
Вывод
Как вы можете видеть выше, создавать и развертывать приложения Elixir с CircleCI 2.0 не так уж и сложно. Эта платформа достаточно гибкая и быстрая, чтобы сделать вашу непрерывную интеграцию яркой и яркой.
Если вы хотите узнать больше по теме, то давайте прочитаем Документацию CircleCI 2.0 и Руководство по языку Elixir.
Всем удачного взлома!
Эта статья изначально была размещена на моем собственном сайте.