Over the past decade, I’ve settled into a daily programming routine that helps me stay productive. It centers on code review, moving tickets forward, finishing in-progress work, and documenting what I learn. Here’s the exact workflow I use.
Why Have a Routine at All?
Many programmers don’t have a routine. So, first let me answer: why have one at all? A routine at work can be a double-edged sword; overemphasize it, and your day can feel too predictable.
The first reason I keep a routine is that there are some things I must do every single day, like team standups. My day goes more smoothly when I plan around events like these.
Second, there are things that I should do every day, like reviewing my peers’ code. A routine helps ensure I don’t forget these team tasks.
Each day, I try to accomplish the following tasks in the order listed.
1. Review Colleagues’ Work 📋
First, I review my colleagues’ work.
I use a Zsh terminal function to open the pull request page:
function rr() {
open https://github.com/<team>/<project>/pulls?q=is%3Apr+is%3Aopen+user-review-requested%3A%40me+
}
The long query parameter puts these important filters into the pull request search bar:
is:pr is:open user-review-requested:@me
Why start with reviewing? Code review is a great first-cup-of-coffee task for me. It helps my team right away.
And, it doesn’t use all my brain the way programming does. I actually think it’s a bit better to not be totally “on” when reviewing code. If something doesn’t make sense to me in that state, it’s probably too complicated.
When reviewing, I try to follow this checklist.
2. Move My Tickets to the Right ➡️
Next, I review my Kanban ticketing system, which I open with a Zsh terminal function:
function pt() {
open https://www.pivotaltracker.com/n/projects/123456
}
I read from right-to-left. On the right is my “Deployed” column, and left is the “Unstarted” column. All the other tickets are somewhere in between those two states.
My goal is to move each ticket to the right. For example:
- A ticket that’s passed QA gets deployed to production
- A ticket that’s passed code review gets sent to QA
- A rejected ticket gets triaged and fixed
- A ticket in progress… more on that below
- A ticket that I’m ready to work on gets started
If I can’t move a ticket, I try to figure out why.
I go right-to-left each time so that I’m systematically unblocking work, starting off with the most valuable activity, deploying to production.
3. Finish My In-Progress Work 🚀
Okay, we’re coding! Any work that I’ve left unfinished yesterday, I finish.
Something that helps me pick up unfinished work is committing small, well-named commits on named branches that are always pushed to the remote. When I do this, my Git log tells a story:
$ git log
ab9e405 Add (failing) test
1ud5bx7 Styled per design
59d5bd7 Complete solution
4bd3580 Initial spike
Reading from bottom-to top, I created a spike, got it working, styled it, and added a failing test. It’s pretty clear to me what I need to do now: make the test pass.
I start by checking out main and rebasing my branch interactively. This lets
me pull in changes and squash or rewrite commits that don’t tell the right story.
$ git checkout main
$ git pull --rebase
$ git checkout <feature-branch>
$ git rebase --interactive main
If I end the day with work unfinished, which happens often, I write myself a note describing what’s left, such as “cleanup CSS open PR.” I use an executable called figlet for this job, which prints my note in the terminal, where I’ll see it in the morning.
$ figlet "OPEN PR"
___ ____ _____ _ _ ____ ____
/ _ \| _ \| ____| \ | | | _ \| _ \
| | | | |_) | _| | \| | | |_) | |_) |
| |_| | __/| |___| |\ | | __/| _ <
\___/|_| |_____|_| \_| |_| |_| \_\
4. Standup 🤝
This is our mandatory team meeting. I have a terminal function that opens the Zoom call.
I show up, make small talk, give a report, and try to be helpful.
5. Bonus: Personal QA 🔎
Sometimes when I have extra time, I’ll do a short QA of our application. It’s a version of exploratory testing.
My goal is to find things that I know are broken or could be better, addressing what I can. If I can’t fix it right away, I write a ticket.
I’ve only started doing this recently and it requires a boss who’s okay with me going rogue. I find it immensely valuable because I get to scratch my own itches, increase my ownership of the product and empathy for our users, and fix bugs before they’re found by anybody else. Few manager will prioritize tech debt, even when it would increase velocity, so we engineers sometimes have to prioritize it ourselves.
6. Move Tickets and Review Colleagues’ Work, Revisited ➡️ 📋
I end the formal portion of my day with one more pass at the ticket board. Sometimes I’ve been waiting for a CI build or a colleague to review my work; this is my chance to react.
I’ll also do another pass at code reviews to ensure I’m not leaving anybody waiting.
7. Spin the Flywheel 🎡
Spinning the flywheel– publicly documenting what I’ve learned– lets me learn and graduate to harder, more interesting problems. Any time I learn something noteworthy, I try to think about how I can document that knowledge.
Typing up what you learned anywhere is valuable, but the medium matters. Count those keystrokes. The least effective place to share what you learned is an asynchronous chat like Slack. These feeds are fast and noisy and what you write there is going to get quickly lost.
I usually pick my TIL collection, where I’ve been writing short posts since 2015.
For ideas I’ve revisited again and again, I post on this blog.
Wrapping Up
Here’s the routine:
- Review colleagues’ work 📋
- Move my tickets to the right ➡️
- Finish my in-progress work 🚀
- Standup 🤝
- Bonus: personal QA 🔎
- Move tickets and review colleagues’ work, revisited ➡️ 📋
- Spin the flywheel 🎡