Bitrise is so flexible that even if it is primarily optimized for mobile apps you can test and deploy a web app using the Linux stack. re:thinc was looking for a CI that they can use for both purposes. Read their story:
Guest post by Christian Feuz, the original post appeared in German on the re:thinc blog.
Christian is a software developer and cofounder of the Swiss-based startup re:thinc. He likes well-tested code, agile methods, Kotlin, and snowboarding. re:thinc creates inspiring digital products such as native apps, web applications, and web services.
One of our major concerns at re:thinc is the ability to deliver the current state of development to all involved parties at any time. We aim to show the concrete product in its current form rather than having discussions based on wireframes or other non-functional artifacts. From a technological point of view, the basic prerequisite for this is an automated process for testing and distribution of the executable product.
What do we expect from a build pipeline?
We have been thinking about how this process should look like in order to simplify the development process and create additional value for all project participants and stakeholders.
Therefore, our build pipeline should match the following requirements:
- Being able to deploy a new version at the push of a button.
- No manual interaction should be necessary during the deployment process.
- If required, the ability to confirm single steps manually (for example after a GUI-testing).
- Ability to update the production environment without any service downtime.
- Being able to rollback to an older version in case of an error.
- If necessary, easily starting up a new test environment.
- Avoiding dependence on a particular cloud service (no vendor lock-in).
In addition, we have formulated some basic requirements for the applications themselves:
- Each service should offer resources to automatically check the current state (health check).
- Each service should be able to be tested fully automated.
- All services should be stateless to ensure scalability.
From a rough idea to an operational build pipeline
For the source code, we already have a version control system (Git) in use. The source code is hosted in private repositories on Bitbucket. Bitbucket has the particular advantage of being integrated well with our ticketing system Jira. Initially, we used Bitbucket pipelines to test and build our applications, however, we soon reached the limit of what is possible (for example with regard to iOS). Since we want to avoid using multiple build tools simultaneously, we have been looking for alternative solutions. With Bitrise we found the friendly robot we were looking for. Bitrise provides the possibility to create complex workflows in an easy and intuitive manner for different target platforms through individual build steps. Furthermore, all environment configurations can be versioned with the rest of the source code (as a YML-file). Bitrise also supports iOS and Android builds by default.
We also use Bitrise to pack the application into a Docker image and then push the image to our Docker registry. Docker images allow developers to define the application environment with all essential settings (for example dependencies, libraries, and environment variables) by code and then run it on any (Docker-)environment.
So far we've updated the applications on the Docker host manually, which lead to a short downtime of the service. At a JS meetup in Berne, a presentation about Rancher caught our attention. Rancher is a management platform that allows Docker containers to be distributed and orchestrated across multiple physical servers. With Rancher we are able to scale a certain service to any number of instances. Rancher then takes care of the Docker image distribution, load balancing, and application monitoring.
And how does this work for apps?
We also want to fully automate the deployment of native iOS and Android apps, which requires these additional steps:
- Application signing with the relevant Appstore certificate.
- Deployment of the signed application through the distribution channels.
- Direct access to the current build (for example for manual testing before the release).
Our applications are available via the Appstore of the respective platform. That’s why we decided to use Testflight (Apple) and Google Play Store Beta (Android) for beta releases. This way we can deliver our beta versions over the proven infrastructure of the dedicated provider. In case of iOS, Testflight offers the possibility to deliver our application to up to 10,000 test devices without signing the app differently.
Bitrise provides predefined steps for signing and distributing to the respective store. In addition, we have the possibility to get the signed applications directly from Bitrise without having to take the detour via the distribution channels.
The pipeline covers all our predefined goals and is flexible enough for any future adjustments. Thanks to the versioning in the Docker registry and the functionality of Rancher we have additional tools to guarantee a stable production environment. We were also able to reduce error-prone manual steps to a minimum. As a result of having different environments, project participants have access to the current state at any time and are able to provide prompt and valuable feedback.