The developers at Swift@IBM maintain a large number of Swift packages that are expected to run on two main platforms, macOS and Ubuntu 14.04. To ensure that our Swift libraries and sample programs go through an automated pipeline for continuous integration builds, execution of automated tests, and creation of artifacts/deliverables, we leverage Travis CI extensively. Travis CI makes macOS and Ubuntu 14.04 platforms available for our builds, which saves us time and let us focus on writing code. Hence, we don’t need to provision and maintain ourselves build systems that run these two platforms.
To leverage Travis CI and avoid duplication of code, we developed a set of utilities for building, testing, and performing quality checks against our Swift code. These common set of utilities are found in a GitHub repository that we have named Package-Builder. Our Swift packages leverage these capabilities by simply including a
.travis.yml file that references the Package-Builder repository. For example, the code snippet below from the
.travis.yml file in the Swift-cfenv library (a library that provides easy access to Cloud Foundry configuration data for Swift applications) shows the minimum required to use Package-Builder for continuous integration and execution of automated tests:
matrix: include: - os: linux dist: trusty sudo: required - os: osx osx_image: xcode8 sudo: required before_install: - git clone https://github.com/IBM-Swift/Package-Builder.git script: - ./Package-Builder/build-package.sh -projectDir $TRAVIS_BUILD_DIR
Instead of having the same continuous integration code repeated in every Swift package that we develop, with Package-Builder we have a common and reusable continuous integration repository that can be leveraged in all our Swift packages. New features and changes made to the Package-Builder repository are automatically available to all Swift packages that reference it.
Package-Builder drives the execution of our Swift project builds on Travis CI by first installing the corresponding version of the Swift binaries. The Swift version for building and running a Swift package is specified in the
.swift-version file that exists in each Swift project we create. Installing Swift is handled behind the scenes without the developers having to do anything other than providing a
.swift-version file in their repositories. Package-Builder then proceeds to compile and link the Swift package application and execute any test cases included in it. For those Swift projects that require a custom build command, an extension point for overriding the default build command (
swift build) is available in Package-Builder. For instance, depending on the nature of a Swift package, it may be needed to provide compilation flags to the build command. Extension points are also available for performing actions before and after the execution of test cases. For instance, say you need to install and configure Redis before your test cases can run, Package-Builder allows you to do just that.
Also, CodeCov is used in Package-Builder to determine how much test coverage we have in each of our Swift repositories. Codecov allows us determine which methods and statements in our code are not currently covered by the automated test cases included in the project. Using this information, our teams can decide which test cases should be implemented next to increase the coverage and quality of our code. For example, see the current test coverage for the Swift-cfenv package here.
We also added logic to Package-Builder to make use of SwiftLint in our continuous integration builds to enforce style and conventions our team has agreed upon. Rules can be defined to enforce the length of functions, length of lines in the code, location of colons and identifiers, and spaces around commas among many others. If violations are encountered, the build fails right away.
We welcome Swift developers to use Package-Builder in their own Swift projects. Feel free to explore our Package-Builder repository, and, if you see room for improvement, we’d like to hear from you!
For more information on server-side Swift, visit the Swift@IBM Developer Center.
Ricardo Olivieri, Senior Software Engineer, IBM Swift Engineering at IBM Cloud