С тех пор, как я слышал о действиях GitHub (с данного указанного как ГСА), я хотел пробовать это в одном из моих проектов. Кроме того, я хотел написать тесты, так как в коде BootCamp я взял не было возможности реализовать их во время окончательного проекта. Так что дали эти две темы, о которых я хотел больше узнать, я решил вручить их вместе и экспериментировать создание рабочего процесса GitHub Actions для тестов. Несмотря на то, что наступившие по учебникам/статьям о настройке рабочих процессов GHA для приложений Rails, я не нашел никаких конкретных учебных пособий, объясняющих, как настроить рабочий процесс GHA для проверки рельсов на приложение Docker. Следовательно, я подумал, что если бы я написал статью, объясняющую мой подход, я мог бы помочь кому-то.
Я предполагаю, что те, кто читает эту статью, уже как-то знакомы с GHA, Docker и Rails, поэтому я сосредоточусь на объяснении установок рабочего процесса.
В приложении Simple Rails, используемое для создания рабочего процесса, есть три службы, которые нам нужно для запуска тестов: сам приложение, база данных (Postgres) и инструмент, который позволяет нам выполнять системные тесты, имитируя браузер (Selenium ). Следовательно, нам нужно создать три контейнера, по одному для каждого из этих услуг.
Я решил попробовать два подхода к рабочему процессу: тот, который использует контейнеры служб GHA и еще один, который создает эти услуги, основанные на DockerFiles, которые мы определим. В конце концов, мой любимый подход оказался первым, так как легче настроить и немного быстрее. Давайте посмотрим на эти подходы подробно.
Услуги контейнеров подходят Наша цель в настройке этого рабочего процесса — проверять приложение каждый раз, когда на нашем репозитории выполняется на нашем хранилище. Есть только несколько тестов в приложении (одна модель теста и пару системных тестов) в качестве основной цели этого учебника состоит в том, чтобы показать базовую настройку для реализации рабочего процесса GHA для запуска тестов на каждом толчке (а не методологию тестирования сам). Мы используем тестовую структуру Rail по умолчанию, Ministest. Мы начнем с появления Test-Services.yml
Файл, помещенный внутри .Github/Workflows
папка.
Давайте пройдем по каждому шагу этой конфигурации.
Во-первых, мы определяем, какое действие будет вызвать этот рабочий процесс: в нашем случае точка зрения будет делать это. Затем мы настроили некоторые переменные Env, связанные с тестовой средой, и указываем, какой тип бегуна мы хотим использовать (Ubuntu).
name: Test on: [push] jobs: test: env: RAILS_ENV: test NODE_ENV: test runs-on: ubuntu-latest # runner }
Далее мы вводим часть служб (которая должна быть размещена до начала шагов). Мы должны указать все услуги, которые нам нужно запустить наши тесты: в этом случае, Postgres и Selenium с помощью браузера Chrome. Делая это, GHA создаст один контейнер для каждого из услуг и конкретной сети, чтобы контейнеры могли общаться друг с другом. Сетевая часть важна для этой настройки, потому что позже нам нужно будет подключиться к нему, чтобы выполнить наши тесты. Вы можете узнать больше о контейнерах услуг GHA и как их настроить здесь Отказ
services: database: image: postgres env: POSTGRES_PASSWORD: postgres ports: - 5432:5432 options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 chrome: image: selenium/standalone-chrome-debug ports: - 4444:4444 - 5900:5900 volumes: - /dev/shm:/dev/shm }
Теперь мы ходим на часть «шагов» конфигурации. Первый шаг, названный «News Services Network», будет хранить под переменной services_network
Имя сети, создаваемое для контейнеров услуг. Позже на шаге имени «пробежные тесты», мы получим доступ к этой переменной и используем его для подключения нашего основного контейнера к сетью контейнеров услуг. На следующем шаге «Checkout Code» мы используем действие GHA, называемую Checkout, которое « проверяет ваш репозиторий под $ github_workspace, поэтому ваш рабочий процесс может получить доступ к нему. «
steps: - name: Output services network id: network run: | echo ::set-output name=services_network::${{ job.container.network }} echo ${{ job.container.network }} - name: Checkout code uses: actions/checkout@v2
Следующим шагом опирается на Docker Action, которое устанавливает Docker BuildX в Runner, используемый для запуска нашего рабочего процесса. BuildX — это плагин CLI, который позволяет использовать дополнительные функции Toolkit Buildkit Builder Suilder. Основная причина, по которой мы устанавливаем BuildX, заключается в пользу способности Buildkit для хранения докеровских слоев в качестве артефактов, которые позже будут ускорить наш рабочий процесс, кэшируя слои нашего Docker Builds. Установить: правда
Опция сделает BuildX Builder по умолчанию в Docker. На следующем шаге «Готовьте метки», мы, ну, подготавливая теги для изображений, которые мы строим/используем.
- name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 with: version: latest install: true - name: Prepare Tags id: tags run: | TAG=$(echo $GITHUB_SHA | head -c7) echo ::set-output name=tagged_image::${IMAGE}:${TAG} echo ::set-output name=tag::${TAG}
Затем мы используем действие GitHub, которое позволяет кэшировать зависимости для работы. По сути, он позволяет нам указать путь, который будет использоваться для кэширования и восстановления зависимостей. Вы можете указать любую папку, которую вы хотите, до тех пор, пока он пустой или содержит только данные ConditX Отказ На следующем шаге «Код сборки», мы наконец-то создам наше главное изображение, которое содержит приложение, которое мы хотим проверить. Мы используем действие Docker Build-push, которое, как следует по имени, позволяет нам построить и нажать изображения докера на GHA Runners. На этом этапе есть некоторые важные конфигурации, поэтому давайте перейдем на каждого из них.
Начнем с Push: false
, что означает, что мы не заинтересованы в толкании этого изображения в любом месте, так как мы просто хотим, чтобы это было проверено (на основе официальной документации этот вариант является ложным по умолчанию, поэтому мы могли бы его удалить из конфигурации, и результат быть таким же).
Далее приходит Файл: .ci-services/dockerfile-services.ci
, который говорит построителю, которое DockerFile использовать для сборки. Загрузить: правда
Опция загрузит результат сборки до документов. Если мы не укажем эту опцию, выполнение шага «Run Tests» не удастся, потому что он не найдет изображение, созданное на этом шаге, чтобы выполнить тесты.
Далее наступает две конфигурации, которые позволят получить кэширование и поиск кэширования для наших сборки: кэш-от
и кэш-к
Отказ На кэш-от
Мы указываем тип кэша (в нашем случае местный, но он также может быть в реестре), а его путь ( SRC =/TMP/.buildx-main-cache
). Этот путь должен показаться знакомым, поскольку мы устанавливаем его на предыдущем шаге «Cache основные слои изображения». Так что здесь мы говорим строителю использовать папку /tmp/.buildx-main-cache
, указанный на предыдущем шаге, чтобы получить кеш.
Что касается кэш-к
Опция, он напишет новый кеш, созданный сборкой на другой папке, называемую /tmp/.buildx-main-cache-new
Отказ Мы могли бы использовать ту же папку, что и в кэш-от
Вариант, но как это действие нажимает действие до сих пор не предлагает способа очистить кеш Мы должны кэшировать в другом месте, удалите /tmp/.buildx-main-cache
папка и переименовать /tmp/.buildx-main-cache-new
путь к /tmp/.buildx-main-cache.
(Это удаление и переименование команд выполняются на последнем шаге, «Переместить кеш»). Таким образом, мы можем запретить кэширование от огромных.
Хотя мы используем обычный Dockerfile в этом руководстве (без многоэтапного здания), стоит упомянуть важной конфигурацию, которая влияет на многоступенчатые здания: Режим = Макс
вариант внутри кэш-к
вариант. Режим = Макс
Опция позволяет кэширование всех слоев, генерируемых многоступенчатой DockerFile, а не только конечным слоем. Если вы используете многоступенчатый докер, и вам нужно получить доступ к промежуточному слою, вы должны установить Режим = Макс
на кэш-к
Вход.
Последний вариант — Тег
, который получит в качестве ввода Tagged_image
Переменная установлена на шаге «Подготовка тегов».
- name: Cache main image layers uses: actions/cache@v2 with: path: /tmp/.buildx-main-cache key: ${{ runner.os }}-buildx-main-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx-main- - name: Build code uses: docker/build-push-action@v2 with: push: false file: .ci-services/Dockerfile-services.ci load: true cache-from: type=local,src=/tmp/.buildx-main-cache cache-to: type=local,mode=max,dest=/tmp/.buildx-main-cache-new tags: ${{ steps.tags.outputs.tagged_image }}
Наконец, у нас все установлено, чтобы запустить наши тесты! Теперь мы можем запустить наш файл Pocter-Copose с некоторыми переменными ENV для создания контейнера от изображения, созданного на этапе «Код сборки», и выполнить нашу тестовую службу. Test_image_tag
Будут хранить имя изображения, которое мы построили на шаге «Код сборки» и Services_network
Будут хранить имя сети, создаваемую для контейнера услуг. Мы также указываем, какой файл Pocker-Compose будет использоваться ( .ci-services/docker-compose.test.services.yml
) И служба, которую мы хотим запустить ( Test
).
- name: Run Tests run: | TEST_IMAGE_TAG=${{ steps.tags.outputs.tagged_image }} SERVICES_NETWORK=${{ steps.network.outputs.services_network }} docker-compose -f .ci-services/docker-compose.test.services.yml run test
Теперь давайте посмотрим на файл Docker-Compose, который мы используем, чтобы понять, как используются эти переменные ENV.
Простое, чтобы увидеть, что мы используем Test_image_tag
ENV переменная, чтобы сказать Docker-Compose, какое изображение использовать для создания тестовой службы. Внутри тестовой службы мы также указываем два переменных ENV: HUB_URL
и Parallel_Workers
Отказ Первая — это конфигурация, связанная с Selenium, и она используется на application_system_test_case.rb
Файл, чтобы сообщить Rails, где найти исполняемый файл Chrome, который будет использоваться на системных тестах. Затем рельсы узнают, что он должен найти и выполнить браузер Chrome, расположенный в хромовом контейнере (определено на наших услугах), а не на месте.
Вторая переменная ENV, Parallel_Workers
То, что только утверждает, что должен быть только один «работник», чтобы запустить тесты, что означает, что тесты будут работать последовательно, а не одновременно. Очевидно, что это не самая эффективная настройка, но создавая больше «рабочих» для прогонских испытаний, будет означать запуск нескольких хромовых контейнеров, которые сделали бы наш рабочий процесс немного более сложным. Эта статья Должна помочь, если вы хотите узнать больше о том, как масштабировать службу Chrome для запуска тестов параллельно.
Возвращаясь к файлу COMBOSE Docker, после настройки переменных ENV, тестовый сервис выполнит команду для запуска тестов Rails ( Test Test && Rails Test: System
). Наконец мы можем увидеть, как Services_network
Переменная ENV используется: он говорит о контейнере тестового сервиса для подключения к определенной сети, которая создана для контейнеров услуг в начале нашего рабочего процесса. Быть подключенным к этой сети позволяет контейнером для тестирования для доступа к базе данных и контейнерам обслуживания Chrome для выполнения тестов.
Контейнеры Dockerfile подходят Я не буду воспользоваться много подробностей об этом подходе, так как у него много сходства с предыдущим подходом. То же самое, что и раньше, целью здесь состоит в том, чтобы проверить приложение каждый раз, когда на нашем репозитории возникают толкающие действия. Основное отличие заключается в том, что вместо использования контейнеров сервисов GHA мы будем использовать действие Docker’s Build-push для создания этих контейнеров. Так что для этого подхода у нас есть следующие test.yml
размещены на .Github/Workflows
папка:
Учитывая, что мы сейчас создаем наши две контейнеры обслуживания с нуля вместо использования контейнеров услуг GHA, test.yml
Файл становится немного более обширным. Теки и те же шаги, которые мы должны были выполнить только для нашего главного обслуживания в предыдущем подходе, теперь должны быть выполнены для Postgres и Chrome Services, а также: Подготовьте кэширование, создайте изображения и переместите кэш.
Кроме того, нам также нужно иметь два дополнительных Dockerfiles: один для службы Postgres и один для службы Chrome. Docker-Compose файл также немного отличается: теперь он должен использовать переменные ENV для обозначения изображений, созданных для Postgres и Chrome Services, чтобы выполнить тесты. Вот как это выглядит:
Учитывая, что Docker-Compose создает все услуги вместе и автоматически создавать сеть для всех из них, нам не нужно беспокоиться о подключении к конкретной сети, чтобы делать работу, поскольку мы сделали в первом подходе.
Упаковка Как уже упоминалось ранее, я предпочитаю использовать первый подход (с использованием контейнеров обслуживания GHA), как это проще, а немного быстрее выполнить. Во всяком случае, я подумал, что стоит упомянуть второй подход (построить сервисные контейнеры с действием по созданию настроек), потому что он работает, и это был первый подход, который я мог бы реализовать.
Вы можете найти репозиторий с этими двумя рабочими процессами здесь Отказ Он имеет папку .devcontainer, чтобы вы могли использовать VSCode и Откройте код внутри контейнера Отказ
Я далеко не являюсь экспертом по ГГ, рельсам или доке, поэтому, пожалуйста, дайте мне знать, если вы думаете, что смогу улучшить этот рабочий процесс и/или, если я написал что-то не так. 😃
Я также хотел бы упомянуть Это отличная статья Это помогло мне настроить свой рабочий процесс и понять, как использовать кэширование докера на ГСУ.
Спасибо за чтение этого!
Оригинал: «https://dev.to/isabelatravaglia/using-github-actions-to-build-test-workflows-on-a-rails-on-docker-app-postgres-and-selenium-leveraging-docker-layer-caching-2hb8»