<!doctype html><html lang=en data-theme=tokyonight class=no-js><head><script>document.documentElement.className=document.documentElement.className.replace("no-js","js")</script><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Managing Your Travis CI Config Files with App::CISetup · Olaf Alders</title><meta name=description content="This post is brought to you by ServerCentral Turing Group in Chicago, a Platinum level sponsor of the meta::hack conference in 2018. For the past 3 years …"><meta name=theme-color content="#1a1b26"><link rel=canonical href=https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md><meta name=author content="Olaf Alders"><meta property="og:site_name" content="Olaf Alders"><meta property="og:title" content="Managing Your Travis CI Config Files with App::CISetup"><meta property="og:description" content="This post is brought to you by ServerCentral Turing Group in Chicago, a Platinum level sponsor of the meta::hack conference in 2018. For the past 3 years we&amp;rsquo;ve had the privilege of having meta::hack at the ServerCentral office space in Chicago."><meta property="og:type" content="article"><meta property="og:url" content="https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md"><meta property="og:image" content="https://www.olafalders.com/img/og-default_hu_1cfaf8cbe81e9d26.png"><meta property="og:image:width" content="1200"><meta property="og:image:height" content="630"><meta property="og:image:alt" content="Managing Your Travis CI Config Files with App::CISetup"><meta name=twitter:image content="https://www.olafalders.com/img/og-default_hu_1cfaf8cbe81e9d26.png"><meta name=twitter:image:alt content="Managing Your Travis CI Config Files with App::CISetup"><meta name=twitter:card content="summary_large_image"><meta property="article:published_time" content="2019-05-22T12:53:44Z"><meta property="article:author" content="Olaf Alders"><link rel=preload href=/fonts/ibm-plex-mono-latin-400-normal.woff2 as=font type=font/woff2 crossorigin><link rel=preload href=/fonts/ibm-plex-sans-latin-400-normal.woff2 as=font type=font/woff2 crossorigin><script type=application/ld+json>{"@context":"https://schema.org","@type":"BlogPosting","author":{"@id":"https://www.olafalders.com/about-me/#person","@type":"Person","name":"Olaf Alders","sameAs":["https://github.com/oalders","https://www.linkedin.com/in/olafalders/","https://fosstodon.org/@oalders"],"url":"https://www.olafalders.com/about-me/"},"dateModified":"2019-05-22T12:53:44Z","datePublished":"2019-05-22T12:53:44Z","description":"This post is brought to you by ServerCentral Turing Group in Chicago, a Platinum level sponsor of the meta::hack conference in 2018. For the past 3 years we\u0026rsquo;ve had the privilege of having meta::hack at the ServerCentral office space in Chicago.","headline":"Managing Your Travis CI Config Files with App::CISetup","image":"https://www.olafalders.com/img/og-default_hu_1cfaf8cbe81e9d26.png","mainEntityOfPage":"https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md","publisher":{"@id":"https://www.olafalders.com/about-me/#person"},"url":"https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md"}</script><script type=application/ld+json>{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","item":"https://www.olafalders.com/posts/","name":"~/posts","position":1},{"@type":"ListItem","item":"https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md","name":"managing-your-travis-ci-config-files-with-appcisetup","position":2}]}</script><link rel=stylesheet href=/css/main.min.c66ffdd5b20fcc995ec587cc18fa2e12ff00497b48fe08384a41e4bd9e77f5e6.css integrity="sha256-xm/91bIPzJlexYfMGPouEv8ASXtI/gg4SkHkvZ539eY="><link rel=icon href=/favicon.ico><link rel=stylesheet href=/css/llm-marker.min.5350c58803a0299e84a044538c099714341f83b05fc15a6cc75e7ae72ce449bf.css integrity="sha256-U1DFiAOgKZ6EoERTjAmXFDQfg7BfwVpsx1565yzkSb8="><script src=/js/llm-block.min.8f7577b60519b0adac95090fecaf580e1ee61932d10302e3f0a20be673291180.js integrity="sha256-j3V3tgUZsK2slQkP7K9YDh7mGTLRAwLj8KIL5nMpEYA=" defer></script><link rel=icon type=image/svg+xml href=/favicon.svg><link rel=icon type=image/png sizes=32x32 href=/favicon-32x32.png><link rel=icon type=image/png sizes=16x16 href=/favicon-16x16.png><link rel=apple-touch-icon href=/apple-touch-icon.png><link rel=me href=https://github.com/oalders><link rel=me href=https://fosstodon.org/@oalders><script>window.goatcounter={path:function(e){return location.host+e}}</script><script data-goatcounter=https://wunder.goatcounter.com/count async src=//gc.zgo.at/count.js></script></head><body><a class=skip-link href=#main>skip to content</a><header class=site-header><div class="wrap site-header__inner"><a class=brand href=/ aria-label="Olaf Alders — home"><span class=brand__tilde>~</span><span class=brand__slash>/</span><span class=brand__name>olafalders</span><span class=brand__cursor aria-hidden=true></span></a><nav class=nav aria-label=Primary><a class=promo-badge href=https://mymindisracing.com rel=noopener title="My Mind is Racing"><img class=promo-badge__logo src=/img/mmir-logo.svg alt width=18 height=18 decoding=async><span class=promo-badge__label>My Mind is <em>Racing</em></span>
</a><a class="nav__link is-active" href=/posts/ aria-current=page>posts</a><a class=nav__link href=/categories/>topics</a><a class=nav__link href=/about-me>about</a>
<span class=nav__utils><a class=nav__rss href=/index.xml aria-label="RSS feed" title="RSS feed"><svg width="15" height="15" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="3.2" cy="12.8" r="1.6"/><path d="M2 6.2A7.8 7.8.0 019.8 14H12A10 10 0 002 4v2.2z"/><path d="M2 1.6A12.4 12.4.0 0114.4 14h2.2A14.6 14.6.0 002-.6v2.2z"/></svg>
</a><button type=button class=search-btn data-search-open aria-label=Search>
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><circle cx="7" cy="7" r="4.5"/><path d="M11 11l3.5 3.5"/></svg>
<span>search</span>
<kbd>/</kbd></button></span></nav></div></header><main class=wrap id=main><article class=post data-pagefind-body><div class=post__head><nav class=breadcrumb aria-label=Breadcrumb><a href=/posts/>~/posts</a>
<span class=breadcrumb__sep>/</span>
<span>managing-your-travis-ci-config-files-with-appcisetup</span></nav><div class=tags><a class=tag href=/categories/perl/>#Perl</a><a class=tag href=/categories/programming/>#Programming</a></div><h1 class=post__title data-pagefind-meta=title>Managing Your Travis CI Config Files with App::CISetup</h1><div class=meta><span>by <a href=/about-me/ rel=author>Olaf Alders</a></span>
<span class=meta__dot>·</span>
<time datetime=2019-05-22>May 22, 2019</time>
<span class=meta__dot>·</span><span>6 min read</span>
<span class=meta__dot>·</span><span>1,185 words</span></div></div><details class=toc><summary class=toc__summary><span class=toc__label>Table of Contents</span>
<span class=toc__toggle aria-hidden=true></span></summary><nav id=TableOfContents><ul><li><a href=#setting-up-a-new-travis-ci-config>Setting Up a New Travis CI Config</a><ul><li><a href=#addons>addons</a></li><li><a href=#cache>cache</a></li><li><a href=#matrix>matrix</a></li><li><a href=#fast_finish>fast_finish</a></li><li><a href=#include>include</a></li><li><a href=#env>env</a></li><li><a href=#before_install>before_install</a></li><li><a href=#__app_cisetup__><code>__app_cisetup__</code></a></li></ul></li><li><a href=#sudo-false>sudo: false</a></li><li><a href=#updating-a-travisyml-file>Updating a .travis.yml file</a></li><li><a href=#doing-it-manually>Doing it Manually</a></li><li><a href=#caveats>Caveats</a></li></ul></nav></details><div class=prose><p>This post is brought to you by ServerCentral Turing Group in Chicago, a Platinum
level sponsor of the meta::hack conference in 2018. For the past 3 years we&rsquo;ve
had the privilege of having meta::hack at the ServerCentral office space in
Chicago.</p><p><img src=https://www.servercentral.com/wp-content/uploads/2018/12/SCTG-Logo.png alt loading=lazy decoding=async></p><p>ServerCentral Turing Group (SCTG) is a trusted provider of AWS consulting,
managed clouds, cloud-native software development, and global data center
services for startups, enterprises, and Fortune 500 companies.</p><h1 id=managing-your-travis-ci-config-files-with-appcisetup><a class=heading-anchor href=#managing-your-travis-ci-config-files-with-appcisetup aria-label="Permalink to this section">#</a>Managing Your Travis CI Config Files with App::CISetup</h1><p>If you write software, you (hopefully) write tests. If you write tests, it&rsquo;s
easy to forget to run them. Using Continuous Integration (CI) for your software
is one way around this. Many of us use <a href=https://travis-ci.org>Travis CI</a> for CI. In this post we&rsquo;ll
go over ways to make your Travis CI faster and hopefully better.</p><h2 id=setting-up-a-new-travis-ci-config><a class=heading-anchor href=#setting-up-a-new-travis-ci-config aria-label="Permalink to this section">#</a>Setting Up a New Travis CI Config</h2><p>Travis builds rely on a <code>.travis.yml</code> file which lives in the top level of your
repository. There are several ways to set up a new config.</p><ul><li>You can do it by hand</li><li>You can have <a href=https://metacpan.org/pod/Dist::Zilla>Dist::Zilla</a> create the file for you when you create a new
distribution</li><li>You can use <a href=https://metacpan.org/pod/App::CISetup>App::CISetup</a></li></ul><p>I&rsquo;m going to cover the last option here, since it&rsquo;s so easy and possibly the
least known of the options mentioned above.</p><p>First, install the module: <code>cpanm App::CISetup</code>.</p><p>Then create a new config file: <code>setup-travis-yml.pl --create --dir .</code></p><p>This will create a file which looks something like this:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-yaml data-lang=yaml><span class=line><span class=cl><span class=nt>addons</span><span class=p>:</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span><span class=nt>apt</span><span class=p>:</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>    </span><span class=nt>packages</span><span class=p>:</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>      </span>- <span class=l>aspell</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>      </span>- <span class=l>aspell-en</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=nt>language</span><span class=p>:</span><span class=w> </span><span class=l>perl</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=nt>perl</span><span class=p>:</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span>- <span class=l>blead</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span>- <span class=l>dev</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span>- <span class=m>5.28</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span>- <span class=m>5.26</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span>- <span class=m>5.24</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span>- <span class=m>5.22</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span>- <span class=m>5.20</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span>- <span class=m>5.18</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span>- <span class=m>5.16</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span>- <span class=m>5.14</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=nt>cache</span><span class=p>:</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span><span class=nt>directories</span><span class=p>:</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>    </span>- <span class=l>$HOME/perl5</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=nt>matrix</span><span class=p>:</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span><span class=nt>allow_failures</span><span class=p>:</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>    </span>- <span class=nt>perl</span><span class=p>:</span><span class=w> </span><span class=l>blead</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span><span class=nt>fast_finish</span><span class=p>:</span><span class=w> </span><span class=m>1</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span><span class=nt>include</span><span class=p>:</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>    </span>- <span class=nt>env</span><span class=p>:</span><span class=w> </span><span class=l>COVERAGE=1</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>      </span><span class=nt>perl</span><span class=p>:</span><span class=w> </span><span class=m>5.28</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=nt>env</span><span class=p>:</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span><span class=nt>global</span><span class=p>:</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>    </span>- <span class=l>AUTHOR_TESTING=1</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>    </span>- <span class=l>RELEASE_TESTING=1</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=nt>before_install</span><span class=p>:</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>  </span>- <span class=l>eval $(curl https://travis-perl.github.io/init) --auto</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>    </span>--<span class=l>always-upgrade-modules</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=c>### __app_cisetup__</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=c># ---</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=c># force_threaded_perls: 0</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=c># perl_caching: 1</span><span class=w>
</span></span></span><span class=line><span class=cl><span class=w>
</span></span></span><span class=line><span class=cl><span class=c>### __app_cisetup__</span><span class=w>
</span></span></span></code></pre></div><p>Let&rsquo;s break down some parts of this file to see what we can learn.</p><h3 id=addons><a class=heading-anchor href=#addons aria-label="Permalink to this section">#</a>addons</h3><pre><code>---
addons:
  apt:
    packages:
      - aspell
      - aspell-en
</code></pre><p>What&rsquo;s going on here? The issue is that some Pod spelling tests will skip
running tests if they don&rsquo;t find the proper dictionary files. If your tests are
not running in verbose mode, you may not even know that tests are being skipped.
So, this part of the setup ensures that there is an English dictionary available
for spell checking. Obviously you can add other languages if your Pod needs
this.</p><h3 id=cache><a class=heading-anchor href=#cache aria-label="Permalink to this section">#</a>cache</h3><pre><code>cache:
  directories:
    - $HOME/perl5
</code></pre><p>In many test builds, installing your CPAN dependencies can add a lot of extra
time to the total build time. This tells Travis to cache your module installs.
Note that each Perl version which you test as a part of your Travis build does
its own module install. So, if you&rsquo;re running 6 different jobs as part of a
Travis build, you&rsquo;ll actually have 6 different caches. You don&rsquo;t have to worry
about a cache from Perl 5.26 contaminating a cache for Perl 5.24.</p><h3 id=matrix><a class=heading-anchor href=#matrix aria-label="Permalink to this section">#</a>matrix</h3><p>Now we&rsquo;re at the build matrix:</p><pre><code>matrix:
  allow_failures:
    - perl: blead
  fast_finish: 1
  include:
    - env: COVERAGE=1
      perl: &amp;#039;5.28&amp;#039;
</code></pre><p>We are going to allow some failures:</p><pre><code>  allow_failures:
    - perl: blead
</code></pre><p>In the case of <code>blead</code> Perl we do care if something breaks, but we probably
don&rsquo;t want to prevent any code from being merged because of a test failure from
<code>blead</code>.</p><p>If you&rsquo;re wondering what <code>blead</code> is, it&rsquo;s explained at
<a href=https://dev.perl.org/perl5/source.html>dev.perl.org/perl5/source.html</a></p><blockquote><p>The master branch, where the development takes places, is named blead</p></blockquote><h3 id=fast_finish><a class=heading-anchor href=#fast_finish aria-label="Permalink to this section">#</a>fast_finish</h3><pre><code>fast_finish: 1
</code></pre><p>Enabling <code>fast_finish</code> allows us to fail faster. <a href=https://blog.travis-ci.com/2013-11-27-fast-finishing-builds>The Travis blog</a> explains
it nicely:</p><blockquote><p>With fast finishing enabled, Travis CI will mark your build as finished as
soon as one of two conditions are met: The only remaining jobs are allowed to
fail, or a job has already failed. In these cases, the status of the build can
already be determined, so there’s no need to wait around until the other jobs
finish.</p></blockquote><p>Basically, enabling <code>fast_finish</code> allows us to get faster notifications from
Travis, if we have builds in the <code>allow_failures</code> section.</p><h3 id=include><a class=heading-anchor href=#include aria-label="Permalink to this section">#</a>include</h3><p>This brings us to the build matrix includes:</p><pre><code>  include:
    - env: COVERAGE=1
      perl: &amp;#039;5.28&amp;#039;
</code></pre><p>In this case we&rsquo;re saying that we want to run an additional build. We want to
run an extra Perl 5.28 build that uses <a href=https://metacpan.org/pod/Devel::Cover>Devel::Cover</a>.</p><p>If we are going to run a coverage build, we&rsquo;ll likely also want to use
<a href=https://coveralls.io/>coveralls.io</a> to track changes to our coverage. Setting up Coveralls is
outside the scope of this post, but if you haven&rsquo;t started using it yet, I
highly recommend taking a few minutes to get set up with this service.</p><h3 id=env><a class=heading-anchor href=#env aria-label="Permalink to this section">#</a>env</h3><p>Moving along, we can see that some global environment variables are being set.</p><pre><code>env:
  global:
    - AUTHOR_TESTING=1
    - RELEASE_TESTING=1
</code></pre><p>The above configuration ensures that author and release tests are run on all
jobs in your build unless you override or unset these variables. Personally, I
prefer to run release tests on just one job per build, but that&rsquo;s just me. I may
eventually change my mind about that.</p><h3 id=before_install><a class=heading-anchor href=#before_install aria-label="Permalink to this section">#</a>before_install</h3><p>The last configuration looks simple, but it does a lot:</p><pre><code>before_install:
  - eval $(curl https://travis-perl.github.io/init) --auto --always-upgrade-modules
</code></pre><p>The above ensures that your build uses the <a href=https://travis-perl.github.io>Travis Perl Helpers</a>, which does
so much handy stuff I&rsquo;ll leave exploration of that as an exercise for the
reader. I should note, however, that <code>--always-upgrade-modules</code> is enabled here,
so even though we are caching our CPAN modules, Travis will automatically
refresh our Perl module cache if it has gotten stale.</p><h3 id=__app_cisetup__><a class=heading-anchor href=#__app_cisetup__ aria-label="Permalink to this section">#</a><code>__app_cisetup__</code></h3><p>After that <a href=https://metacpan.org/pod/APP::CISetup>APP::CISetup</a> tracks some of our choices as comments, so that
Travis does not know or care about them:</p><pre><code>### __app_cisetup__
# ---
# force_threaded_perls: 0
# perl_caching: 1

### __app_cisetup__
</code></pre><p>Now, what&rsquo;s missing from our Travis config?</p><h2 id=sudo-false><a class=heading-anchor href=#sudo-false aria-label="Permalink to this section">#</a>sudo: false</h2><p>Remember when you added <code>sudo: false</code> to all of your Travis builds so that they
would build faster? <a href=https://blog.travis-ci.com/2018-11-19-required-linux-infrastructure-migration>That&rsquo;s no longer a thing</a>, so <a href=https://metacpan.org/pod/App::CISetup>App::CISetup</a>
helpfully removes this for you.</p><h2 id=updating-a-travisyml-file><a class=heading-anchor href=#updating-a-travisyml-file aria-label="Permalink to this section">#</a>Updating a .travis.yml file</h2><p>In future you can run <code>setup-travis-yml.pl --dir .</code> as many times as you&rsquo;d like.
(Note that this is not exactly the same command that we used earlier, since we
have dropped the <code>--create</code>.) This will increment your Perl versions as new
versions become available. This will also remove <code>sudo: false</code> from any config
files which currently contain this option. Try running this on your existing
<code>.travis.yml</code> files to see what happens.</p><h2 id=doing-it-manually><a class=heading-anchor href=#doing-it-manually aria-label="Permalink to this section">#</a>Doing it Manually</h2><p>All of the above can also be achieved by making these configurations by hand.
Using <code>App::CISetup</code> is not for everyone. You may, for example, not want your
YAML to be rewritten by a script which is outside of your direct control. Maybe
you want things ordered in a certain way. Maybe you don&rsquo;t want to test on the
latest version(s) of Perl. However you decide to manage your config files, I
hope you&rsquo;ve found some useful information here.</p><h2 id=caveats><a class=heading-anchor href=#caveats aria-label="Permalink to this section">#</a>Caveats</h2><p>At some point after I began writing this post and before I finished <a href=https://blog.travis-ci.com/2019-01-23-travis-ci-joins-idera-inc>Travis CI
was acquired</a>. I won&rsquo;t get into the specifics as I&rsquo;m not close to the
situation but as with any change of ownership, but it&rsquo;s something to be aware
of.</p><p>Happy testing!</p></div><div class=share><span class=share__label>$ share</span><nav class=share__links aria-label="Share this post"><a class=share__link href="https://www.linkedin.com/sharing/share-offsite/?url=https%3a%2f%2fwww.olafalders.com%2f2019%2f05%2f22%2fmanaging-your-travis-ci-config-files-with-appcisetup.md" target=_blank rel="noopener noreferrer">linkedin</a>
<a class=share__link href="https://www.reddit.com/submit?url=https%3a%2f%2fwww.olafalders.com%2f2019%2f05%2f22%2fmanaging-your-travis-ci-config-files-with-appcisetup.md&title=Managing%20Your%20Travis%20CI%20Config%20Files%20with%20App%3a%3aCISetup" target=_blank rel="noopener noreferrer">reddit</a>
<a class=share__link href="https://www.facebook.com/sharer/sharer.php?u=https%3a%2f%2fwww.olafalders.com%2f2019%2f05%2f22%2fmanaging-your-travis-ci-config-files-with-appcisetup.md" target=_blank rel="noopener noreferrer">facebook</a>
<a class=share__link href="https://api.whatsapp.com/send?text=Managing%20Your%20Travis%20CI%20Config%20Files%20with%20App%3a%3aCISetup%20https%3a%2f%2fwww.olafalders.com%2f2019%2f05%2f22%2fmanaging-your-travis-ci-config-files-with-appcisetup.md" target=_blank rel="noopener noreferrer">whatsapp</a>
<a class=share__link href="https://t.me/share/url?url=https%3a%2f%2fwww.olafalders.com%2f2019%2f05%2f22%2fmanaging-your-travis-ci-config-files-with-appcisetup.md&text=Managing%20Your%20Travis%20CI%20Config%20Files%20with%20App%3a%3aCISetup" target=_blank rel="noopener noreferrer">telegram</a>
<a class=share__link href="mailto:?subject=Managing%20Your%20Travis%20CI%20Config%20Files%20with%20App%3a%3aCISetup&body=https%3a%2f%2fwww.olafalders.com%2f2019%2f05%2f22%2fmanaging-your-travis-ci-config-files-with-appcisetup.md">email</a></nav></div><nav class=post-nav aria-label="More posts"><a class="post-nav__link post-nav__link--prev" href=/2019/05/23/creating-a-twitter-list-of-cpan-authors/><span class=post-nav__text><span class=post-nav__dir>← newer</span>
<span class=post-nav__title>Creating a Twitter List of CPAN Authors</span></span><div class="cover cover--thumb cover--cyan"><span class=cover__glyph aria-hidden=true>&lt;/></span></div></a><a class="post-nav__link post-nav__link--next" href=/2019/05/14/how-i-spent-my-perl-toolchain-summit-v2019/><div class="cover cover--thumb"><img class=cover__img src=/2019/05/14/how-i-spent-my-perl-toolchain-summit-v2019/featured_hu_39cf4e53868a7021.jpeg width=320 height=180 alt="How I Spent My Perl Toolchain Summit v2019 (Marlow)" loading=lazy decoding=async></div><span class=post-nav__text><span class=post-nav__dir>older →</span>
<span class=post-nav__title>How I Spent My Perl Toolchain Summit v2019 (Marlow)</span></span></a></nav></article></main><footer class=site-footer><div class="wrap site-footer__wrap"><a class=promo href=https://mymindisracing.com rel=noopener><img class=promo__logo src=/img/mmir-logo.svg alt width=40 height=40 loading=lazy decoding=async>
<span class=promo__body><span class=promo__label>My Mind is <em>Racing</em></span>
<span class=promo__tag>Find every run, swim, ride and race</span>
</span><span class=promo__arrow aria-hidden=true>→</span></a><div class=site-footer__inner><div class=site-footer__copy>© 2026 Olaf Alders <span class=dot>·</span> built with Hugo <span class=dot>·</span> designed by Claude</div><div class=social><a class=social__link href=https://github.com/oalders rel="me noopener" aria-label=GitHub><svg width="15" height="15" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M8 0C3.58.0.0 3.58.0 8a8 8 0 005.47 7.59c.4.07.55-.17.55-.38.0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95.0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12.0.0.67-.21 2.2.82a7.6 7.6.0 012-.27c.68.0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15.0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48.0 1.07-.01 1.93-.01 2.2.0.21.15.46.55.38A8 8 0 0016 8c0-4.42-3.58-8-8-8z"/></svg>
<span>github</span>
</a><a class=social__link href=https://www.linkedin.com/in/olafalders/ rel="me noopener" aria-label=LinkedIn><svg width="15" height="15" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M0 1.146C0 .513.526.0 1.175.0h13.65C15.474.0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487.0 14.854zm4.943 12.248V6.169H2.542v7.225zm-1.2-8.212c.837.0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248S2.4 3.226 2.4 3.934c0 .694.521 1.248 1.327 1.248zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869.0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274.0-1.845.7-2.165 1.193v.025h-.016l.016-.025V6.169h-2.4c.03.678.0 7.225.0 7.225z"/></svg>
<span>linkedin</span>
</a><a class=social__link href=https://fosstodon.org/@oalders rel="me noopener" aria-label=Mastodon><svg width="15" height="15" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M11.19 12.195c2.016-.24 3.77-1.475 3.99-2.603.348-1.778.32-4.339.32-4.339.0-3.47-2.286-4.488-2.286-4.488C12.062.238 10.083.017 8.027.0h-.05C5.92.017 3.942.238 2.79.765c0 0-2.286 1.017-2.286 4.488l-.002.662c-.004.64-.007 1.35.011 2.091.083 3.394.626 6.74 3.78 7.57 1.454.383 2.703.463 3.709.408 1.823-.1 2.847-.647 2.847-.647l-.06-1.317s-1.303.41-2.767.36c-1.45-.05-2.98-.156-3.215-1.928a3.6 3.6.0 01-.033-.496s1.424.346 3.228.428c1.103.05 2.137-.064 3.188-.189zm1.613-2.47H11.13v-4.08c0-.859-.364-1.295-1.091-1.295-.804.0-1.207.517-1.207 1.541v2.233H7.168V5.89c0-1.024-.403-1.541-1.207-1.541-.727.0-1.091.436-1.091 1.296v4.079H3.197V5.522c0-.859.22-1.541.66-2.046.456-.505 1.052-.764 1.793-.764.856.0 1.504.328 1.933.983L8 4.39l.417-.695c.429-.655 1.077-.983 1.934-.983.74.0 1.336.259 1.791.764.442.505.661 1.187.661 2.046z"/></svg>
<span>mastodon</span>
</a><a class=social__link href=/index.xml aria-label="RSS feed"><svg width="15" height="15" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><circle cx="3.2" cy="12.8" r="1.6"/><path d="M2 6.2A7.8 7.8.0 019.8 14H12A10 10 0 002 4v2.2z"/><path d="M2 1.6A12.4 12.4.0 0114.4 14h2.2A14.6 14.6.0 002-.6v2.2z"/></svg>
<span>rss</span>
</a><a class=social__link href=mailto:olaf@wundersolutions.com aria-label=Email><svg width="15" height="15" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4" aria-hidden="true"><rect x="1.5" y="3" width="13" height="10" rx="1.5"/><path d="M2 4l6 4.2L14 4"/></svg>
<span>email</span></a></div></div></div></footer><script src=/js/search.min.d18a302872e7a0d7c518e9f402acb56a38b0a7ba46417a456a189f400dbb953a.js integrity="sha256-0YowKHLnoNfFGOn0Aqy1ajiwp7pGQXpFahifQA27lTo=" defer></script><div class=search id=search-modal hidden><div class=search__scrim data-search-close></div><div class=search__panel role=dialog aria-modal=true aria-label=Search><div class=search__input-row><svg width="17" height="17" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6" aria-hidden="true"><circle cx="7" cy="7" r="4.5"/><path d="M11 11l3.5 3.5"/></svg>
<input type=search class=search__input id=search-input placeholder="search posts…" autocomplete=off spellcheck=false aria-label="Search posts" role=combobox aria-expanded=false aria-controls=search-results aria-autocomplete=list>
<kbd class=search__esc>esc</kbd></div><div class=search__results id=search-results role=listbox aria-label=Results></div><div class=search__foot><span><kbd>↑↓</kbd> navigate</span>
<span><kbd>↵</kbd> open</span>
<span class=search__powered>pagefind</span></div></div></div><script src=/js/copy-code.min.b23f62b452fd41ab858217153628367627d3ba8c9ceac679550b7f2bc22796cc.js integrity="sha256-sj9itFL9QauFghcVNig2difTuoyc6sZ5VQt/K8Inlsw=" defer></script><script>(function(){var n=document.documentElement,e=!1;function t(){e=!1,n.classList.toggle("is-scrolled",window.scrollY>8)}addEventListener("scroll",function(){if(e)return;e=!0,requestAnimationFrame(t)},{passive:!0}),t()})()</script></body></html>