Customizing the build

Travis CI’s documentation of the .travis.yml file sprawls quite a bit as there are so many features available, so I’ll start with an example .travis.yml config file that should work for testing most of your open-source PowerShell projects on the Travis CI platform.  In my next post, I will provide a high-level overview of all of the available options that I found in the documentation for reference, as well as my design decisions for the ArmorPowerShell project.

Example .travis.yml config file

To start testing your open-source PowerShell project on macOS & Ubuntu, copy the contents below to a file named .travis.yml in the base directory of your project.


language: generic

    - os: linux
      dist: trusty
      sudo: false
            - sourceline: "deb [arch=amd64] trusty main"
              key_url: ""
            - powershell
    - os: osx
      osx_image: xcode9.1
        - brew tap caskroom/cask
        - brew cask install powershell
  fast_finish: true

  - pwsh -f "${env:TRAVIS_BUILD_DIR}/install-dependencies.ps1"

  - pwsh -f "${env:TRAVIS_BUILD_DIR}/build.ps1"

  - pwsh -f "${env:TRAVIS_BUILD_DIR}/test.ps1"

  - pwsh -f "${env:TRAVIS_BUILD_DIR}/deploy.ps1"
  • The powershell executable name has been shortened to pwsh as of v6.0.0-beta.9.
  • There are a few lines that call PowerShell to execute a file, such as pwsh -f "${env:TRAVIS_BUILD_DIR}/install-dependencies.ps1" in the base directory of the project, fully-pathed through the TRAVIS_BUILD_DIR environment variable, but these are by no means necessary.  You could store these files in sub-directories, give the files different names, call commands instead of files, or do something else entirely- these are all just ideas to stimulate your imagination; however, whatever logic you define needs to be valid or your build will fail.

What does this .travis.yml config file do?

  • language: This defines the programming language that the build system should use.
    • I set this to generic, because I am building a scripting language project.
    • The generic setting is not documented in the Travis CI Languages documentation, but is listed in a few examples, such as this one.
  • matrix: The Matrix section allows you to customize each image that will build your code.
    • include: Include the specified image configurations.  All configurations defined for an image in the matrix will override the corresponding global configuration.  For example, I configured a before_install section in the osx image above, so if I had a global before_install section defined in the .travis.yml config file, the macOS image would skip it.  Excludes can also be defined for here more complex build topologies.
      • os: The operating system of the image.  As of 20171125, the two choices are osx (macOS) and linux (Ubuntu).
      • dist: The Ubuntu Linux distro image.  As of 20171125, the two choices are trusty (Ubuntu 14.04 LTS Trusty Tahr) and precise (Ubuntu 12.04 LTS Precise Pangolin, which is end of life).
      • sudo: This purpose of this setting is almost certainly not what you think.  Setting sudo to false in your Trusty images causes your build to be deployed to a container instead of a VM, which will start up and complete much faster than the VM image.  Unfortunately, as of 20171125, there is not a containerized option for macOS yet.  If you want or need to use an Linux VM image, set sudo to required.  I have had no issues with building or testing my code inside a container so far.  I will update the article if I discover a blocking issue, but I don’t expect to at this point since the PowerShell Core team publishes nightly builds on Docker Hub and of note, they also build on Travis CI.
      • addons: There is a lot that can be configured in the addons section, but for now, we’re only going to use this for the Trusty image to add the appropriate Microsoft software repository where the official PowerShell Core binaries are hosted, the software repository key, and to install PowerShell Core per the recommended methodology as defined in the PowerShell Core Install Guide.
        • apt: The default package management tool for Ubuntu.
          • sources: Software repositories to add.
            • sourceline: The software repository configuration.
            • key_url: The public key for encrypting the traffic.
          • packages: Software packages to install
            • powershell: Install PowerShell Core on Linux, please and thank you.
      • osx_image: The macOS image that you want to use.
        • As of 20171125, the Travis CI default is 7.3, which is an older macOS 10.11 image.
        • The official PowerShell install guide only lists support for macOS 10.12; however, I have performed a few basic functional tests on osx images: 7.3 (10.11) & 6.4 (10.10). PowerShell Core installed, and completed the build and test runs successfully without any additional configuration on macOS 10.11, but failed on macOS 10.10.
          • PowerShell Core may work on macOS 10.10 with additional configuration, but I am not interested in researching this any further at this time.
        • If you are concerned about breaking changes between macOS versions, you can duplicate the osx matrix image section and replace the value of osx_image with a different version.
          • Available image versions can be found here.
      • before_install: This matrix image section overrides the global before_install configuration for our osx image, and is used for installing PowerShell Core as defined in the installation guide.
        • brew tap caskroom/cask: reference

          Homebrew-Cask extends Homebrew and brings its elegance, simplicity, and speed to macOS applications and large binaries alike.

        • brew cask install powershell: Install PowerShell Core on macOS, please and thank you.
    • fast_finish: Job failures halt the build.  If you would rather have the build attempt to continue on error, change the value to false.
  • install: This section can be used for calling the PowerShell script to install dependencies, such as any modules needed to build and/or test the script.
    • I highly recommend storing the logic for each section in a separate file so that:
      1. It is easier for you to reuse & maintain code if you choose to also integrate with AppVeyor for testing your open-source project for free on Windows PowerShell as well, and also…
      2. …because of the inherent challenges with embedding code in code.
    • The build lifecycle order of operations has the install section follow the before_install section and precedes the before_script section.
    • Here is my install-dependencies.ps1 script for the ArmorPowerShell project.
  • before_script: This section can be used for calling your PowerShell build script to do things such as update the module manifest, update the documentation, et cetera.
    • Here is my build.ps1 script for the ArmorPowerShell project.
  • script: This section can be used for calling your PowerShell unit, integration, and/or functional test scripts.
    • If you are new to these concepts, I recommend reading up on those topics, as well as Pester.
    • Here is my start-tests.ps1 script for the ArmorPowerShell project.
  • after_success: This section can be used for calling a deployment script if that makes sense for your project, such as publishing your module, script, et cetera to the PowerShell Gallery, NuGet, Chocolatey, GitHub Releases, et cetera.

Travis CI is an extremely powerful platform with tons of other features that you can take advantage of, but that is all that I am going to cover in this post as to the possibilities available in the .travis.yml config file.

Continued in Part 3.

Improve this page