<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Maximilien Pressensé</title>
    <description>The latest articles on DEV Community by Maximilien Pressensé (@mpressen).</description>
    <link>https://dev.to/mpressen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F286879%2F09199c2e-ac07-44e5-b22c-b5cac0aa0895.jpeg</url>
      <title>DEV Community: Maximilien Pressensé</title>
      <link>https://dev.to/mpressen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mpressen"/>
    <language>en</language>
    <item>
      <title>Heroku Review Apps: setup &amp; configuration</title>
      <dc:creator>Maximilien Pressensé</dc:creator>
      <pubDate>Fri, 23 Oct 2020 11:20:42 +0000</pubDate>
      <link>https://dev.to/mpressen/heroku-review-apps-setup-configuration-a4a</link>
      <guid>https://dev.to/mpressen/heroku-review-apps-setup-configuration-a4a</guid>
      <description>&lt;p&gt;At my job at &lt;a href="https://www.videorunrun.com/" rel="noopener noreferrer"&gt;VideoRunRun&lt;/a&gt;, we use Github and Heroku.&lt;/p&gt;

&lt;p&gt;We have a pipeline with a staging and a prod app, and when I joined the team few months ago, I suggested to enable Review Apps as well.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are Review Apps ?
&lt;/h1&gt;

&lt;p&gt;I'll quote the &lt;a href="https://devcenter.heroku.com/articles/github-integration-review-apps" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Review apps run the code in any GitHub pull request in a&lt;br&gt;
complete, disposable Heroku app. Review apps each have a&lt;br&gt;
unique URL you can share, making them a great way to&lt;br&gt;
propose, test, and merge changes to your code base.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mainly, it allows us to shorten feedback loops, especially with our Product Owner, for UI/UX considerations, for testing purposes in a production environment, for PR reviews, etc.&lt;/p&gt;

&lt;p&gt;Overall it's very convenient for many different use cases and we just love it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's a killer feature&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting it up
&lt;/h1&gt;

&lt;p&gt;In order to use Review Apps up to their potential, they must be ready-to-use as soon as they are deployed.&lt;/p&gt;

&lt;p&gt;If you need to manually set up heroku dependencies, define some env vars, or run a script every time you need to use a review, poor child you're lost.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcon29yt5c0quyaomoyqu.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcon29yt5c0quyaomoyqu.jpeg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As always, automation is key. &lt;/p&gt;

&lt;p&gt;Luckily, &lt;strong&gt;Review Apps are very easy to set up&lt;/strong&gt; and documentation is pretty straight-forward.&lt;/p&gt;



&lt;p&gt;General config happens on Heroku UI:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhumn8lio0qlq1k69prkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhumn8lio0qlq1k69prkz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There you can enable Review Apps, define env vars, choose a URL pattern, etc.&lt;/p&gt;



&lt;p&gt;For advanced config, you'll need to add an &lt;code&gt;app.json&lt;/code&gt; file to your app's root folder.&lt;/p&gt;

&lt;p&gt;Here's a working example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# app.json
{
  "environments": {
    "review": {
      "formation": {
        "worker": {
          "quantity": 1,
          "size": "free"
        }
      },
      "addons": [
        "heroku-postgresql:hobby-dev",
        "heroku-redis:hobby-dev"
      ],
      "scripts": {
        "postdeploy": "rails db:schema:load db:seed"
      }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Populate your database
&lt;/h1&gt;

&lt;p&gt;If your seeding scripts aren't giving you all the data you need, you might lurk at your sexy staging database.&lt;/p&gt;

&lt;p&gt;Here's what Heroku's team has to say about it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu7pua9gc7hde84psgn5x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu7pua9gc7hde84psgn5x.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks like you'll have to work on that seeding then.&lt;/p&gt;

&lt;p&gt;You don't want to ? Tell me your reasons in comments please.&lt;/p&gt;

&lt;p&gt;Anyway I've got you covered.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;One could simply use his staging database both for reviews and staging environment. (bad solution imho)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One could hack his way around :&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# app.json
{
  "environments": {
    "review": {
      "buildpacks": [
        {
          "url": "https://github.com/heroku/heroku-buildpack-cli"
        },
        ...
      ],
      "scripts": {
        "postdeploy": "heroku pg:copy {STAGING_APP_NAME}::DATABASE DATABASE --app $HEROKU_APP_NAME --confirm $HEROKU_APP_NAME  &amp;amp;&amp;amp; sleep 1s &amp;amp;&amp;amp; rails db:migrate"
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It consists on installing &lt;a href="https://devcenter.heroku.com/articles/heroku-cli" rel="noopener noreferrer"&gt;Heroku CLI&lt;/a&gt; directly on every app reviews. Then the &lt;code&gt;postdeploy&lt;/code&gt; script launchs the appropriate heroku command and runs migrations. Beware you'll need to set HEROKU_API_KEY first. RTFM !&lt;/p&gt;

&lt;h1&gt;
  
  
  References:
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;official documentation for heroku reviews (&lt;a href="https://devcenter.heroku.com/articles/github-integration-review-apps" rel="noopener noreferrer"&gt;https://devcenter.heroku.com/articles/github-integration-review-apps&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;official documentation on &lt;code&gt;app.json&lt;/code&gt; (&lt;a href="https://devcenter.heroku.com/articles/app-json-schema" rel="noopener noreferrer"&gt;https://devcenter.heroku.com/articles/app-json-schema&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;official documentation about buildpacks (&lt;a href="https://devcenter.heroku.com/articles/app-json-schema#buildpacks" rel="noopener noreferrer"&gt;https://devcenter.heroku.com/articles/app-json-schema#buildpacks&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;heroku buildpack-cli (&lt;a href="https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-cli" rel="noopener noreferrer"&gt;https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-cli&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;official documentation about heroku database handling (&lt;a href="https://devcenter.heroku.com/articles/heroku-postgres-backups#direct-database-to-database-copies" rel="noopener noreferrer"&gt;https://devcenter.heroku.com/articles/heroku-postgres-backups#direct-database-to-database-copies&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>ci</category>
      <category>heroku</category>
      <category>rails</category>
    </item>
    <item>
      <title>Rails: minitest &amp; GitLab CI</title>
      <dc:creator>Maximilien Pressensé</dc:creator>
      <pubDate>Fri, 09 Oct 2020 15:44:13 +0000</pubDate>
      <link>https://dev.to/mpressen/rails-minitest-gitlab-ci-31ap</link>
      <guid>https://dev.to/mpressen/rails-minitest-gitlab-ci-31ap</guid>
      <description>&lt;p&gt;Hi everybody, this post is the first of a serie I'd like to write, revolving around rails and CI/CD.&lt;/p&gt;

&lt;p&gt;In this one I'll show you how to setup a proper CI for your new rails project.&lt;/p&gt;

&lt;p&gt;I tried to give you the simplest example in order to focus on what's interesting, the configuration, I hope you'll find it useful.&lt;/p&gt;

&lt;p&gt;Here is the repo alongside this article: &lt;a href="https://gitlab.com/mpressen/rails_with_gitlab_ci" rel="noopener noreferrer"&gt;https://gitlab.com/mpressen/rails_with_gitlab_ci&lt;/a&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  &lt;em&gt;Init project&lt;/em&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rails new rails_with_gitlab_ci --database=postgresql
$ cd rail_with_gitlab_ci
$ rails db:create db:migrate
$ rails server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp990pzrizto9kfxr8xt7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp990pzrizto9kfxr8xt7.png" alt="Yay! You're on Rails"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perfect time to commit and push our code :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git add -A
$ git commit -m 'init rails project with postgresql'
$ git remote add origin git@gitlab.com:$(username)/rails_with_gitlab_ci.git
$ git push --set-upstream origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  &lt;em&gt;Add failing tests&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;Let's create a failing controller test :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# test/controllers/dummy_controller_test.rb&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'test_helper'&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DummyControllerTest&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;IntegrationTest&lt;/span&gt;
  &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"the truth"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And a failing system test :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# test/system/dummy_system_test.rb&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'application_system_test_case'&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DummySystemTest&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationSystemTestCase&lt;/span&gt;
  &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="s1"&gt;'the truth'&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  &lt;em&gt;Setup gitlab CI&lt;/em&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .gitlab-ci.yml&lt;/span&gt;

&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ruby&lt;/span&gt;

&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;

&lt;span class="na"&gt;tests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;selenium/standalone-chrome&lt;/span&gt;
    &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;chrome&lt;/span&gt;
  &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apt-cache&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node_modules&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;vendor/bundle&lt;/span&gt;
  &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;DB_HOST&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
      &lt;span class="na"&gt;SELENIUM_REMOTE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://chrome:4444/wd/hub&lt;/span&gt;
      &lt;span class="na"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
      &lt;span class="na"&gt;BUNDLE_PATH&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vendor/bundle&lt;/span&gt;
  &lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export APT_CACHE_DIR=`pwd`/apt-cache &amp;amp;&amp;amp; mkdir -pv $APT_CACHE_DIR&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;apt-get update -qq &amp;amp;&amp;amp; apt-get -o dir::cache::archives="$APT_CACHE_DIR" install -yqq yarn&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;yarn install&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bundle install&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bundle exec rails db:setup&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bundle exec rails test  test/*&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# config/database.yml&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="ss"&gt;default: &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="ss"&gt;host: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= ENV["DB_HOST"] %&amp;gt;
  username: &amp;lt;%=&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"POSTGRES_USER"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;%&amp;gt;&lt;/span&gt;
  &lt;span class="ss"&gt;password: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= ENV["POSTGRES_PASSWORD"] %&amp;gt;
...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This config caches back and front dependencies for speed and computation cost (a must).&lt;/p&gt;

&lt;p&gt;My favorite part is the use of a third docker image, &lt;code&gt;selenium/standalone-chrome&lt;/code&gt; that avoids a pain point (chrome versions ...) some might have encountered before. With this config, it's another container that runs an headless chrome navigator on system tests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# test/application_system_test_case.rb&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"test_helper"&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationSystemTestCase&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SystemTestCase&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'SELENIUM_REMOTE_URL'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="no"&gt;Capybara&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;server_host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'0.0.0.0'&lt;/span&gt;
    &lt;span class="n"&gt;driven_by&lt;/span&gt; &lt;span class="ss"&gt;:selenium&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;using: :headless_chrome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;screen_size: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;options: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;url: &lt;/span&gt;&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'SELENIUM_REMOTE_URL'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;driven_by&lt;/span&gt; &lt;span class="ss"&gt;:selenium&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;using: :chrome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;screen_size: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1400&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'SELENIUM_REMOTE_URL'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;net&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ip_address_list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:ipv4_private?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;'localhost'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ip_address&lt;/span&gt;
      &lt;span class="no"&gt;Capybara&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;app_host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"http://&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="ss"&gt;:test&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'webdrivers'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;require: &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'SELENIUM_REMOTE_URL'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's try it !&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git add -A
$ git commit -m 'setup gitlab CI'
$ git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4mbpvmog9thui9ehmbfu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4mbpvmog9thui9ehmbfu.png" alt="CI failure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's replace &lt;code&gt;assert false&lt;/code&gt; by &lt;code&gt;assert true&lt;/code&gt; in our dummy tests, commit and push.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftbi30prrt2dezqtgqf4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftbi30prrt2dezqtgqf4o.png" alt="CI success"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yeah !&lt;/p&gt;

</description>
      <category>rails</category>
      <category>devops</category>
      <category>ruby</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
