Prelude
Fastlane is widely used by iOS teams all around the world. It became the standard de facto to automate common tasks such as building apps, running tests, and uploading builds to App Store Connect. Fastlane has been recently moved under the Mobile Native Foundation which is amazing as Google wasn’t actively maintaining the project.
At Just Eat Takeaway, we have implemented an extensive number of custom lanes to perform domain-specific tasks and used them from our CI.
The major problem with Fastlane is that it’s written in Ruby. When it was born, using Ruby was a sound choice but iOS developers are not necessarily familiar with such language which represents a barrier to contributing and writing lanes.
While Fastlane.swift, a version of Fastlane in Swift, has been in beta for years, it’s not a rewrite in Swift but rather a “solution on top” meaning that developers and CI systems still have to rely on Ruby, install related software (rbenv or rvm) and most likely maintain a Gemfile. The average iOS dev knows well that Ruby environments are a pain to deal with and have caused an infinite number of headaches.
In recent years, Apple has introduced technologies that would enable a replacement of Fastlane using Swift:
Being myself a big fan of CLI tools written in Swift, I soon started maturing the idea of a Fastlane rewrite in Swift in early 2022. I circulated the idea with friends and colleagues for months and the sentiment was clear: it’s time for a fresh simil-Fastlane tool written in Swift.
Journey
Towards the end of 2022, I was determined to start this project. I teamed up with 2 iOS devs (not working at Just Eat Takeaway) and we started working on a design. I was keen on calling this project “Swiftlane” but the preference seemed to be for the name “Interstellar” which was eventually shortened into “Stellar”.
Fastlane has the concept of Actions and I instinctively thought that in Swift-land, they could take the form of SPM packages. This would make Stellar a modular system with pluggable components.
For example, consider the Scan action in Fastlane. It could be a package that solely solves the same problem around testing. My goal was not to implement the plethora of existing Fastlane actions but rather to create a system that allows plugging in any package building on macOS. A sound design of such system was crucial.
The Stellar ecosystem I had in mind was composed of 4 parts:
Actions
Actions are the basic building blocks of the ecosystem. They are packages that define a library product. An action can do anything, from taking care of build tasks to integrating with GitHub.
Actions are independent packages that have no knowledge of the Stellar system, which treats them as pluggable components to create higher abstractions.
Ideally, actions should expose an executable product (the CLI tool) using SAP calling into the action code. This is not required by Stellar but it’s advisable as a best practice.
Official Actions would be hosted in the Stellar organisation on GitHub. Custom Actions could be created using Stellar.
Tasks
Tasks are specific to a project and implemented by the project developers. They are SAP ParsableCommand
or AsyncParsableCommand
which use actions to construct complex logic specific to the needs of the project.
Executor
Executor is a command line tool in the form of a package generated by Stellar. It’s the entry point to the user-defined tasks. Invoking tasks on the Executor is like invoking lanes in Fastlane.
Both developers and CI would interface with the Executor (masked as Stellar) to perform all operations. E.g.
stellar setup_environment --developer-mode
stellar run_unit_tests module=OrderHistory
stellar setup_demo_app module=OrderHistory
stellar run_ui_tests module=OrderHistory device="iPhone 15 Pro"
Stellar CLI
Stellar CLI is a command line tool that takes care of the heavy lifting of dealing with the Executor and the Tasks. It allows the integration of Stellar in a project and it should expose the following main commands:
init
: initialise the project by creating an Exectutor package in the.stellar
folderbuild
: builds the Executor generating a binary that is shared with the team members and used by CIcreate-action
: scaffolding to create a new action in the form of a packagecreate-task
: scaffolding to create a new task in the form of a packageedit
: opens the Executor package for editing, similar totuist edit
This design was presented to a restricted group of devs at Just Eat Takeaway and it didn’t take long to get an agreement on it. It was clear that once Stellar was completed, we would have integrated it in the codebase.
Wider design
I believe that a combination of CLI tools can create complex, templateable and customizable stacks to support the creation and growth of iOS codebases.
Based on the experience developed at JET working on a large modular project with lots of packages, helper tools and optimised CI pipelines, I wanted Stellar to be eventually part of a set of tools taking the name “Stellar Tools” that could enable the creation and the management of large codebases.
Something like the following:
- Tuist: generates projects and workspaces programmatically
- PackageGenerator: generates packages using a DSL
- Stacker: creates a modular iOS project based on a DSL
- Stellar: automate tasks
- Workflows: generates GitHub Actions workflows that use Stellar
From my old notes:
Current state
After a few months of development within this team (made of devs not working at Just Eat Takeaway), I realised things were not moving in the direction I desired and I decided it was not beneficial to continue the collaboration with the team. We stopped working on Stellar mainly due to different levels of commitment from each of us and focus on the wrong tasks signalling a lack of project management from my end. For example, a considerable amount of time and effort went into the implementation of a version management system (vastly inspired by the one used in Tuist) that was not part of the scope of the Stellar project.
The experience left me bitter and demotivated, learning that sometimes projects are best started alone. We made the repo public on GitHub aware that it was far from being production-ready but in my opinion, it’s no doubt a nice, inspiring, MVP.
The intent was then to progress on my own or with my colleagues at JET. As things evolved in 2023, we embarked on big projects that continued to evolve the platform such as a massive migration to GitHub Actions. To this day, we still plan to remove Fastlane as our vision is to rely on external dependencies as little as possible but there is no plan to use Stellar as-is. I suspect that, for the infrastructure team at JET, things will evolve in a way that sees more CLI tools being implemented and more GitHub actions using them.