DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Why and How to Introduce DevSecOps Into CI/CD Pipelines
  • A Comprehensive DevSecOps Guide: Key Considerations to Effectively Secure Your CI/CD Pipeline
  • Streamlining AWS Lambda Deployments
  • Implementing CI/CD Pipelines With Jenkins and Docker

Trending

  • Enhancing Business Decision-Making Through Advanced Data Visualization Techniques
  • Can You Run a MariaDB Cluster on a $150 Kubernetes Lab? I Gave It a Shot
  • Distributed Consensus: Paxos vs. Raft and Modern Implementations
  • Simpler Data Transfer Objects With Java Records
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. DevOps and CI/CD
  4. Top 5 Tips for Integrating SwiftLint Into iOS CI/CD Pipelines

Top 5 Tips for Integrating SwiftLint Into iOS CI/CD Pipelines

This tips will help you in the integration with SwiftLint in iOS CI/CD pipelines, from installation to smart build phases and reporting.

By 
Shashikant Jagtap user avatar
Shashikant Jagtap
·
Oct. 06, 17 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
8.3K Views

Join the DZone community and get the full member experience.

Join For Free

swift is getting to be a popular programming language for developing ios apps these days. being a type-safe language, it's important to focus on code styling and conventions of swift code. swiftlint is an open source tool to enforce swift style and convention. swiftlint allows us to enforce code style rules and stick to it during the development of ios apps. there are various blog posts about integrating swiftlint into the development process, as well as swiftlint itself has good documentation about its usage, however, there are some tricks we can use while integrating swiftlint into continuous deployment pipelines. we will cover some of the tips for setting swiftlint on ci server and embedding it into build pipeline. note that, this post assumes that you have selected rules and configured.swiftlint.yml files. let's see how to integrate those rules on ci servers.

note: source code for this post is available on gith]hub swiftlint-ci repo, and travisci build is available here .

1] install swiftlint with cocoapods

there are four methods of installing swiftlint, as mentioned in the documentation. it's important to select the method of installation for a ci server as each of them has its own pros and cons.

homebrew

swiftlint can be easily installed using homebrew package manager.

$ brew install swiftlint

this seems to be the easiest method of installing swiftlint on any ci server. some of the cloud ci servers like travisci have swiftlint pre-installed in the macos images . there are some pros and cons of this method of installation

pros

  • easy to install with one command.
  • some cloud ci servers have a pre-installed version of swiftlint using homebrew.
  • no need to make any changes in the application code.
  • a script can run independently on a ci server without making any changes in the xcode project.

cons

  • homebrew installs the latest version of swiftlint every time we run the $ brew install swiftlint command. it's hard to go back to previous versions if needed.
  • there might be a different version of swiftlint running on the local machine and ci server. the team needs to stick to the version of swiftlint installed on the ci server. for example, travisci has swiftlint version 0.17.0 installed in an xcode 8.3 macos image. the latest version of swiftlint at the time writing this post is swiftlint 0.21.0; it's bit hard to go back to old version using homebrew

cocoapods

swiftlint can also be used with cocoapods ; there is detailed documentation on how to install swiftlint using cocoapods here, but in summary, we need to get the swiftlint pod by adding the pod 'swiftlint' into podfile and install swiftlint using the pod install command. this will create an executable binary inside ./pods/swiftlint/swiftlint, which can be added to build phases of the target. this is the recommended approach to installation in the swiftlint readme file, but it also has some pros and cons. still, cocoapods is the best way to install swiftlint on a ci server.

pros

  • we can install a specific version of swiftlint rather than simply the latest.
  • versions are locked inside the podfile.lock file so everyone in the team will be using the same version of swiftlint, including ci.
  • we can execute swiftlint using the binary located at./pods/swiftlint/swiftlint.

cons

  • we have to add another dependency in our application source code.
  • it will add dependencies and binaries inside pods/ directory, which needs to be checked into the scm.

there are other methods of swftlint installation like compiling from source and downloading a pre-built package are available there but compiling from source isn't a good idea at all. some users found the downloading pre-built package is faster on ci. we can download and install the package using the following command.

$ wget --output-document /tmp/swiftlint.pkg https://github.com/realm/swiftlint/releases/download/0.21.0/swiftlint.pkg
$ sudo installer -pkg /tmp/swiftlint.pkg -target /

the best idea is to pick the cocoapods way of installing swiftlint.

2] succinct podfile

swiftlint can be used to lint multiple targets of an ios app by using a simple ruby technique; we can apply swiftlint to multiple targets. we can write the podfile like this:

targets_to_lint = ["swiftlint-ci", "swiftlint-citests", "swiftlint-ciuitests"]

targets_to_lint.each do |target|
  target "#{target}" do
    use_frameworks!
    pod 'swiftlint'
  end
end

this will apply swiftlint for all the targets mentioned in the targets_to_lint array once we run the pod install command.

3] run early & independently on ci

swiftlint being a static analysis tool, we have to run linting before running any other development task like building, testing, or archiving. this will help us to fail early if there are some issues in the code quality. we can have a separate build phase in our ci pipeline to run the static analysis with swiftlint. the script we want to run is

$ ./pods/swiftlint/swiftlint

this makes sure that the correct swiftlint binary is getting executed as part of the build script rather than executing the pre-installed binary. in our example app, we have configured a separate phase for swiftlint. check out the .travis. yml.

4] balance local and ci linting

the ios developers mostly work with xcode , however, ci servers have to run some automated scripts on the server to run the development tasks. in order to make both developers and ci happy, we need to balance how to run swiftlint without making them upset. there are a couple of things, we can focus on while development and ci phase like xcode build phases and reporting of swiftlint results.

smart build phases

swiftlint works perfectly when run from command line however, ios developers would love to integrate it with xcode . in order to integrate it with xcode, we need to add run swiftlint as part of the build phase of the targets but we don't want to repeat the execution for each build on ci. we can add a run script in the build phase smartly so that we can still run the swiftlint from local xcode as well as on ci. we can achieve it by creating a ci environmental variable (most ci servers have this similar variable already set) and adding a conditional execution script in the build phases of the target.

if [ -z "$ci" ]; then
    ${pods_root}/swiftlint/swiftlint
fi

this will make sure that there won't be repeated execution of swiftlint scripts on the ci server, but developers can still run it from the local xcode.

smart reporting

swiftlint has different reporting types, including xcode, json, csv, checkstyle, junit, html, and emoji. the default reporter type is xcode. it's a good idea to keep the xcode reporting for the local execution and generate fancy reports using html or junit on the ci server. we can change the reporter style using

./pods/swiftlint/swiftlint --reporter junit

5] mind the fastlane

fastlane has become a very popular tool to automate ios development tasks for continuous deployment. fastlane comes with various tools and actions to perform specific tasks. fastlane has an action for swiftlint which looks great but it's not required to execute swiftlint as fastlane action. if we using swiftlint with cocoapods, then actions must set an executable parameter, pointing to the binary located at./pods/swiftlint/swiftlint path. otherwise, fastlane will pick a default binary, if there is any. the swiftlint fastlane config should look like this:

swiftlint(
  mode: :lint,      
  output_file: "swiftlint.result.json", 
  executable: "./pods/swiftlint/swiftlint"
)

this will make sure that we are executing the correct binary of swiftlint with fastlane.

hope you like these tips!

Continuous Integration/Deployment Pipeline (software) XCode

Published at DZone with permission of Shashikant Jagtap, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Why and How to Introduce DevSecOps Into CI/CD Pipelines
  • A Comprehensive DevSecOps Guide: Key Considerations to Effectively Secure Your CI/CD Pipeline
  • Streamlining AWS Lambda Deployments
  • Implementing CI/CD Pipelines With Jenkins and Docker

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!