At hyper, our mission is to improve the Developer Experience because we believe that happy developers === quality product === happy customers.
Having an ephemeral development environment means I can simply create an issue in GitHub and open a fresh Visual Studio Code environment with a new branch for the issue with GitPod. The environment bootstraps itself and seeds a local dev environment with clean data. Our entire hyper cloud developer dashboard stack runs locally within GitPod. I start fresh with a clean environment every time. I don't mutate a shared development database with other developers. It's all local. I know that the code I have is the most recent. Merges and conflicts are kept to a minimum. Feature flags allow me to write features and ship early. Our feature flags are grouped by environment. So I can set configure a scenario in dev knowing that my feature is hidden until it is time to release. Its the best dev experience I have worked with in over 25 years. I love it.
Trip Ottinger - hyper
How do we get happy developers?
- Motivation (provide developers a fair salary and benefits)
- Intrinsic Motivation ( Autonomy, Mastery, and Purpose )
- Remove repeatable friction (automate)
What is friction?
Friction is a force resisting relative motion, developers are happy when they are solving problems within a flow or relative motion of creating, verify, update, verify, ship.
Define a problem, create solution, verify solution, update or fine tune, verify, review, deliver, go to next problem.
What are things that create friction in developer flow?
- Merges and Interruptions (Code Reviews/Pull Requests, Training/Onboarding)
This friction has many solutions, our solution was to document the big picture, where do we want to go (mission and vision)? Then capture our values/principles and practices and write them down.
At hyper, we created a repo called journal and we document our big picture, values and practices in this repository for all to view and provide input and modification.
Then we record updates or stand-ups in slack and via releases/changelogs.
We dont have unnecessary meetings just to have them. Our meetings result in a path forward on the issue at hand.
Every software project has general tasks that have to be done in order to focus on the purpose of the application. We call these chores:
- Setup Dev Environment
- Seed Data
- Setup Test Environment
- Update/Maintain dependencies
- Automate deployment, releases and rollbacks
Our focus is to automate all the things as much as we can automate these tasks we do, we use hyper our product to provide a generic re-usable API to common services which allow us to build re-usable tools and scripts for common chores. And we make them idempotent. This means they can run again and again and always return the result is always the same outcome.
Merges and Interruptions
In previous development teams, we would work in a feature branch development process where each task was not submitted to be merged until it was complete, and when using a sprint cycle this often resulted in longer than usual merge processes. Because the developers on the team were working on their assigned features in branches, we would have to come together for a day to merge all the results then it could take the QA team a few days even a week of back and forth to resolve issues. This was a huge friction point in our developer flow, we wanted to eliminate or reduce this friction. The answer is Continuous Integration or trunk-based development.
Continuous Integration - Trunk based development
The act of continuously integration your work into the main branch of your project regardless of the feature is complete. How?
- Parallel Code Reviews or Pair Programming
- Short-lived Pull Requests
- Cloud Development Environments
- Feature flags
- Branch by abstraction
This was very counterintuitive and we had a huge debate on this recommendation, everyone agreed that this was a source of friction and would love to solve it, but some were not sold on the idea of committing unfinished features to production code. The main debate came down to short-lived pull requests and cloud development environments.
Short-lived pull requests
Task or Topic requests, ideally you are creating and merging these branches multiple times a day, but a branch should never last for more than 2 days. Team members commit to being available for code reviews within 15 - 30 minutes of the request.
With cloud dev environments, we can open a pull-request in a separate tab and quickly perform a code review, run the test suite and interact with the code, create comments, recommendations, etc.
This process eliminated the friction of merges because we are basically always working with the latest code, the code reviews are quick and effective because there is only so much code you can create in one sitting.
The use of a cloud development environment means that our project is instantly ready for onboarding, there is no development environment setup, when you launch the project in your tab, you are given a full development environment ready to code, running all the necessary components to provide you continuous feedback. By our whole team constantly onboarding we keep our environments automated and instant so when new team members join, there is no lengthy install or setup process, they click a button and they are working in the code ready to commit.
Frictionless Development is about focus on developer flow while providing high-quality software. Trunk-based development with Short-Lived Feature Branches and Cloud-Based Development completed our CI/CD picture and radically reduced the friction in our development lifecycle. We are excited to come to work every day and get into developer flow and move the product forward. There are some challenges with this approach that you have to work through, but I can say it has been a game-changer for us.