Incrementally Moving to Trunk Based Development and CI - Part Two
In Part One I laid out my thoughts on Trunk Based Development (TBD) and how it interacts with aspects of DevOps, Automation, Separation of concerns, Clean Architecture and more.
Here are some questions you might ask, a hypothetical and resources to reference.
What about X?
I’m sure there are a lot of questions floating around in your head. “Why should I change my process?” “Why do you think this is the approach to use?” I’ll attempt to answer some of them. Add more in the comments and let’s discuss more. Remember to read the recommended books for a better/in-depth argument and answers to your questions.
Feature flags for the full stack?
I’d try having a DB table called FeatureFlags. Cache this value on startup and use this throughout. Have a way in the UI to turn this value on and off and require a login/logout. You should think about having this per user or per group or for the full app. Having for the full app would be the easiest first attempt.
Won’t more commits/pushes = more chaos?
“My concern is that I think that there would be a noticeable drop in productivity as we change processes. We’re already constantly behind, so I’m not sure it it will be accepted by management.” ~ a knowledgeable and experienced co-worker
This question is very valid. I’d point you back to The DevOps Handbook and the Accelerate research book that points out that teams have gotten over this hump and that you probably will have a drop in “productivity”, but if TBD is achieved, you’ll gain that time back quickly.
You need automated tests and builds to reduce the chaos.
How does QA keep up with things changing?
- Isolate in progress with feature flags
- make sure to remove flags after work is done
- talk about combination of flags
- Have flags toggleable in a UI/script so QA can change when needed
- Automation will reduce the manual testing time and manual regression testing needs
- Automate the ability to create an environment, allow QA to each have an isolated testing environment if necessary
- They are still essential
- Embed them in the team, to test things in pro
How do I monitor with things moving?
- Use AppInsights
- Create a page that shows the version of all the pieces (pull of the dll version)
My team isn’t ready or doesn’t seem to have desire to change or learn new things
- Most developers I work with have a desire to learn new things. Sometimes there are too many deadlines or pressure for them to spend energy
- Make sure that changes can be implemented, there’s not much that is more demoralizing then identifying issues and not getting a chance to change things.
How is my marketing/tech writing/training group going to keep up?
- embed a Tech writer in the team
- involve them with planning before sprints
How do I know what’s released in each version if it is always changing?
- Create a version page to easily view it
- Use Azure DevOps work items and require association with a check in. Coupling this with a release pipeline provides good visibility to this.
How do I fix issues in production?
- Label the source code (in the build) with each artifact (the output of the build). Then you have to know what’s released.
- When a bug is found, create a branch, fix the bug, do a good pull request/code review, push that version out with only that change.
- merge that bug fix commit into master.
- See Git-scm Chapter 3.2
How do I handle database schema changes?
- Step #1. Get your database schema into source control with DB Project or other tool
- Check in the DB changes before or with other changes.
- Make additive changes with default values.
- if you need to remove a column, declare them as obsolete and notify consumers that they have a few release/months/what makes sense.
- Here’s a more in depth article
How do I handle deploying to multiple environments/clients that are hosted in different data centers?
It’s a lot easier to do TBD and CD when you have a simple web application, but it is definitely more complicated when you can’t just use Azure DevOps builds and pipelines to push things out when you want. You’ll have multiple versions and production environments to handle.
- Is is possible to move to a Software As Service (SaS) model and add in users/auth to distinguish between the clients?
- Successful example: VSTS (now Azure DevOps) was releasing every 3 weeks to their Azure hosted and TFS versions every quarter or so.
- I suggest a goal of having only 2 or 3 versions out. Make it easy and safe to upgrade and deploy. Then the Ops people will take your updates. Make it automated so that they can schedule it on off hours. After a dozen or so non-event upgrades, they might even trust you to push the changes remotely, without all hands on deck. Work to build that trust.
- Don’t forget a rollback plan, in case something goes wrong.
- As you “move the pain forward” and deploy more often, you’ll get better as you improve your process and automation.
Why, you should
My friend, slarson gave this feedback. “For the process discussion and friction around having dev and master be separate and they pain it introduces I like to remind people: 10 minutes of your day is 1 week of your year. It is super counter to a lot of dev ops cultural posts, but I think getting flags around changes, some form of test automation on a build, linting, and an easy way to publish a metric are more important than the cultural side because the standard argument is how “that’d be nice, but we don’t have X Y Z so we can’t do that””
Let’s say you have a MVC .Net Framework application and multiple WebApi projects that is several years old. There are 3 TFVC branches DEV/QA/RC in your on-premise TFS. There are no builds (or existing XAML builds that take way too long) in your TFS setup at the moment.
A standard process is to write code locally, check in to main with a goal of one change-set, deploy to Dev, test in Dev and review with the team. Once approved, merge to QA and QA can start testing. Repeat as necessary for any issues QA finds. Once QA verifies the changes, then merged to RC.
How do you incrementally improve?
- Buy the Phoenix Project and The DevOps Handbook for everyone. Commit to reading as a team weekly book lunch discussions.
- Watch the Spotify videos
- We need builds to make sure the code builds
- There aren’t many unit tests, if any
- Does the deploy to environment happen manually through VS or through the XAML builds?
- How stable are things? Is QA getting interrupted often
- We need to get the database into source and version it with our code.
- We have complex production environment with multiple servers with CRM and other dependencies.
- Branching issues
- Are they adding value?
- We spend several hours per developer merging to QA and still have manual merge issues
- Do you have errors due to manual merging issues?
- Do you know what version of code is in what branch?
- Can you reduce 2 branches into 1, then eventually go TBD?
- Merging to RC isn’t happening as often as it should and getting a release out is very difficult (2 weeks on average, with frequent delays when bugs are found)
- Do a value stream mapping exercise to identify work (Making Work Visible looks like a great reference book)
- How can you minimize work in progress (WIP)?
- Where is the technical debt in your system?
- Make a plan/goals - Month 1
- Get a gated build working that build the solution and run tests (use the “vNext” builds and convert any XAML builds to the task based builds)
- Write unit tests on new features, any new bugs found and identify critical areas for tests to be added
- Create a SQL Server Database Project and use it to deploy DB changes
- Investigate moving to each developer having their own database.
- Identify minimal seed data needed for each database.
- Move to 2 week sprints with the goal of something to demo and release at the end of each sprint
- Pay down technical debt in x area each sprint.
- Work on reducing technical debt and coupling in your code.
- Clean Code by Bob Martin and @ardalis at Weekly Dev Tips has great tips on this.
- Goals for beyond (split into pieces that into 1 or more sprints)
- Investigate migrating to the Azure DevOps Platform
- Create scripts to create your environments (Automate everything you can)
- Does moving to Azure AppService and other tools on Azure make sense for our company?
- Create a Continuous Integration/Release Pipeline to take the built files and deploy to the environments
- Deploy the web application
- Deploy the Apis
- Update the Database
- Start writing UI tests with Selenium to cover common use cases and reduce manual regression testing
- Move more code into a “platform API” so that other applications can use the same endpoint.
- Make environment creation easy
- testing a branch should be easy
- Azure and virtualization makes this easy in some cases (but watch your costs)
- Containers might be an option here
- This includes DB creation from scripts with the minimum amount of seed data
- make it throw-awayable
- Add AppInsights (if hosted on Azure/internet out accessible) or Stackify for logging and monitoring
- Show progress to the company
- Move to Git
- Git helps a lot with branches
- You don’t have to move from TFVC, but after moving to Git myself, I think it does help a lot.
- Be prepared to have a lot of questions and some messed up branches. It’s good to have a git “guru” available for these questions for a few weeks as people get used to the change.
- Here’s my help on the topic
- Feature flags/toggles
- hide in-progress work
- different then hide/show features from users based on user/feature set
- Evaluate (Retrospective)
- How have things improved?
- Are we getting changes from dev start to tested complete out to our users faster?
- Deploying faster?
- Less time merging?
- Less confusion on what is in what environments?
- Anything not going well?
- What do we need to change/tweak to continue improving?
- Celebrate, share what you learned and continue improving.
In order to reduce the friction of getting value (completed features/fixes) to our customers, we want to incrementally move from processes that cause the friction. One of these areas is having multiple branches to isolate changes that require merging.
We need to move incrementally, because in most circumstances the business is still demanding new features. There are certain “capabilities” that are required to move towards trunk based development.
I’ve proposed some common things that will help move towards TBD.
- Learn Together
- Make goals together
- Choose where to start to incrementally improve
- Get management buy-in and ensure time to work on this
- Evaluate often (Retrospective)
- Start moving and improving
This is my collection of links. Of course, there are many more.
I considered naming this “I want to be done merging code manually, but I don’t know how to get there” to mimic my I know I should be Unit Testing, but I don’t know how or where to start - presentation :-).
A Grand Adventure
I think it’s worth repeating this :-).
As Bilbo said to Frodo “He often used to say there was only one Road; that it was like a great river: its springs were at every doorstep and every path was its tributary. “It’s a dangerous business, Frodo, going out of your door,” he used to say. “You step into the Road, and if you don’t keep your feet, there is no telling where you might be swept off to.”
Frodo Baggins about Bilbo, The Fellowship of the Ring, Three is Company”
~ Found with Bing on
Keep evaluating and improving and I think you’ll end up in a much more productive and happy place for your team and company.
If you find value in this post, please re-tweet my conversation and share this with others.