Development is complicated. Not only because of the technologies and patterns that are required knowledge, but also because of the myriad of tasks that are involved in getting work to production.
As an example, I picked up a story this week that was adding a new field to a form. Simple enough, but it went like this.
First thing's first. I need to make sure I have the right tools to do my job here. Does the ticket have acceptance criteria? Do I understand what changes need to be made to accomplish what's entailed? These checks are the first set that I'll run through when starting the process of working a story.
Once the ticket it good, I make a plan for getting the work done. This is my time to figure out what parts of our codebase I'll need to touch to get the new feature done. I normally write this out in a notebook I use as a mousepad.
For this story, I needed to update three things.
- Database
- API
- Front End
It's important to point out that we have four environments in our delivery pipeline and work flows in this order: Local -> dev -> UAT -> Prod.
I added a new column to the DB to hold the new value. Because all dev work starts locally and then is propagated to other environments as it moves through the delivery pipeline, I wrote a script to add the column.
This is the first thing I need to keep track of. Tasks like this are one type of work that is involved in the process for working through a story. If I push the code that uses the new column to another environment without first running the script for the DB in that environment, things will break.
So, I write that down on a sticky or take note of it in my notebook.
Secondly, I pull down the first of two repositories (the API) that will require changes to get this story done. Here lies another set of things that have to happen in the right order. I run tests on the parent branch to make sure things work, then make my own branch, make my changes, run tests, make changes, run tests, fix tests, and make commits along the way.
Once that repo is good to go (I know because I've tested it running against the DB changes I've made...locally), I move on to the second repo, the front end, and repeat the process.
At this point, I have three separate pieces of work (DB script, API pull request, front end pull request) that all work together and depend on one another to meet the acceptance criteria of the story I'm working on.
This is where I really have to start paying attention to process. Because I have multiple PRs out, it's inevitable that they are reviewed and accepted at different times. It's possible that one gets the green light one day and one the next. When they do get the ol' "good to go", "ship it", or :thumbs-up:, I'll need to merge them into the next environment in the pipeline. It's important they go in the right order so things don't break and I have to remember to run that damn DB script on every environment along the way.
If my work gets kicked back by QA, the fix will more than likely only be in one of the two repositories I've worked in. So, at that point, I have to remember to pull back the other work as well so things stay together.
All the while, because the work for that story is done and I'm just waiting on things to happen, I'm starting the process all over again with another story.
The hard part about all of this is that this seems like one process, "Working a story", but in truth it's many disparate checklists, tasks lists, and time lines that have to be managed correctly just to get one field into a form. More than once, this concentric circle of checklists has bitten me and some piece of code was in an environment before it should have been.
I'm wondering how other devs deal with this complexity. What tools or methods do you use to manage it?
Top comments (5)
I am totally with you about all the problems you stated. Specially the thing about that damn DB script. that's always a big scary point in going into production: "we didn't miss any DB update right?". What we do regarding the different repos: frontend and API are different stories dependent on each other. Whenever possible we ensure that stories in the frontend who rely on a backend-story don't make it into the Sprint as long as the backend is not on production. Meaning we try to break down stories to the minimum deployable unit. So you focus on one thing during development and dependencies are sorted out by mid term planning.
sorry, got carried away by the repo-part. How I work thru a story? If it's not clearly defined, it doesn't make it thru estimating and planning. So I start defining which parts it touches (data layer, utils, buisness logic...) and then work my way up: write tests that define the behaviour, write code till tests are green, create pull request, next layer. If a pull request depends on one of a lower layer I mark it WIP with a reference to the version/pull request it's depending on.
How big is your team?
The whole team is roughly 8 devs. But on different technologies (web, iOS, Android, backend, 3D, core)
That sounds very similar to the process I follow where I work. We face a few unique challenges in our particular market but we're slowly working past them and changing attitudes along the way.
We're mostly a monolithic application transitioning over to small Java libraries. Because of that, we have a lot of dependencies (aka libraries) to manage. In order to address this, we pull our dependencies in via Gradle. This makes it easy to promote code in separate repositories without worrying too much about parts of a story getting ahead of the rest of the story, though that possibility is still there.
Another very nuanced and complicated issue for our particular situation is that we don't continuously deploy (currently... working towards it). We do continuously integrate, but deploying happens only after release which happens a few times a year. This is a pretty complicated issue given the customers we target, but I do feel it's the right choice (for now) given the constraints we have. As such, we don't have to worry about one part of a story going straight to prod since releasing and deploying is such a huge process at the moment.
Maybe to help understand this I should briefly describe our general process. It's pretty similar to yours:
After opening the PR on the core repo, the rest is automated. It'll eventually get into a "pre-release" type branch where it waits until the company is ready to release. Keep in mind that this is happening for 9 teams of 8-12 people each. Sometimes that causes issues but most of the time it runs smoothly. This process is also constantly improving. It's gotten significantly better since I started and we have goals to improve it even more.