A workflow automated and optimized for simplicity
Imagine a workflow so sophisticated, that you couldn’t break the integration branch even if you tried. And at the same time you wouldn’t have to go anywhere else than your terminal and your favorite IDE to manage issues, promotions and deploys.
So as a developer I’d like a workflow that goes like this:
Tasks and issues are groomed and ready to work on. When I want to work on a task I set up a branch for the purpose. When I’m done with my work I deliver it for integration - and hopefully I’ll never have to go back to that again; The Jenkins automation backend tests and verifies that everything is OK, and if not, I get a notification. The issues are promoted automatically, through the task management system.
We have given ourselves the luxury to choose a simple, minimalistic tool-stack that supports our ideal workflow. We use it for a wide range of our deliveries and it’s easy to demonstrate, since most of these are Open Source.
masteris the integration branch if it exist locally - otherwise its’
GitHub, Waffle and Jenkins all contribute their part of the magic.
closedbefore the issue - It’s automatically closed.
fix-#112and it’s pushed to
originthen waffle.io will mark issue #112 as work in progress.
origin, but simply by adding the label that Waffle.io uses for marking work in progress (we use the label “Status - In progress”).
ready/*. It then kicks off the integration onto the GitHub default branch - typically
ready/*branch is removed.
We’re using the same set of labels in all our GitHub repositories and in the flow between columns in waffle.io.
The action labels are set to indicate that the person who the issue is assigned to needs to take some kind of action - the issue is in a blocked state.
The priority labels follows the MoSCow rules and are set by the issue- or product owner.
The size labels indicate the estimated workload on the developer or asignee and are set by the person who shall implement the solution. Size 0 is used to indicate that the issue is not workable - is’t a briefing or an epic. It describes something that will have to be broken into tasks. Small Indicates that it can be done in less than two hours. Medium is up to five hours of work, and large is up to a full day’s work. If the estimate is too big it indicates that it will take more than a day to implement and it will have to be broken down.
The status labels are the ones that we use in waffle.io to indicate the promotions between columns, except the black duplicate which allows you to close a case, without any other comment than a reference to the issue it duplicates.
GHI is a ruby gem you can install simply by running:
It allows you to manipulate all the GitHub issues, labels and milestones. All you have to do, is have your current working directory in a clone of a GitHub repo, and the ghi command you issue will operate on the issues there.
Ghi allows us to create all these labels in a new repository like this:
If it really is a brand new repo, or at least one where issues haven’t been used before, you probably want to start with removing all the default labels to get a fresh start:
Jenkins is used to do the integration. So a dedicated job will monitor any branch that is named
ready/** and when it finds one, it will checkout the default branch, integrate the branch that triggered it, commit and then run the toll-gate test. If the build is successful, the new commit is pushed to origin and if it’s not, a message goes out to the committer.
This is all done simply by installing the Pretested Integration Plugin and then just going with the default settings.
We have created a handful of Git aliases that we’re using to support this flow:
To use these aliases simply copy them to the aliases section of your
git issue-wip <issue-number> will set the label used to mark an issue as work in progress. In waffle.io it will be moved to the corresponding column.
git issue-branch <issue-number> will take the title of the issue and based on this, it will construct a string that will essentially make up a good branch name for working on this issue.
git default-branch is used to determine if our integration branch is
gh-pages, simply assuming that if
master exists, then that takes precedence.
git work-on <issue-number> will fetch from origin and branch off from the
<origin/default-branch>. This has the intended side effect, that you track the remote branch default branch - so at any point in your work process a simple
git pull --rebase will keep you in sync.
git addremove takes every change in the workspace and adds or removes it to the index. If you’re familiar with Mercurial Hg, you know the usefulness of this already.
git wrapup is used to automatically
addremove everything and then commit it with a close message - and the title of the issue.
git deliver will simply push your current branch to a
ready/<current-branch> on the remote and then rename your local branch to
delivered/<current-branch>. You might not want to delete your branch just yet, until you’ve seen that it’s successfully integrated.
git purge-all-delivered will remove all local branches named
delivered/** and at the same time remove any corresponding branches you may have pushed to origin - without the
With this set of ingredients we can carry out a series of useful everyday scenarios without even leaving the terminal
In my terminal I can simply run
ghi list --mine to get a list of the issues that are assigned to me:
Then I can run
git work-on 200 to work on this blog post. It will create a branch called
200-Story-on-how-we-work. In fact, I already did, you will see in the picture above that the issue is already marked as work in progress.
If you look at waffle you’ll see that it’s moved to the in progress column.
When I’m done, I simply run
git wrapup. The command will add, remove and commit everything with a comment message in the format
close #200 Story on how we work
When I run
git deliver it will kick off the Jenkins job I have waiting to do the integration. A few seconds later it’s integrated:
In waffle, the issue is automatically moved to done because of my commit message mentioning
And on GitHub issues the log is maintained nicely - even with a reference to the commit I made, and all the various labels being applied:
Ghi supports that you can create new issues locally, right in your editor. All you have to do is run
ghi open. I use Atom as my favorite editor, but for creating issues I like to stay in my terminal, so I have instructed ghi to use nano, simply by adding it to my
.gitconfig like this:
The first line becomes the title and the rest of the file content is added as the issue description. When I close the file in nano, ghi displays the number of the newly created issue:
201 and I can simply continue with business as usual
git work-on 201.
Hack, hack, hack.
Had enough of sluggish polling? With instant Artifactory event triggers you can give responsiveness in Jenkins a real boost. Here’s an easy way to set it up.
A super easy configuration guide
With the arrival of microservices code is becoming disposable. Does this mean that we no longer need maintainable code? Is it the end of refactoring?
Still relevant or increasingly redundant?
In software development tight coupling is one of our biggest enemies. On the function level it makes our application hard to change and fragile. Unfortunately, tight coupling is like the entropy of software development, so we have always have to be working to reduce it.
How to safely introduce modular architecture to legacy software.
I am an Atlassian certified trainer and over the years I have been spending much time with clients and their Jiras. In this blogpost, I have collected some small tips and tricks that will make your Jira usage better.
Jira Software is a powerful tool deployed in so many organizations, yet in day to day usage people are missing out on improvements, big and small.
In this post, I’ll take a closer look at the version of Jenkins X using Tekton, to give you an idea of how the general development, build, test, deploy flow looks like with Jenkins X. How does it feel to ship your code to production using a product coming from the Jenkins community that has very little Jenkins in it?
A crash course in Jenkins X and how to test it out on a local Kubernetes cluster
In this blog I will show you how to create snapshots of Persistent volumes in Kubernetes clusters and restore them again by only talking to the api server. This can be useful for either backups or when scaling stateful applications that need “startup data”.
Sneak peak at CSI Volume snapshotting Alpha feature
When I read Fowler’s new ‘Refactoring’ book I felt sure the example from the first chapter would make a good Code Kata. However, he didn’t include the code for the test cases. I can fix that!
Writing tests for ‘Theatrical Players’
Nicole Forsgren and the Accelerate DORA team has just released the newest iteration of the State of DevOps report. The report investigates what practices make us better at delivering valuable software to our users as measured by business outcomes. Read on for our analysis of the report, and how it can be best put to use.
The latest drivers of software delivery performance
A major challenge of software development is that our work is by and large invisible. This makes our folklore essential in business matters. Some of our commonly used arguments and visualizations are digital urban legends rather than solid foundations for informed decisions. Here, we’ll go through a few examples and some measures to address our misconceptions.
How the stories we tell influence our decisions
When you embark on your cloud native journey there will be important choices to make about cloud providers, continuous deployment, environments’ setup and separation. This guide will help you make the right choices by sharing lessons learnt from running cloud native apps in production.
Kubernetes has become the de facto container orchestration platform. When we help clients of different sizes and domains start their cloud native journeys in Kubernetes, we assist them in making sound decisions and technology choices. There is no one-size-fits-all solution when it comes to choosing cloud providers, CI tools, continuous deployment pipelines etc., so it is important to make the right decisions at the start. Failing to do so can be very costly in terms of lost time and money.
How to make the right technical choices on your cloud native journey
Learn how Docker and Kubernetes work and the key benefits they bring. Using real demos, I show how Docker is a great packaging and distribution technology, and how Kubernetes provides a powerful runtime for containerized applications.
Watch this introduction to Docker and Kubernetes at the Trondheim Developer Conference (TDC)
In the world of Agile and DevOps we use many figures, charts and diagrams to argue and reason about our world and how we prioritize and make choices. However, at all levels of the organization, we misuse and misinterpret figures. It’s time to be explicit, measure the right things and act on them. Watch this talk from DevOpsDays Zurich in May 2019.
Watch this talk from DevOpsDays Zurich
Hear about upcoming events in Scandinavia, latest tech blogs, and training in the field of Continuous Delivery and DevOps