<!doctype html><html lang=en dir=ltr class=scroll-smooth data-default-appearance=dark data-auto-appearance=true><head><meta charset=utf-8><meta http-equiv=content-language content="en"><meta name=viewport content="width=device-width,initial-scale=1"><meta http-equiv=X-UA-Compatible content="ie=edge"><meta name=theme-color><title>Managing Your Travis CI Config Files with App::CISetup &#183; olafalders.com</title><meta name=title content="Managing Your Travis CI Config Files with App::CISetup &#183; olafalders.com"><meta name=keywords content="Perl,Programming"><link rel=canonical href=https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md><meta property="og:url" content="https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md"><meta property="og:site_name" content="olafalders.com"><meta property="og:title" content="Managing Your Travis CI Config Files with App::CISetup"><meta property="og:locale" content="en"><meta property="og:type" content="article"><meta property="article:section" content="posts"><meta property="article:published_time" content="2019-05-22T12:53:44+00:00"><meta property="article:modified_time" content="2019-05-22T12:53:44+00:00"><meta name=twitter:card content="summary"><meta name=twitter:title content="Managing Your Travis CI Config Files with App::CISetup"><link type=text/css rel=stylesheet href=/css/main.bundle.min.dcfee641ddaf5ac9a5513f2132fd552f58c36e51fc13d0fd827614fa9c17781a8d193fe1843494540c7d48376133e1ad06aa8ffc87ae36dc6598cae29007d20f.css integrity="sha512-3P7mQd2vWsmlUT8hMv1VL1jDblH8E9D9gnYU+pwXeBqNGT/hhDSUVAx9SDdhM+GtBqqP/IeuNtxlmMrikAfSDw=="><script type=text/javascript src=/js/appearance.min.6f41174b3a05b680820fe08cadbfa5fb7a7ca347b76a0955cdc68b9d8aca1ce24f0547e138cea33bcc7904d551a90afcb1cc7f2d9fe8557075d501419046c08c.js integrity="sha512-b0EXSzoFtoCCD+CMrb+l+3p8o0e3aglVzcaLnYrKHOJPBUfhOM6jO8x5BNVRqQr8scx/LZ/oVXB11QFBkEbAjA=="></script><script type=text/javascript src=/js/zen-mode.min.9814dee9614d32aeb56239d118edfe20acd6231424f9b19c2dd48835038414130a5e946c0d1c9087d60e60e31840c9babfd217e3d4b95643dc8d651a71ccdf4a.js integrity="sha512-mBTe6WFNMq61YjnRGO3+IKzWIxQk+bGcLdSINQOEFBMKXpRsDRyQh9YOYOMYQMm6v9IX49S5VkPcjWUacczfSg=="></script><script src=/lib/zoom/zoom.min.umd.a527109b68c082a70f3697716dd72a9d5aa8b545cf800cecbbc7399f2ca6f6e0ce3e431f2062b48bbfa47c9ea42822714060bef309be073f49b9c0e30d318d7b.js integrity="sha512-pScQm2jAgqcPNpdxbdcqnVqotUXPgAzsu8c5nyym9uDOPkMfIGK0i7+kfJ6kKCJxQGC+8wm+Bz9JucDjDTGNew=="></script><script defer type=text/javascript id=script-bundle src=/js/main.bundle.min.f9fe268fcd89dff326e0b5bf1183a8dd1c1ec5059292635b1eed4e4ed7b35aa272234cecb245d91be3e1b7fd9403e6e5cfcdd7d5a4fcb2c8ba11deb4b81dadd2.js integrity="sha512-+f4mj82J3/Mm4LW/EYOo3RwexQWSkmNbHu1OTtezWqJyI0zsskXZG+Pht/2UA+blz83X1aT8ssi6Ed60uB2t0g==" data-copy=Copy data-copied=Copied></script><script src=/lib/jquery/jquery.slim.min.b0dca576e87d7eaa5850ae4e61759c065786cdb6489d68fcc82240539eebd5da522bdb4fda085ffd245808c8fe2acb2516408eb774ef26b5f6015fc6737c0ea8.js integrity="sha512-sNylduh9fqpYUK5OYXWcBleGzbZInWj8yCJAU57r1dpSK9tP2ghf/SRYCMj+KsslFkCOt3TvJrX2AV/Gc3wOqA=="></script><link rel=icon type=image/x-icon href=/favicon.ico><script type=application/ld+json>[{"@context":"https://schema.org","@type":"Article","articleSection":"posts","name":"Managing Your Travis CI Config Files with App::CISetup","headline":"Managing Your Travis CI Config Files with App::CISetup","inLanguage":"en","url":"https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md","author":{"@type":"Person","name":""},"copyrightYear":"2019","dateCreated":"2019-05-22T12:53:44\u002b00:00","datePublished":"2019-05-22T12:53:44\u002b00:00","dateModified":"2019-05-22T12:53:44\u002b00:00","mainEntityOfPage":"true","wordCount":"1199"}]</script><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 class="flex flex-col h-screen m-auto leading-7 max-w-7xl px-6 sm:px-14 md:px-24 lg:px-32 text-lg bg-neutral text-neutral-900 dark:bg-neutral-800 dark:text-neutral scrollbar-thin scrollbar-track-neutral-200 scrollbar-thumb-neutral-400 dark:scrollbar-track-neutral-800 dark:scrollbar-thumb-neutral-600"><div id=the-top class="absolute flex self-center"><a class="px-3 py-1 text-sm -translate-y-8 rounded-b-lg bg-primary-200 focus:translate-y-0 dark:bg-neutral-600" href=#main-content><span class="font-bold text-primary-600 pe-2 dark:text-primary-400">&darr;</span>
Skip to main content</a></div><div class=min-h-[148px]></div><div class="fixed inset-x-0 z-100"><div id=menu-blur class="absolute opacity-0 inset-x-0 top-0 h-full single_hero_background nozoom backdrop-blur-2xl shadow-2xl"></div><div class="relative m-auto leading-7 max-w-7xl px-6 sm:px-14 md:px-24 lg:px-32"><div class="main-menu flex items-center justify-between py-6 md:justify-start gap-x-3 pt-[2px] pr-2 md:pr-4 pb-[3px] pl-0"><div class="flex flex-1 items-center justify-between"><nav class="flex space-x-3"><a href=/ class="text-base font-medium">olafalders.com</a></nav><nav class="hidden md:flex items-center gap-x-5 md:ml-12 h-12"><a href=/posts/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label="Latest Articles" title=posts><p class="text-base font-medium">Latest Articles</p></a><a href=https://www.wundersolutions.com target=_blank class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label="Hire Me" title><p class="text-base font-medium">Hire Me</p></a><div><div class="cursor-pointer flex items-center nested-menu"><a aria-label=Projects class="text-base font-medium hover:text-primary-600 dark:hover:text-primary-400" title><p>Projects</p></a><span><span class="relative block icon"><svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M5.23 7.21a.75.75.0 011.06.02L10 11.168l3.71-3.938a.75.75.0 111.08 1.04l-4.25 4.5a.75.75.0 01-1.08.0l-4.25-4.5a.75.75.0 01.02-1.06z" clip-rule="evenodd"/></svg></span></span></div><div class="absolute menuhide"><div class="pt-2 p-5 mt-2 rounded-xl backdrop-blur shadow-2xl"><div class="flex flex-col space-y-3"><a href=https://www.prettygoodping.com target=_blank aria-label=PrettyGoodPing class="flex items-center hover:text-primary-600 dark:hover:text-primary-400"><p class="text-sm font-sm" title>PrettyGoodPing</p></a><a href=https://github.com/oalders/is target=_blank aria-label="is: an inspector for your environment" class="flex items-center hover:text-primary-600 dark:hover:text-primary-400"><p class="text-sm font-sm" title>is: an inspector for your environment</p></a><a href=https://metacpan.org target=_blank aria-label=MetaCPAN class="flex items-center hover:text-primary-600 dark:hover:text-primary-400"><p class="text-sm font-sm" title>MetaCPAN</p></a><a href=https://github.com/oalders/dot-files target=_blank aria-label="My dotfiles" class="flex items-center hover:text-primary-600 dark:hover:text-primary-400"><p class="text-sm font-sm" title>My dotfiles</p></a></div></div></div></div><a href=/categories/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Categories title=categories><p class="text-base font-medium">Categories</p></a><a href=/about-me class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=About title><p class="text-base font-medium">About</p></a><a href=/posts/index.xml class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Feed title><p class="text-base font-medium">Feed</p></a><button id=search-button aria-label=Search class="text-base hover:text-primary-600 dark:hover:text-primary-400" title="Search (/)">
<span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></button><div class="flex items-center"><button id=appearance-switcher aria-label="Dark mode switcher" type=button class="text-base hover:text-primary-600 dark:hover:text-primary-400"><div class="flex items-center justify-center dark:hidden"><span class="relative block icon"><svg viewBox="0 0 512 512"><path fill="currentColor" d="M32 256C32 132.2 132.3 32 255.8 32c11.36.0 29.7 1.668 40.9 3.746 9.616 1.777 11.75 14.63 3.279 19.44C245 86.5 211.2 144.6 211.2 207.8c0 109.7 99.71 193 208.3 172.3 9.561-1.805 16.28 9.324 10.11 16.95C387.9 448.6 324.8 480 255.8 480 132.1 480 32 379.6 32 256z"/></svg></span></div><div class="items-center justify-center hidden dark:flex"><span class="relative block icon"><svg viewBox="0 0 512 512"><path fill="currentColor" d="M256 159.1c-53.02.0-95.1 42.98-95.1 95.1s41.2 96.9 95.1 96.9 95.1-42.98 95.1-95.1S309 159.1 256 159.1zM509.3 347l-63.2-91.9 63.15-91.01c6.332-9.125 1.104-21.74-9.826-23.72l-109-19.7-19.7-109c-1.975-10.93-14.59-16.16-23.72-9.824L256 65.89 164.1 2.736c-9.125-6.332-21.74-1.107-23.72 9.824L121.6 121.6 12.56 141.3C1.633 143.2-3.596 155.9 2.736 164.1L65.89 256 2.74 347.01c-6.332 9.125-1.105 21.74 9.824 23.72l109 19.7 19.7 109c1.975 10.93 14.59 16.16 23.72 9.824L256 446.1l91.01 63.15c9.127 6.334 21.75 1.107 23.72-9.822l19.7-109 109-19.7C510.4 368.8 515.6 356.1 509.3 347zM256 383.1c-70.69.0-127.1-57.31-127.1-127.1.0-70.69 57.31-127.1 127.1-127.1S383.1 186.2 383.1 256c0 70.7-56.4 127.1-127.1 127.1z"/></svg></span></div></button></div></nav><div class="flex md:hidden items-center gap-x-5 md:ml-12 h-12"><span></span>
<button id=search-button-mobile aria-label=Search class="text-base hover:text-primary-600 dark:hover:text-primary-400" title="Search (/)">
<span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg>
</span></button>
<button id=appearance-switcher-mobile aria-label="Dark mode switcher" type=button class="text-base hover:text-primary-600 dark:hover:text-primary-400 me-1"><div class="flex items-center justify-center dark:hidden"><span class="relative block icon"><svg viewBox="0 0 512 512"><path fill="currentColor" d="M32 256C32 132.2 132.3 32 255.8 32c11.36.0 29.7 1.668 40.9 3.746 9.616 1.777 11.75 14.63 3.279 19.44C245 86.5 211.2 144.6 211.2 207.8c0 109.7 99.71 193 208.3 172.3 9.561-1.805 16.28 9.324 10.11 16.95C387.9 448.6 324.8 480 255.8 480 132.1 480 32 379.6 32 256z"/></svg></span></div><div class="items-center justify-center hidden dark:flex"><span class="relative block icon"><svg viewBox="0 0 512 512"><path fill="currentColor" d="M256 159.1c-53.02.0-95.1 42.98-95.1 95.1s41.2 96.9 95.1 96.9 95.1-42.98 95.1-95.1S309 159.1 256 159.1zM509.3 347l-63.2-91.9 63.15-91.01c6.332-9.125 1.104-21.74-9.826-23.72l-109-19.7-19.7-109c-1.975-10.93-14.59-16.16-23.72-9.824L256 65.89 164.1 2.736c-9.125-6.332-21.74-1.107-23.72 9.824L121.6 121.6 12.56 141.3C1.633 143.2-3.596 155.9 2.736 164.1L65.89 256 2.74 347.01c-6.332 9.125-1.105 21.74 9.824 23.72l109 19.7 19.7 109c1.975 10.93 14.59 16.16 23.72 9.824L256 446.1l91.01 63.15c9.127 6.334 21.75 1.107 23.72-9.822l19.7-109 109-19.7C510.4 368.8 515.6 356.1 509.3 347zM256 383.1c-70.69.0-127.1-57.31-127.1-127.1.0-70.69 57.31-127.1 127.1-127.1S383.1 186.2 383.1 256c0 70.7-56.4 127.1-127.1 127.1z"/></svg></span></div></button></div></div><div class="-my-2 md:hidden"><div id=menu-button class=block><div class="cursor-pointer hover:text-primary-600 dark:hover:text-primary-400"><span class="relative block icon"><svg viewBox="0 0 448 512"><path fill="currentColor" d="M0 96C0 78.33 14.33 64 32 64H416c17.7.0 32 14.33 32 32 0 17.7-14.3 32-32 32H32C14.33 128 0 113.7.0 96zM0 256c0-17.7 14.33-32 32-32H416c17.7.0 32 14.3 32 32s-14.3 32-32 32H32c-17.67.0-32-14.3-32-32zM416 448H32c-17.67.0-32-14.3-32-32s14.33-32 32-32H416c17.7.0 32 14.3 32 32s-14.3 32-32 32z"/></svg></span></div><div id=menu-wrapper class="fixed inset-0 z-30 invisible w-screen h-screen m-0 overflow-auto transition-opacity opacity-0 cursor-default bg-neutral-100/50 backdrop-blur-sm dark:bg-neutral-900/50 pt-[5px]"><ul class="flex space-y-2 mt-3 flex-col items-end w-full px-6 py-6 mx-auto overflow-visible list-none text-end max-w-7xl"><li id=menu-close-button><span class="cursor-pointer inline-block align-text-bottom hover:text-primary-600 dark:hover:text-primary-400"><span class="relative block icon"><svg viewBox="0 0 320 512"><path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75.0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3 54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75.0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75.0-45.25s32.75-12.5 45.25.0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25.0s12.5 32.75.0 45.25l-105.4 105.4L310.6 361.4z"/></svg></span></span></li><li class=mt-1><a href=/posts/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label="Latest Articles" title=posts><p class="text-bg font-bg">Latest Articles</p></a></li><li class=mt-1><a href=https://www.wundersolutions.com target=_blank class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label="Hire Me" title><p class="text-bg font-bg">Hire Me</p></a></li><li class=mt-1><a href aria-label=Projects class="flex items-center hover:text-primary-600 dark:hover:text-primary-400"><p class="text-bg font-bg" title>Projects</p><span><span class="relative block icon"><svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M5.23 7.21a.75.75.0 011.06.02L10 11.168l3.71-3.938a.75.75.0 111.08 1.04l-4.25 4.5a.75.75.0 01-1.08.0l-4.25-4.5a.75.75.0 01.02-1.06z" clip-rule="evenodd"/></svg></span></span></a></li><li class=mt-1><a href=https://www.prettygoodping.com target=_blank aria-label=PrettyGoodPing class="flex items-center hover:text-primary-600 dark:hover:text-primary-400"><p class="text-sm font-small" title>PrettyGoodPing</p></a></li><li class=mt-1><a href=https://github.com/oalders/is target=_blank aria-label="is: an inspector for your environment" class="flex items-center hover:text-primary-600 dark:hover:text-primary-400"><p class="text-sm font-small" title>is: an inspector for your environment</p></a></li><li class=mt-1><a href=https://metacpan.org target=_blank aria-label=MetaCPAN class="flex items-center hover:text-primary-600 dark:hover:text-primary-400"><p class="text-sm font-small" title>MetaCPAN</p></a></li><li class=mt-1><a href=https://github.com/oalders/dot-files target=_blank aria-label="My dotfiles" class="flex items-center hover:text-primary-600 dark:hover:text-primary-400"><p class="text-sm font-small" title>My dotfiles</p></a></li><li class=mb-2></li><li class=mt-1><a href=/categories/ class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Categories title=categories><p class="text-bg font-bg">Categories</p></a></li><li class=mt-1><a href=/about-me class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=About title><p class="text-bg font-bg">About</p></a></li><li class=mt-1><a href=/posts/index.xml class="flex items-center hover:text-primary-600 dark:hover:text-primary-400" aria-label=Feed title><p class="text-bg font-bg">Feed</p></a></li></ul></div></div></div></div></div></div><script type=text/javascript src=/js/background-blur.min.605b3b942818f0ab5a717ae446135ec46b8ee5a2ad12ae56fb90dc2a76ce30c388f9fec8bcc18db15bd47e3fa8a09d779fa12aa9c184cf614a315bc72c6c163d.js integrity="sha512-YFs7lCgY8KtacXrkRhNexGuO5aKtEq5W+5DcKnbOMMOI+f7IvMGNsVvUfj+ooJ13n6EqqcGEz2FKMVvHLGwWPQ==" data-blur-id=menu-blur></script><div class="relative flex flex-col grow"><main id=main-content class=grow><article><header id=single_header class="mt-5 max-w-prose"><h1 class="mt-0 text-4xl font-extrabold text-neutral-900 dark:text-neutral">Managing Your Travis CI Config Files with App::CISetup</h1><div class="mt-1 mb-6 text-base text-neutral-500 dark:text-neutral-400 print:hidden"><div class="flex flex-row flex-wrap items-center"><time datetime=2019-05-22T12:53:44+00:00>May 22, 2019</time><span class="px-2 text-primary-500">&#183;</span><span>1199 words</span><span class="px-2 text-primary-500">&#183;</span><span title="Reading time">6 mins</span><span class="px-2 text-primary-500">&#183;</span><span class=mb-[2px]>
<span id=zen-mode-button class="text-lg hover:text-primary-500" title="Enable zen mode" data-title-i18n-disable="Enable zen mode" data-title-i18n-enable="Disable zen mode"><span class="inline-block align-text-bottom"><span class="relative block icon"><svg viewBox="0 0 50 50" width="50" height="50"><path fill="currentColor" d="M12.980469 4C9.1204688 4 5.9804688 7.14 5.9804688 11L6 26H9.9804688V11c0-1.65 1.3400002-3 3.0000002-3H40.019531c1.66.0 3 1.35 3 3V39c0 1.65-1.34 3-3 3H29c0 1.54-.579062 2.94-1.539062 4H40.019531c3.86.0 7-3.14 7-7V11c0-3.86-3.14-7-7-7H12.980469zM7 28c-2.206.0-4 1.794-4 4V42c0 2.206 1.794 4 4 4H23c2.206.0 4-1.794 4-4V32c0-2.206-1.794-4-4-4H7zm0 4H23L23.001953 42H7V32z"/></svg></span></span></span></span></div><div class="flex flex-row flex-wrap items-center"><span style=margin-top:.5rem class=mr-2 onclick='window.open("/categories/perl/","_self")'><span class="flex cursor-pointer"><span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">Perl
</span></span></span><span style=margin-top:.5rem class=mr-2 onclick='window.open("/categories/programming/","_self")'><span class="flex cursor-pointer"><span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">programming</span></span></span></div><script>window.onload=function(){var e=document.getElementById("zen-mode-button");e.click()}</script></div></header><section class="flex flex-col max-w-full mt-0 prose dark:prose-invert lg:flex-row"><div class="order-first lg:ml-auto px-0 lg:order-last lg:ps-8 lg:max-w-2xs"><div class="toc ps-5 print:hidden lg:sticky lg:top-[140px]"><details open id=TOCView class="toc-right mt-0 overflow-y-auto overscroll-contain scrollbar-thin scrollbar-track-neutral-200 scrollbar-thumb-neutral-400 dark:scrollbar-track-neutral-800 dark:scrollbar-thumb-neutral-600 rounded-lg -ms-5 ps-5 pe-2 hidden lg:block"><summary class="block py-1 text-lg font-semibold cursor-pointer bg-neutral-100 text-neutral-800 -ms-5 ps-5 dark:bg-neutral-700 dark:text-neutral-100 lg:hidden">Table of Contents</summary><div class="min-w-[220px] py-2 border-dotted border-s-1 -ms-5 ps-5 dark:border-neutral-600"><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></div></details><details class="toc-inside mt-0 overflow-hidden rounded-lg -ms-5 ps-5 lg:hidden"><summary class="py-1 text-lg font-semibold cursor-pointer bg-neutral-100 text-neutral-800 -ms-5 ps-5 dark:bg-neutral-700 dark:text-neutral-100 lg:hidden">Table of Contents</summary><div class="py-2 border-dotted border-neutral-300 border-s-1 -ms-5 ps-5 dark:border-neutral-600"><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></div></details><script>(function(){"use strict";const s=.33,o="#TableOfContents",i=".anchor",a='a[href^="#"]',r="li ul",c="active";let t=!1;function l(e,n){const o=window.scrollY+window.innerHeight*n,i=[...document.querySelectorAll('#TableOfContents a[href^="#"]')],s=new Set(i.map(e=>e.getAttribute("href").substring(1)));if(t)for(let t=0;t<e.length;t++){const n=e[t];if(!s.has(n.id))continue;const o=n.getBoundingClientRect().top+window.scrollY;if(Math.abs(window.scrollY-o)<100)return n.id}for(let t=e.length-1;t>=0;t--){const n=e[t].getBoundingClientRect().top+window.scrollY;if(n<=o&&s.has(e[t].id))return e[t].id}return e.find(e=>s.has(e.id))?.id||""}function e({toc:e,anchors:t,links:n,scrollOffset:s,collapseInactive:o}){const i=l(t,s);if(!i)return;if(n.forEach(e=>{const t=e.getAttribute("href")===`#${i}`;if(e.classList.toggle(c,t),o){const n=e.closest("li")?.querySelector("ul");n&&(n.style.display=t?"":"none")}}),o){const n=e.querySelector(`a[href="#${CSS.escape(i)}"]`);let t=n;for(;t&&t!==e;)t.tagName==="UL"&&(t.style.display=""),t.tagName==="LI"&&t.querySelector("ul")?.style.setProperty("display",""),t=t.parentElement}}function n(){const n=document.querySelector(o);if(!n)return;const l=!1,u=[...document.querySelectorAll(i)],d=[...n.querySelectorAll(a)];l&&n.querySelectorAll(r).forEach(e=>e.style.display="none"),d.forEach(e=>{e.addEventListener("click",()=>{t=!0})});const c={toc:n,anchors:u,links:d,scrollOffset:s,collapseInactive:l};window.addEventListener("scroll",()=>e(c),{passive:!0}),window.addEventListener("hashchange",()=>e(c),{passive:!0}),e(c)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",n):n()})()</script></div></div><div class="min-w-0 min-h-0 max-w-fit"><div class="article-content max-w-prose mb-20"><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><figure><img class="my-0 rounded-md" loading=lazy decoding=async fetchpriority=low alt src=https://www.servercentral.com/wp-content/uploads/2018/12/SCTG-Logo.png></figure></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 class="relative group">Managing Your Travis CI Config Files with App::CISetup<div id=managing-your-travis-ci-config-files-with-appcisetup class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#managing-your-travis-ci-config-files-with-appcisetup aria-label=Anchor>#</a></span></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 target=_blank>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 class="relative group">Setting Up a New Travis CI Config<div id=setting-up-a-new-travis-ci-config class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#setting-up-a-new-travis-ci-config aria-label=Anchor>#</a></span></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 target=_blank>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 target=_blank>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-wrapper><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></span></code></pre></div></div><p>Let&rsquo;s break down some parts of this file to see what we can learn.</p><h3 class="relative group">addons<div id=addons class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#addons aria-label=Anchor>#</a></span></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 class="relative group">cache<div id=cache class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#cache aria-label=Anchor>#</a></span></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 class="relative group">matrix<div id=matrix class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#matrix aria-label=Anchor>#</a></span></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 target=_blank>dev.perl.org/perl5/source.html</a></p><blockquote><p>The master branch, where the development takes places, is named blead</p></blockquote><h3 class="relative group">fast_finish<div id=fast_finish class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#fast_finish aria-label=Anchor>#</a></span></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 target=_blank>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 class="relative group">include<div id=include class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#include aria-label=Anchor>#</a></span></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 target=_blank>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/ target=_blank>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 class="relative group">env<div id=env class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#env aria-label=Anchor>#</a></span></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 class="relative group">before_install<div id=before_install class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#before_install aria-label=Anchor>#</a></span></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 target=_blank>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 class="relative group"><code>__app_cisetup__</code><div id=__app_cisetup__ class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#__app_cisetup__ aria-label=Anchor>#</a></span></h3><p>After that <a href=https://metacpan.org/pod/APP::CISetup target=_blank>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 class="relative group">sudo: false<div id=sudo-false class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#sudo-false aria-label=Anchor>#</a></span></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 target=_blank>That&rsquo;s no longer a thing</a>, so <a href=https://metacpan.org/pod/App::CISetup target=_blank>App::CISetup</a>
helpfully removes this for you.</p><h2 class="relative group">Updating a .travis.yml file<div id=updating-a-travisyml-file class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#updating-a-travisyml-file aria-label=Anchor>#</a></span></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 class="relative group">Doing it Manually<div id=doing-it-manually class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#doing-it-manually aria-label=Anchor>#</a></span></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 class="relative group">Caveats<div id=caveats class=anchor></div><span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"><a class="text-primary-300 dark:text-neutral-700 !no-underline" href=#caveats aria-label=Anchor>#</a></span></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 target=_blank>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><hr><div class="flex justify-center"><script async src=https://eocampaign1.com/form/c69c5b94-ab1b-11ee-9c33-172c25a39049.js data-form=c69c5b94-ab1b-11ee-9c33-172c25a39049></script></div></div><section class="flex flex-row flex-wrap justify-center pt-4 text-xl"><a target=_blank class="m-1 rounded bg-neutral-300 p-1.5 text-neutral-700 hover:bg-primary-500 hover:text-neutral dark:bg-neutral-700 dark:text-neutral-300 dark:hover:bg-primary-400 dark:hover:text-neutral-800" href="https://www.linkedin.com/shareArticle?mini=true&amp;url=https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md&amp;title=Managing%20Your%20Travis%20CI%20Config%20Files%20with%20App::CISetup" title="Share on LinkedIn" aria-label="Share on LinkedIn"><span class="relative block icon"><svg viewBox="0 0 448 512"><path fill="currentColor" d="M416 32H31.9C14.3 32 0 46.5.0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6.0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3.0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2.0 38.5 17.3 38.5 38.5.0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6.0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2.0 79.7 44.3 79.7 101.9V416z"/></svg>
</span></a><a target=_blank class="m-1 rounded bg-neutral-300 p-1.5 text-neutral-700 hover:bg-primary-500 hover:text-neutral dark:bg-neutral-700 dark:text-neutral-300 dark:hover:bg-primary-400 dark:hover:text-neutral-800" href="https://reddit.com/submit/?url=https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md&amp;resubmit=true&amp;title=Managing%20Your%20Travis%20CI%20Config%20Files%20with%20App::CISetup" title="Submit to Reddit" aria-label="Submit to Reddit"><span class="relative block icon"><svg viewBox="0 0 512 512"><path fill="currentColor" d="M201.5 305.5c-13.8.0-24.9-11.1-24.9-24.6.0-13.8 11.1-24.9 24.9-24.9 13.6.0 24.6 11.1 24.6 24.9.0 13.6-11.1 24.6-24.6 24.6zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-132.3-41.2c-9.4.0-17.7 3.9-23.8 10-22.4-15.5-52.6-25.5-86.1-26.6l17.4-78.3 55.4 12.5c0 13.6 11.1 24.6 24.6 24.6 13.8.0 24.9-11.3 24.9-24.9s-11.1-24.9-24.9-24.9c-9.7.0-18 5.8-22.1 13.8l-61.2-13.6c-3-.8-6.1 1.4-6.9 4.4l-19.1 86.4c-33.2 1.4-63.1 11.3-85.5 26.8-6.1-6.4-14.7-10.2-24.1-10.2-34.9.0-46.3 46.9-14.4 62.8-1.1 5-1.7 10.2-1.7 15.5.0 52.6 59.2 95.2 132 95.2 73.1.0 132.3-42.6 132.3-95.2.0-5.3-.6-10.8-1.9-15.8 31.3-16 19.8-62.5-14.9-62.5zM302.8 331c-18.2 18.2-76.1 17.9-93.6.0-2.2-2.2-6.1-2.2-8.3.0-2.5 2.5-2.5 6.4.0 8.6 22.8 22.8 87.3 22.8 110.2.0 2.5-2.2 2.5-6.1.0-8.6-2.2-2.2-6.1-2.2-8.3.0zm7.7-75c-13.6.0-24.6 11.1-24.6 24.9.0 13.6 11.1 24.6 24.6 24.6 13.8.0 24.9-11.1 24.9-24.6.0-13.8-11-24.9-24.9-24.9z"/></svg>
</span></a><a target=_blank class="m-1 rounded bg-neutral-300 p-1.5 text-neutral-700 hover:bg-primary-500 hover:text-neutral dark:bg-neutral-700 dark:text-neutral-300 dark:hover:bg-primary-400 dark:hover:text-neutral-800" href="https://www.facebook.com/sharer/sharer.php?u=https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md&amp;quote=Managing%20Your%20Travis%20CI%20Config%20Files%20with%20App::CISetup" title="Share on Facebook" aria-label="Share on Facebook"><span class="relative block icon"><svg viewBox="0 0 512 512"><path fill="currentColor" d="M504 256C504 119 393 8 256 8S8 119 8 256c0 123.78 90.69 226.38 209.25 245V327.69h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48 27.14.0 55.52 4.84 55.52 4.84v61h-31.28c-30.8.0-40.41 19.12-40.41 38.73V256h68.78l-11 71.69h-57.78V501C413.31 482.38 504 379.78 504 256z"/></svg>
</span></a><a target=_blank class="m-1 rounded bg-neutral-300 p-1.5 text-neutral-700 hover:bg-primary-500 hover:text-neutral dark:bg-neutral-700 dark:text-neutral-300 dark:hover:bg-primary-400 dark:hover:text-neutral-800" href="mailto:?body=https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md&amp;subject=Managing%20Your%20Travis%20CI%20Config%20Files%20with%20App::CISetup" title="Send via email" aria-label="Send via email"><span class="relative block icon"><svg viewBox="0 0 512 512"><path fill="currentColor" d="M207.8 20.73c-93.45 18.32-168.7 93.66-187 187.1-27.64 140.9 68.65 266.2 199.1 285.1 19.01 2.888 36.17-12.26 36.17-31.49l1e-4-.6631c0-15.74-11.44-28.88-26.84-31.24-84.35-12.98-149.2-86.13-149.2-174.2.0-102.9 88.61-185.5 193.4-175.4 91.54 8.869 158.6 91.25 158.6 183.2v16.16c0 22.09-17.94 40.05-40 40.05s-40.01-17.96-40.01-40.05v-120.1c0-8.847-7.161-16.02-16.01-16.02l-31.98.0036c-7.299.0-13.2 4.992-15.12 11.68-24.85-12.15-54.24-16.38-86.06-5.106-38.75 13.73-68.12 48.91-73.72 89.64-9.483 69.01 43.81 128 110.9 128 26.44.0 50.43-9.544 69.59-24.88 24 31.3 65.23 48.69 109.4 37.49C465.2 369.3 496 324.1 495.1 277.2V256.3c0-149.2-133.9-265.632-287.3-235.57zM239.1 304.3c-26.47.0-48-21.56-48-48.05s21.53-48.05 48-48.05 48 21.56 48 48.05-20.6 48.05-48 48.05z"/></svg>
</span></a><a target=_blank class="m-1 rounded bg-neutral-300 p-1.5 text-neutral-700 hover:bg-primary-500 hover:text-neutral dark:bg-neutral-700 dark:text-neutral-300 dark:hover:bg-primary-400 dark:hover:text-neutral-800" href="https://api.whatsapp.com/send?text=https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md&amp;resubmit=true&amp;title=Managing%20Your%20Travis%20CI%20Config%20Files%20with%20App::CISetup" title="Share via WhatsApp" aria-label="Share via WhatsApp"><span class="relative block icon"><svg viewBox="0 0 448 512"><path fill="currentColor" d="M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4.0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3.0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2.0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2.0-101.7 82.8-184.5 184.6-184.5 49.3.0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5.0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8s-14.3 18-17.6 21.8c-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2s-9.7 1.4-14.8 6.9c-5.1 5.6-19.4 19-19.4 46.3.0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z"/></svg>
</span></a><a target=_blank class="m-1 rounded bg-neutral-300 p-1.5 text-neutral-700 hover:bg-primary-500 hover:text-neutral dark:bg-neutral-700 dark:text-neutral-300 dark:hover:bg-primary-400 dark:hover:text-neutral-800" href="https://t.me/share/url?url=https://www.olafalders.com/2019/05/22/managing-your-travis-ci-config-files-with-appcisetup.md&amp;resubmit=true&amp;title=Managing%20Your%20Travis%20CI%20Config%20Files%20with%20App::CISetup" title="Share via Telegram" aria-label="Share via Telegram"><span class="relative block icon"><svg viewBox="0 0 496 512"><path fill="currentColor" d="M248 8C111.033 8 0 119.033.0 256S111.033 504 248 504 496 392.967 496 256 384.967 8 248 8zM362.952 176.66c-3.732 39.215-19.881 134.378-28.1 178.3-3.476 18.584-10.322 24.816-16.948 25.425-14.4 1.326-25.338-9.517-39.287-18.661-21.827-14.308-34.158-23.215-55.346-37.177-24.485-16.135-8.612-25 5.342-39.5 3.652-3.793 67.107-61.51 68.335-66.746.153-.655.3-3.1-1.154-4.384s-3.59-.849-5.135-.5q-3.283.746-104.608 69.142-14.845 10.194-26.894 9.934c-8.855-.191-25.888-5.006-38.551-9.123-15.531-5.048-27.875-7.717-26.8-16.291q.84-6.7 18.45-13.7 108.446-47.248 144.628-62.3c68.872-28.647 83.183-33.623 92.511-33.789 2.052-.034 6.639.474 9.61 2.885a10.452 10.452.0 013.53 6.716A43.765 43.765.0 01362.952 176.66z"/></svg></span></a></section><h2 class="mt-8 text-2xl font-extrabold mb-10">Related</h2><section class="w-full grid gap-4 sm:grid-cols-2 md:grid-cols-3"><a href=/2019/05/14/how-i-spent-my-perl-toolchain-summit-v2019/ class=min-w-full><div class="min-h-full border border-neutral-200 dark:border-neutral-700 border-2 rounded overflow-hidden shadow-2xl relative"><div class="w-full thumbnail_card_related nozoom" style=background-image:url(/2019/05/14/how-i-spent-my-perl-toolchain-summit-v2019/featured_hu_167ce7ff382cc59f.jpeg)></div><div class="px-6 py-4"><div class="font-bold text-xl text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral" href=/2019/05/14/how-i-spent-my-perl-toolchain-summit-v2019/>How I Spent My Perl Toolchain Summit v2019 (Marlow)</div><div class="text-sm text-neutral-500 dark:text-neutral-400"><div class="flex flex-row flex-wrap items-center"><time datetime=2019-05-14T13:04:07+00:00>May 14, 2019</time><span class="px-2 text-primary-500">&#183;</span><span>3040 words</span><span class="px-2 text-primary-500">&#183;</span><span title="Reading time">15 mins</span></div><div class="flex flex-row flex-wrap items-center"><span style=margin-top:.5rem class=mr-2 onclick='window.open("/categories/metacpan/","_self")'><span class="flex cursor-pointer"><span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">metacpan
</span></span></span><span style=margin-top:.5rem class=mr-2 onclick='window.open("/categories/perl/","_self")'><span class="flex cursor-pointer"><span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">Perl
</span></span></span><span style=margin-top:.5rem class=mr-2 onclick='window.open("/categories/programming/","_self")'><span class="flex cursor-pointer"><span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">programming
</span></span></span><span style=margin-top:.5rem class=mr-2 onclick='window.open("/categories/perl-toolchain-summit/","_self")'><span class="flex cursor-pointer"><span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">Perl Toolchain Summit</span></span></span></div><script>window.onload=function(){var e=document.getElementById("zen-mode-button");e.click()}</script></div></div><div class="px-6 pt-4 pb-2"></div></div></a><a href=/2019/02/19/about-the-various-pans/ class=min-w-full><div class="min-h-full border border-neutral-200 dark:border-neutral-700 border-2 rounded overflow-hidden shadow-2xl relative"><div class="w-full thumbnail_card_related nozoom" style=background-image:url(/tower_hu_6e9da4ced1d36a1f.jpeg)></div><div class="px-6 py-4"><div class="font-bold text-xl text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral" href=/2019/02/19/about-the-various-pans/>About the Various PANs</div><div class="text-sm text-neutral-500 dark:text-neutral-400"><div class="flex flex-row flex-wrap items-center"><time datetime=2019-02-19T17:34:22+00:00>February 19, 2019</time><span class="px-2 text-primary-500">&#183;</span><span>1494 words</span><span class="px-2 text-primary-500">&#183;</span><span title="Reading time">8 mins</span></div><div class="flex flex-row flex-wrap items-center"><span style=margin-top:.5rem class=mr-2 onclick='window.open("/categories/perl/","_self")'><span class="flex cursor-pointer"><span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">Perl
</span></span></span><span style=margin-top:.5rem class=mr-2 onclick='window.open("/categories/programming/","_self")'><span class="flex cursor-pointer"><span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">programming</span></span></span></div><script>window.onload=function(){var e=document.getElementById("zen-mode-button");e.click()}</script></div></div><div class="px-6 pt-4 pb-2"></div></div></a><a href=/2016/07/12/dont-forget-about-uriheuristic/ class=min-w-full><div class="min-h-full border border-neutral-200 dark:border-neutral-700 border-2 rounded overflow-hidden shadow-2xl relative"><div class="w-full thumbnail_card_related nozoom" style=background-image:url(/tower_hu_6e9da4ced1d36a1f.jpeg)></div><div class="px-6 py-4"><div class="font-bold text-xl text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral" href=/2016/07/12/dont-forget-about-uriheuristic/>Don’t Forget about URI::Heuristic</div><div class="text-sm text-neutral-500 dark:text-neutral-400"><div class="flex flex-row flex-wrap items-center"><time datetime=2016-07-12T20:51:27+00:00>July 12, 2016</time><span class="px-2 text-primary-500">&#183;</span><span>276 words</span><span class="px-2 text-primary-500">&#183;</span><span title="Reading time">2 mins</span></div><div class="flex flex-row flex-wrap items-center"><span style=margin-top:.5rem class=mr-2 onclick='window.open("/categories/perl/","_self")'><span class="flex cursor-pointer"><span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">Perl
</span></span></span><span style=margin-top:.5rem class=mr-2 onclick='window.open("/categories/programming/","_self")'><span class="flex cursor-pointer"><span class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">programming</span></span></span></div><script>window.onload=function(){var e=document.getElementById("zen-mode-button");e.click()}</script></div></div><div class="px-6 pt-4 pb-2"></div></div></a></section></div><script type=text/javascript src=/js/page.min.54b6f4371722649edbe871e431d8670d670878c22be8f36e229fe53cc9b786fe25a834def5e6de621f7a3e37b72bc8cd73839aa5ed907ed6cbd45cd3e1b0fa20.js integrity="sha512-VLb0NxciZJ7b6HHkMdhnDWcIeMIr6PNuIp/lPMm3hv4lqDTe9ebeYh96Pje3K8jNc4Oape2QftbL1FzT4bD6IA==" data-oid=views_posts/2019-05-22-managing-your-travis-ci-config-files-with-appcisetup.md data-oid-likes=likes_posts/2019-05-22-managing-your-travis-ci-config-files-with-appcisetup.md></script></section><footer class="pt-8 max-w-prose print:hidden"><div class=pt-8><hr class="border-dotted border-neutral-300 dark:border-neutral-600"><div class="flex justify-between pt-3"><span class="flex flex-col"><a class="flex text-neutral-700 hover:text-primary-600 dark:text-neutral dark:hover:text-primary-400" href=/2019/05/14/how-i-spent-my-perl-toolchain-summit-v2019/><span class=leading-6><span class="inline-block rtl:rotate-180">&larr;</span>&ensp;How I Spent My Perl Toolchain Summit v2019 (Marlow)
</span></a><span class="ms-6 mt-1 text-xs text-neutral-500 dark:text-neutral-400"><time datetime=2019-05-14T13:04:07+00:00>May 14, 2019</time>
</span></span><span class="flex flex-col items-end"><a class="flex text-right text-neutral-700 hover:text-primary-600 dark:text-neutral dark:hover:text-primary-400" href=/2019/05/23/creating-a-twitter-list-of-cpan-authors/><span class=leading-6>Creating a Twitter List of CPAN Authors&ensp;<span class="inline-block rtl:rotate-180">&rarr;</span>
</span></a><span class="me-6 mt-1 text-xs text-neutral-500 dark:text-neutral-400"><time datetime=2019-05-23T17:40:30+00:00>May 23, 2019</time></span></span></div></div></footer></article><div id=scroll-to-top class="fixed bottom-6 end-6 z-50 transform translate-y-4 opacity-0 duration-200"><a href=#the-top class="pointer-events-auto flex h-12 w-12 items-center justify-center rounded-full bg-neutral/50 text-xl text-neutral-700 hover:text-primary-600 dark:bg-neutral-800/50 dark:text-neutral dark:hover:text-primary-400" aria-label="Scroll to top" title="Scroll to top">&uarr;</a></div></main><footer id=site-footer class="py-10 print:hidden"><div class="flex items-center justify-between"><p class="text-sm text-neutral-500 dark:text-neutral-400">© 2026 Olaf Alders</p><p class="text-xs text-neutral-500 dark:text-neutral-400">Powered by <a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" href=https://gohugo.io/ target=_blank rel="noopener noreferrer">Hugo</a> & <a class="hover:underline hover:decoration-primary-400 hover:text-primary-500" href=https://blowfish.page/ target=_blank rel="noopener noreferrer">Blowfish</a></p></div><script>mediumZoom(document.querySelectorAll("img:not(.nozoom)"),{margin:24,background:"rgba(0,0,0,0.5)",scrollOffset:0})</script><script type=text/javascript src=/js/process.min.ee03488f19c93c2efb199e2e3014ea5f3cb2ce7d45154adb3399a158cac27ca52831db249ede5bb602700ef87eb02434139de0858af1818ab0fb4182472204a4.js integrity="sha512-7gNIjxnJPC77GZ4uMBTqXzyyzn1FFUrbM5mhWMrCfKUoMdsknt5btgJwDvh+sCQ0E53ghYrxgYqw+0GCRyIEpA=="></script></footer><div id=search-wrapper class="invisible fixed inset-0 flex h-screen w-screen cursor-default flex-col bg-neutral-500/50 p-4 backdrop-blur-sm dark:bg-neutral-900/50 sm:p-6 md:p-[10vh] lg:p-[12vh] z-500" data-url=https://www.olafalders.com/><div id=search-modal class="flex flex-col w-full max-w-3xl min-h-0 mx-auto border rounded-md shadow-lg top-20 border-neutral-200 bg-neutral dark:border-neutral-700 dark:bg-neutral-800"><header class="relative z-10 flex items-center justify-between flex-none px-2"><form class="flex items-center flex-auto min-w-0"><div class="flex items-center justify-center w-8 h-8 text-neutral-400"><span class="relative block icon"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></div><input type=search id=search-query class="flex flex-auto h-12 mx-1 bg-transparent appearance-none focus:outline-dotted focus:outline-2 focus:outline-transparent" placeholder=Search tabindex=0></form><button id=close-search-button class="flex items-center justify-center w-8 h-8 text-neutral-700 hover:text-primary-600 dark:text-neutral dark:hover:text-primary-400" title="Close (Esc)">
<span class="relative block icon"><svg viewBox="0 0 320 512"><path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75.0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3 54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75.0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75.0-45.25s32.75-12.5 45.25.0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25.0s12.5 32.75.0 45.25l-105.4 105.4L310.6 361.4z"/></svg></span></button></header><section class="flex-auto px-2 overflow-auto"><ul id=search-results></ul></section></div></div></div></body></html>