Effective App Development Scrumban Workflow
My team embraces Scrumban, a methodology that ingeniously combines the strengths of Scrum and Kanban to deliver flexibility and efficiency in our development process. It uses Scrum's stable structure of sprints, standups, and retrospectives, according to Atlassian's definition. Then it adds Kanban's visual workflow and work-in-progress limitations.
I'd like to share the app development workflow that my team has honed and refined over time. This workflow has consistently proven to be highly effective.
The Workflow
An agile workflow serves as the roadmap for agile teams, guiding the development of an application from initial ideation to successful completion. Below is the workflow that we follow:
- Ready: Work that has been defined and is ready to begin.
- In Progress: Work currently in active development.
- Code Review: Work that has been implemented and awaits review.
- QA: Work that has been implemented and reviewed, now awaiting testing.
- Waiting for Release: Code that has been reviewed and is ready for merging into the main or release branch.
- Done: Completed work.
The Development Flow
Once a task is fully defined, it progresses through the following development states:
Each state has a primary contributor:
- Engineer (Author)
- Engineer (Reviewer, Release Manager)
- Product Manager & Product Designer
Let's delve into the roles and responsibilities at each stage of our development flow.
Ready
- Owner: Engineer (Author)
- Activities
- Ensure that the task's description and acceptance criteria are adequately defined.
- Next Steps
- ✅ Good: Move the task to the In Progress column.
- 🚫 No Good: If more information is required, collaborate with the team to resolve any issues before proceeding.
The "Ready" stage marks the starting point of the development workflow after the discovery and definition phase. We want to make sure that tasks are truly ready. This means that every element necessary for the engineer to proceed should be in place - including well-defined acceptance criteria that describe the "Done" state. Major engineering decisions should have been made before this stage to prevent engineers from encountering major architectural questions during development. For example, if a new feature requires new data, its location should already be determined at this point. Once everything is set, the author can move the task to the next stage: In Progress.
In Progress
- Owner: Engineer (Author)
- Activities
- Implement the code changes.
- Write and validate test code on a local machine.
- Prepare for Code Review and QA.
- Next Steps
- ✅ Good: Move the task to the Code Review column and assign it to the reviewer.
- 🚫 No Good: If the task is blocked, mark it as flagged and communicate with the team before starting other tasks.
This is the stage where actual coding takes place. Ideally, only one task should be in this column, as juggling multiple tasks in this phase can lead to a high context-switching cost.
Before writing the actual code, it's a good practice to consider the direction of the changes. When implementing the code, it's helpful to work in two phases: 1) Make it work and 2) Refactor. Try to implement the feature with the smallest amount of code changes. This approach will help you write efficient code and allow you to share the in-progress work with the product team to receive any ad hoc feedback as needed. Don't forget to perform refactoring at the end to ensure that your new code is in its proper place, which will benefit future engineering efforts, including your own.
We've set up continuous integration (CI) to automatically build review apps whenever the author pushes new changes to the remote repository. This helps code reviewers and QA person in testing the new changes on their devices. Not every task requires this type of verification, but for some, it is immensely helpful.
Additionally, consider how to facilitate the QA process at this stage. For example, taking screenshots or recording video of your changes can help code reviewers and QA person. It's also essential to prepare for the code review process by providing clear descriptions for merge requests and tidying up code changes. When everything is ready, the tasks move to the next stage: Code Review.
Code Review
- Owner: Engineer (Reviewer)
- Activities
- Review the code in accordance with the team's code review guidelines.
- Reviewers can use screenshots and review app builds as needed.
- Next Steps
- ✅ Good: Approve the merge request, move the task to the QA column, and assign it to the QA person.
- 🚫 No Good: Comment and assign the task back to the author.
Code review is a critical peer review process that helps developers ensure or enhance code quality before merging and deploying it. We conduct code reviews for all code changes, as we've found it to be one of the most practical ways to maintain a clean and flexible codebase.
To avoid code reviews becoming emotional battles between authors and reviewers, it's vital to establish clear code review guidelines that everyone on the team can agree upon. The goal isn't to achieve perfection, as there's no such thing as perfect code in this world. We approve merge requests when we believe that the code changes represent an improvement over the previous code.
Once the changes pass the code review stage, they move on to the next stage: QA.
QA
- Owner: Product Manager, Product Designer (design review)
- Activities
- Test and ensure that the behavior aligns with the acceptance criteria.
- Next Steps
- ✅ Good: Move the task to the Waiting for Release column and assign it to the Engineer (Release Manager).
- 🚫 No Good: Assign the task back to the author.
QA is where we validate that the changes meet the specified requirements. Product Managers primarily verify if the change aligns with the PRD (Product Requirement Document), while Product Designers check if it aligns with the design requirements.
The question arises: should both Product Managers and Product Designers QA the changes? There's no definitive answer to this question, but it's crucial to give both of them an opportunity to provide feedback at the right time. What has worked well for us is having engineers collaborate closely with designers during the development (In Progress) phase. Once they've achieved the initial implementation (making it work), they can promptly share screenshots with designers to gather graphical feedback and make early changes. By the end of this stage, the changes should already align with the Product Designer's perspective, reducing the need for additional design QA.
QA by the Product Manager is better to happen after the Code Review, as you don't want to have the code change approved by QA, and then receive Code Review feedback and accidentally break the QA-approved behavior while trying to resolve the code review feedback.
When everything is in order, we can advance to the next phase: Waiting for Release.
Waiting for Release
- Owner: Engineer (Release Manager)
- Activities
- Merge the merge requests into the integration branch.
- Prepare for the next release.
- Next Steps
- Move the task to the Done column and assign them back to the authors.
The "Waiting for Release" stage primarily involves activities conducted by release managers to finalize tasks and prepare them for app releases. This stage is particularly valuable because we utilize review apps from feature branches and don't merge changes during the QA process.
During this stage, the release managers, one for iOS and another for Android, merge the release branches and link tasks to upcoming release versions. At the end of each week, we create an integration build for iOS and Android, and we submit the binary for app review. You can find more details about our weekly releases in this post.
A Final Thought: Iterate
One valuable lesson learned over time is that there is no one-size-fits-all perfect process for all teams. Even a process that worked well for a team during one season may not be the best fit for another. To ensure the process continues to serve the team and not the other way around, it's essential to iterate on the process. This iterative approach helps the team better understand why the process exists and allows for adjustments to any aspects that may not work for them.