Lab4U saw an opportunity to increase the efficiency of its software planning, development, test, and release processes to become more agile, ensure consistent quality, and reduce time to market. Microsoft joined forces with Lab4U to implement an end-to-end solution.

Customer profile

Lab4U is an award-winning, Chilean-American company on a mission to democratize science education using mobile apps.

The first app it released, Lab4Physics, is an educational solution designed to help teachers around the world improve science education by making it easy and inexpensive to bring lab experiences into the classroom. Leveraging the built-in sensors found in smartphones and tablets, Lab4Physics instantly turns mobile devices into powerful science instruments—providing students and teachers with tools such as accelerometers, sonometers, and speedometers, all of which help bring to life predesigned experiments.

The Lab4Physics experiments involve fundamental topics such as gravity, acceleration, and free fall. It enables creation of pendulums to study waves. The experiments are organized into easily recognizable learning topics, making it simple for teachers to integrate new experiments into existing curricula.

The project team:

  • Fernando Mejia – Head of Product Development, Lab4U
  • Alvaro Peralta – Co-founder and Chief Technology Officer, Lab4U
  • Soledad Merlo – Audience Evangelist Manager, Microsoft
  • Hans Nemarich – Principal Technical Evangelist, Microsoft
  • Alex Campos – Technical Evangelist, Microsoft

Problem statement

The Lab4Physics “as-is” development process involved a lot of effort behind the scenes, multiple tools, ad-hoc integration, manual error-prone steps, and several points of wasteful activity. As a result, the time they spent per sprint cycle was an average of three weeks from planning to release.

Evolving applications quickly and efficiently is crucial because the company is immersed in a high-innovation startup environment and a competitive education market. This creates several challenges that Lab4U must overcome by shipping faster, continuously, and with the lowest costs possible.

One of their concerns was related to raising the application’s quality levels to the highest standards, but without having to compromise time to release. They needed a way to get real feedback and valuable insights about application runs, bugs, and crashes from real users and be able to inject that input early into the sprint planning process, as fast as possible.

When we talked with them, they were already using an Agile-based Scrum approach and several tools well known by the industry to manage their apps lifecycle, but without getting the theoretical benefits associated with a lean practice. We proposed to study their technical architecture and related applications lifecycle processes further.

Architecture

Lab4Physics runs as a native mobile application written in Swift programming language for iOS and Java for Android OS. Their back end is a set of Node.js services on top of the Mobile Apps feature of Azure App Service. The database layer is powered by a platform as a service (PaaS) Azure SQL Database and Azure Blob storage on top of Azure Content Delivery Network for delivering static content. Currently, the application is used in both Content Delivery Network regions. They’re also using a SendGrid component from the Azure Marketplace and Microsoft Power BI Embedded to visualize reports about key analytics application KPIs as usage, sessions, devices, users, countries, and so on.

Figure 1. Lab4Physics - high-level architecture view

Figure 1 – Lab4Physics - High level Architecture view

Value stream map

As soon as the product development unit demands more features, the IT team knows to be ready to ship several releases in a short timeframe. The Lab4Physics development has different subteams with some complex interactions. The back end and front end run in parallel, as do iOS and Android, but they depend on back-end services. Our main tool for identifying bottlenecks and friction points was the value stream mapping (VSM) methodology.

The execution of the VSM exercise helped us to understand where wasteful activities were and which results were associated with their software development lifecycle. In this case, with the Android application, we identified several pain points. Our main findings were about the use of different, nonintegrated tools to manage different parts of the lifecycle and several manual, ad-hoc activities. Those factors were keeping them from getting the benefits of a Scrum and lean development process.

Figure 2. Lab4Physics - value stream map

Figure 2 – Lab4Physics - Value Stream Map

As the value stream map shows, the kind of waste identified was associated with different parts of the development process:

  • Manual activities to manage the data in Azure that require 4 hours from one developer to process and execute.
  • Updating and syncing different tools for sprint planning and heroic waste, needing 2-3 hours.
  • More than 5 hours in the manual flow to test new features.
  • Some 2-3 hours for packaging and releasing a new version of the apps to both Google Play and the Apple App Store. It is important to address this in order to accelerate and improve the way to deliver the app first to stakeholders and then to end users.

The sprint flow starts with a weekly sprint meeting, where business requirements are prioritized along with bug fixing and improvements from previous sprints. Lab4U uses a combination of Atlassian JIRA for feature requests coming from their business area and Zendesk for bugs raised by end users. The input sources also include an Excel spreadsheet that has to be synced with JIRA, where they manage sprints and user histories, assign activities, and track the work done. There is a manual sync involving copy-and-paste between these tools.

After being assigned a user story, a Lab4U developer has to update the dev environment manually, which, depending on whether the developer belongs to the front-end or back-end dev team, involves updating and running new database scripts, deploying back-end Node.js app services, or updating a mobile app layer. After that, they code every user history against a Bitbucket repository, where application code is stored in per-feature branches. They have another branch for code merge and another for stable releases. Unit-testing code is also developed, along with application code.

Figure 3. Lab4Physics - sprint process

Figure 3 – Lab4Physics – Sprint process

When the sprint coding process is finished, there’s a code merge managed by their Scrum master before it goes to their integrated dev environment. At this stage they resolve any code merge conflicts to build a dev release. This way, they’re making front- and back-end services work together with the new features for the first time. Also at this stage, they perform an early integration test before moving everything to the QA environment.

Before moving the release to the QA environment, they update their acceptance dev criteria. This is a document that includes the minimum quality bar expected and the manual tests to be performed by their testers.

The QA environment must also be updated. They do another round of code deployment, run DB Scripts, and build and deploy Android and iOS packages for side loading. If everything meets the acceptance criteria, the code is moved into a release branch and deployed into the production environment. In parallel, the mobile apps are sent to publish manually into Google Play and the App Store, where they can be accessed by the end users. Feedback from end users is received in Zendesk and it’s prioritized along with features for the next sprint.

From the VSM, it was clear to the whole team that there was room for improvement. Using core DevOps practices such as continuous integration and continuous deployment could save valuable time to release. Integrating centralized automated testing into the dev cycle would raise the app quality, and having a way to put feature flags—allowing separation of code deploy from feature enablement—would increase the roll-out flexibility.

Solution, steps, and delivery

While we were conducting the Lab4Physics VSM, we thought about the scope to set in order to focus on the most critical dev-test-release path. The Lab4U team chose their Android app for the start of improvements to their dev cycle.

With a pure Java native Android app, we had the opportunity to leverage the Java capabilities of Visual Studio Team Services, its Java tools integration and Java unit testing and code coverage. Also, we could use HockeyApp to get faster internal deployments and detailed user feedback, and leverage some DevOps advanced practices such as feature flags, which would allow new features to be tested in production or to be released and activated later, decoupling the front- and back-end development. Our goal was to save time and help them to improve the quality of their product. Here’s what we made together.

Team Services setup

Creation of a new Visual Studio Team Services tenant was straightforward: https://lab4uinc.visualstudio.com/ was the chosen URL for our workspace with Lab4U. We added a new team room and a project called Lab4Physics.ANDROID. Adding us and Lab4U as a team members and assigning roles was also straightforward. We then divided the work that needed to be done into three stages: code, work, and build and release.

Code

The first step was to choose a repository type. Because Lab4U was already using Bitbucket—a private Git-based repository—our recommendation was to use a Git repository inside Visual Studio Team Services, which also has a plugin for Android Studio. This way, we can have a single and integrated place where code, branches, and developer permissions are in the same tool as the work, build, and release process. Our team migrated between remote repositories while at the same time maintaining previous history seamlessly.

After setting the repository origin at https://lab4uinc.visualstudio.com/\_git/Lab4Physics.ANDROID, it was time to set a Git branching strategy. We decided to organize branches using the following structure:

  • master branch is a folder that has a branch for every stable product sent to production.
  • develop branch is merged code coming from different features and hotfixes.
  • feature is a folder that has a branch for each product feature.
  • hotfix is a folder that has a branch for each fix that is not part of a stable release.
  • release is a folder that has a branch for every stable product sent to QA.

Figure 4. Lab4Physics - branching strategy

Figure 4 – Lab4Physics – Branching Strategy

We set branch policies to enable continuous integration or require a revision of pull requests in certain branches, to protect branch quality and subsequent maintenance.

Work

To choose a methodology for the dev process, the team had to decide between Agile and Scrum because the current process wasn’t CMMI-based (Capability Maturity Model Integration). After further examination, we determined the Lab4U dev process was more Scrum-based, so that was the most obvious option.

We started defining some product backlog items and mapping them to features. Then we mapped features into epics.

Figure 5. Lab4Physics.ANDROID – mapping backlog items into features, epics, and sprints

Figure 5: Lab4Physics.ANDROID – Mapping backlog items into features, epics and sprints

Later, we defined a sprint where tasks were assigned and progress was tracked through the built-in Kanban board.

Figure 6. Lab4Physics.ANDROID – Kanban board visualization for sprint 1 (newly created)

Figure 6: Lab4Physics.ANDROID – Kanban board visualization for sprint 1 (newly created)

Build and release

Because one of the goals was trying to saving time while also improving the dev process, we recommended setting up a continuous integration (CI) automated process at this stage. The main definition was:

“Any pull request on any branch will trigger a new build in VSTS.”

To achieve this goal, we chose to create a custom Linux build agent ‘lab4uCI’ because we needed to be able to add several Java libraries, customize runtime, and add SDKs to the build path for the complete automated build process.

An Ubuntu virtual machine in Microsoft Azure was created and subsequently a Team Services agent package was downloaded, installed, and configured to run as a Linux systemd service. Later, to have this virtual machine as a fully functional build agent for Android apps, we installed required dev dependencies, runtimes, and build tools:

  • OpenJDK for Linux, as Java runtime and SDK
  • Android Studio SDK for Linux, for Android-specific tool support
  • Gradle as a build automation tool
  • Other custom libraries for authentication, support, optimization, and testing

After restarting the agent, we got our new set of build capabilities ready.

Figure 7. lab4uCI – Linux build agent capabilities

Figure 7: lab4uCI – Linux build agent capabilities

After getting our agent live, we started the new build definition process. It started specifying repository, branch, and agent pool. The pool name ‘default’ is related to our recently created lab4uCI agent.

Figure 8. Build definition – repository and agent queue

Figure 8: Build definition – Repository and agent queue

Because Lab4U was using Gradle through Android Studio, we decided to keep a Gradle-centric approach, but managed from Team Services for maximum control and flexibility. This allowed us to save time and reuse Gradle settings files from their current dev process, which already had automated code coverage, unit testing, and bug- and style-checking conventions defined, along with compilation and APK packaging.

Using the Gradle built-in build step set to the gradlew wrapper utility integrates it to Team Services

Figure 9. Gradle build step definition

Figure 9: Gradle build step definition

Because every Android app requires APKs to be signed, we added an Android signing task after the Gradle step. Android APK signing is based on signed JAR—a standard in Java—that involved some additional Java utilities to create and set up a KeyStore file. This was the last step before staging and publishing the now-ready-to-release ‘drop’ APK artifact.

Figure 10. Adding an Android signing task

Figure 10: Adding an Android Signing Task

The release strategy was a little more sophisticated. The main goal was to streamline deployments into three environments:

  • Tester devices (QA environment)
  • Google Play, private alpha
  • Google Play, private beta

Because several steps were involved to configure each release definition, we will not cover the setup process of each in detail. Instead, we will highlight some key decisions we made.

In their previous dev process, every time Lab4U had to test a new build of their app, they had to manually side load it to their testing devices, which took a lot of time. We proposed to use HockeyApp as an automated deployment platform for their first environment, Ring 0, providing an automated distribution channel that will accomplish our objective. We installed the HockeyApp VSTS extension directly from the Visual Studio Team Services Marketplace.

Figure 11. Ring 0 – HockeyApp environment definition

Figure 11: Ring 0 – HockeyApp Environment Definition

Before going live into private beta, they wanted to add an internal staging area. They want to use it for prerelease testing in Google Play Alpha Track. We proposed that they install the Google Play VSTS extension and define this environment as Ring 1.

Figure 12. Ring 1 – Google Play Alpha Environment Definition

Figure 12: Ring 1 – Google Play Alpha Environment Definition

The last stage we helped to create was related to promoting Google Play Alpha to Beta Track. This is used for private beta deployment to a group of Lab4Physics registered insider users, before it goes to general availability. This is named Ring 2.

Figure 13. Ring 2 – Google Play Alpha to Beta promotion

Figure 13: Ring 2 – Google Play Alpha to Beta promotion

Integration and extensibility capabilities of Team Services allow us to integrate with Google Play seamlessly, accessing even advanced Google Play features such as track selection. This way we proceeded to automate the publishing process to Google Play, a cumbersome manual task.

Figure 14. Improving release environment cycle through different rings

Figure 14: Improving release environment cycle through different Rings

Bonus: Slack and feature flags

After the cycle was completed, we proposed to implement a very easy and useful Slack integration. We accomplished that using service hooks and a Lab4Physics Slack group as described here. We configured it to be triggered with every build to release.

We also proposed testing one of the DevOps advanced practices: feature flags.

Feature flags are a best practice for rolling out, or testing, certain functionality in production. They allow you to toggle certain features “on” or “off” on the fly, without having to re-release or distribute any incremental version. This is useful to separate code deploys from feature rollouts, but also to have a more flexible way to ship, roll out, and roll back specific features.

We chose LaunchDarkly, which provides a flexible framework to implement and manage feature flags in a convenient software as a service (SaaS) model. We helped Lab4U to set up a message feature flag as one of the simpler examples.

Code snippet: feature flag sample code using LaunchDarkly

import com.launchdarkly.client.*;

String message;
LDClient client = new LDClient(SDK_SECRET_KEY);
LDUser user = new LDUser("xxx@xxx.xxx");

boolean isOn = client.get().boolVariation("lab4.physics", user, false);

if (isOn) {
  //message = "Hi There!"
}
else {
  //message = "";
}

Figure 15. Lab4Physics.ANDROID – LaunchDarkly feature flags portal

Figure 15: Lab4Phisycs.Android –LaunchDarkly Feature flags portal

Conclusion

This project combined Lab4U and Microsoft team skills, delivering excellent results in a very efficient way. Using the value stream mapping methodology was key to identifying wasteful and inefficient labors, thereby giving great insight into the underlying dev process. This project was implemented in five meetings of two to three hours each.

Visual Studio Team Services proved to be an awesome tool to support a Java-Android app scenario, providing capabilities from well-known Java build automation tools such as Gradle and APK (JAR) signing. A very rich set of plug-ins from Visual Studio Marketplace allowed us to go even further, seamlessly integrating third-party tools such as Slack and Android Studio IDE or publishing directly to HockeyApp and Google Play in a fully automated way. This reduced the time to publish either in QA or production from more than 3 hours to a few minutes. Also, reducing the number of different spare tools and consolidating everything into Team Services allows Lab4U to bring every stakeholder to the same table, from business users and Scrum masters to testers and developers.

The addition of HockeyApp to the test process was also valuable, adding a better and faster way to deploy builds for testing with a new layer of real user feedback, which allows them to improve their app and raise their quality bar.

Two weeks after we finished migrating their Android dev cycle, Lab4U migrated their iOS and Node.js-based app services dev process by themselves, following the same methodology. Now the whole sprint process from planning to release takes only one and a half week. They still keep their value stream map in their offices to keep improving.

Figure 16. Lab4U and Microsoft – end of VSM session 2

Lab4U and Microsoft – End of VSM Session 2

“Thanks to Microsoft, Lab4U is now a truly agile business. Value stream mapping methodology and Visual Studio Team Services allowed us to focus most of our time on product feature development, achieving more productivity and spending less time on doing manual tasks while at the same time improving our dev team happiness.”

– Fernando Mejia, Head of Product Development at Lab4U