Thursday, April 30, 2015

How Microsoft blew our minds at Build 2015

Here we are again. After a little detour to QCon San Francisco and New York in 2013 and 2014, we thought it to be about time to rejoin our fellow Microsoft developers here at Microsoft Build 2015 at the Moscone Center in San Francisco. Since we couldn't get a direct flight from Amsterdam to San Francisco, we had no choice to travel over Los Angeles and take a 2015 Mustang Convertible along the Pacific Coastal Highway. Oh well, being a professional isn't always fun.  Compared to QCon, which usually has about 500-600 attendees, Build is huge. We didn't get any official head count yet, but my guess is that we're amongst 2000-2500 geeks here.

After a healthy breakfast of croissants and other pastries (guys…give us some yogurts), we queued up with those thousand others for the keynote. I'm pretty sure nobody really cares about the keynote itself. Most people just like to know what gadget they'll get this year. I'm not saying I wasn't interested in that, but what really blew my mind this year is how Microsoft managed to embrace the things this profession really cares about.


For instance, the number of features that Azure gained over the last year or so is staggering. Look at Docker for example. They showed us an ASP.NET 5 application that was hosted in a Docker container on Windows Server which got Docker support recently, and then switched to Ubuntu to run that same application on Linux. Even better, they demonstrated a remote debugging session from inside Visual Studio connecting to that Docker container on Linux. It's so surreal to hear terms like Docker, Linux, Android, cross-platform and Windows being intermingled on a Microsoft conference.



Other noticeable features of Azure include elastic database pooling using dynamic scaling and sizing by employing Machine Learning. But the mobile telemetry pages provided by the Azure Portal are also pretty impressive. It's like AppDynamics / NewRelic, but then for Windows Phone, Android and iOS. And then there was something called Logic Apps, a very cool cloud-based workflow platform for visually designing business orchestrations where your own (Swagger-enabled) services as well as external parties can be connected together. It's a bit like FFFT or Zapier, but then integrated in the Azure ecosystem.

This entire cross-platform mentality was visible everywhere. Even custom-build add-ons for the next version of Office work everywhere. Whether you run Office on Windows, use Office Online or use the iPad version, it'll work the same everywhere. And think of it, they actually demonstrated an iPad on stage…on Microsoft Build. And now that I mention it, and what really reinforced this mentality, was the announcement of Visual Studio Code, a fully functional IDE for MacOS and Linux, including debugging, IntelliSense and rich refactoring features, all available now!

But, they made sure not to forget the Windows platform itself, and do what it takes to make Windows 10 a big success. For instance, web sites can now be amended with rich Windows 10 integration and then distributed through the Windows Store. The same goes for 'traditional' Win32 and .NET applications. You can package them up, distribute them through the Store and get the same install/uninstall experience you get with those modern apps. And it must really work, because they showed off Adobe Photoshop as a Windows Store app.

So on one hand, they actively embrace the other platforms, but on the other hand they try to convince the developers for those same platforms to join the Windows 10 eco-system. How? By allowing them to compile an existing Java/C++ for Android app into a Windows 10 app from inside Visual Studio! And they don't have to, but they can easily enhance that app to get better integration with Windows 10. Now wait, that's not all. You can similarly compile Objective-C apps and games as well. That sure will solve the app store gap that Windows Phone has been suffering from. Oh, and did I mention that Microsoft's new browser, now officially called Microsoft Edge, supports converting FireFox and Chrome add-ons with ease?

In a way, you can say Microsoft has declared Google and Apple its friends and moved its guns towards Amazon. I call that a significant improvement… 

Thursday, April 23, 2015

Software versioning without thinking about it

Solving the versioning problem
If you're building libraries, products or any other software system, versioning is usually a pretty big deal. It's the only way to determine what version of that library, product or system you're looking at. Before an organization settles on a versioning strategy, many discussions have been held on what constitutes a major release versus a minor release, how to version the component from a marketing perspective, and how to deal with bug fixes. In addition to that, if that software system involves a library or framework, or just component, then you'd be pretty interested to know when an update to that component involves breaking changes.

Fortunately, the open-source community has solved both of these problems for us. First, we have semantic versioning, which unambiguously defines how to update your version when you do hot fixes and patches, minor back-wards compatible improvements or breaking changes. They even define how you should post-fix your version numbers to denote pre-releases and build numbers. Assuming all decent software project are using Git these days, then the other problem is solved by following the GitFlow branching strategy, an initiative by fellow countryman Vincent Driessen. GitFlow describes in detail on what branch you do your main development work, how you stabilize an upcoming release and how you track production releases.

So I'll assume for a minute you are going  to embrace the semantic versioning scheme as well as follow the branching strategy prescribed by GitFlow. Wouldn't it be cool if some kind of tool existed that used the names of the branches and the tags on master (representing the production releases) to generate the proper version numbers for you? Well, once again, the open-source community comes to the rescue. Jake Ginnivan and the guys from ParticularLabs, the company behind NServiceBus, have build just that and named it GitVersion. So let's see how that works.

Showing of the beauty of automatic versioning
First, we need to install GitVersion, which is pretty easy through Chocolatey.

> choco install gitversion.portable

This allows you to run it from the command-line. You can also hook it into your build system by copying the single executable into source control or adding it as a NuGet package. It will detect build engines like TeamCity and AppVeyor and adopt its output. Now let's assume you have a new Git project with a first commit on the master branch:

> mkdir GitDemo
> git init
Initialized empty Git repository in D:/Tmp/GitDemo/.git/

> echo "hello" demo.txt
> git add .
> git commit -m "My first commit"
[master (root-commit) 2a34238] First commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 demo.txt

Now run the GitVersion command-line tool

> gitversion

This will result in the following JSON output:

{
  "Major":0,
  "Minor":1,
  "Patch":0,
  "PreReleaseTag":"",
  "PreReleaseTagWithDash":"",
  "BuildMetaData":0,
  "FullBuildMetaData":"0.Branch.master.Sha.2a34238911a4b47ec4b8794e27cd69c5857cb12a",
  "MajorMinorPatch":"0.1.0",
  "SemVer":"0.1.0",
  "LegacySemVer":"0.1.0",
  "LegacySemVerPadded":"0.1.0",
  "AssemblySemVer":"0.1.0.0",
  "FullSemVer":"0.1.0+0",
  "InformationalVersion":"0.1.0+0.Branch.master.Sha.2a34238911a4b47ec4b8794e27cd69c5857cb12a",
  "ClassicVersion":"0.1.0.0",
  "ClassicVersionWithTag":"0.1.0.0",
  "BranchName":"master",
  "Sha":"2a34238911a4b47ec4b8794e27cd69c5857cb12a",
  "NuGetVersionV2":"0.1.0",
  "NuGetVersion":"0.1.0"
}

So, by default your version numbering starts with 0.1.0. Notice the many variables targeted to specific uses. For instance, we store the InformationalVersion that includes the hash of the commit in the AssemblyInformationalVersion attribute of the assembly. Similarly, we use the NuGetVersion for our NuGet packages. Finally, our build numbers are mapped to the FullSemVer variable. That last part is pretty important, because traditional build numbers don't say much about the actual changes. With Git versioning, rebuilding a particular commit renders the exact same number. This creates a whole lot more tracability.

Let's follow Gitflow and continue development on the develop branch and run GitVersion.

> git checkout -b develop
> gitversion

Ignoring the remainder of the variables for now, this is the result:

  "FullSemVer":"0.2.0.0-unstable"

You'll notice two things. First, the minor version number is automatically updated. Second, the version number is post-fixed to make it pretty clear your working a development branch. Now let's add a couple of commits and see what happens.

> echo "test" > demo2.txt
> git add .
> git commit -m "another commit"
> gitversion

This will result in the last digit representing the number of commits since we branched of from master.

"FullSemVer":"0.2.0.1-unstable"

So let's work on a little feature through a feature branch.

> git checkout -b feature1
> echo "test2" > demo2.txt
> git add .
> git commit -m "another commit"

Running Gitversion again will give you:

"FullSemVer":"0.2.0-Feature.1+1"

And again it's crystal clear what version you're working on. To simulate working on some feature, I'll assume a couple of more commits without repeating myself here. Running GitVersion after those changes results in:

"FullSemVer":"0.2.0-Feature.1+4"

Now it's time to integrate those changes back into the develop branch.

> git checkout develop
Switched to branch 'develop'

> git merge feature1
Updating eb79902..8c374d1
Fast-forward
 demo.txt  | Bin 0 -> 16 bytes
 demo3.txt | Bin 0 -> 14 bytes
 demo4.txt | Bin 0 -> 14 bytes
 3 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 demo3.txt
 create mode 100644 demo4.txt

> gitversion
"FullSemVer":"0.2.0.5-unstable"

So, whatever you do, the version is always in sync with the changes without any manual tasks.

Now suppose principal development has completed and it's time to stabilize the code base. Let's make that explicit by starting a release branch.

> git checkout -b release-1.0.0
Switched to a new branch 'release-1.0.0'

> gitversion
"FullSemVer":"1.0.0-beta.1+0"

So it seems release branches are not for shipping release versions. Instead, they are used to ship beta versions of your system. Again, the +0 is used to denote the number of commits since the last time you shipped a beta package. Consequently, if you do ship such a package, you're supposed to tag that commit with something like 1.0.0-beta.1. When you do, and you add any additional commits to that branch, the following happens.

> git tag 1.0.0-beta.1

> ..make some changes

> git commit -m "some more changes"
[release-1.0.0 76682ac] some more changes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 demo5.txt

> gitversion
"FullSemVer":"1.0.0-beta.2+1"

As long as you're stabalizing a system or shipping intermediate versions for acceptance testing or similar situations, stay on the release branch. By doing so, you can support both the upcoming version as well as the current production version. Now, when you're ready to go into production it's time to merge to master.

> git checkout master
Switched to branch 'master'

> git merge release-1.0.0
Updating 2a34238..76682ac
Fast-forward
 demo.txt  | Bin 0 -> 16 bytes
 demo2.txt | Bin 0 -> 14 bytes
 demo3.txt | Bin 0 -> 14 bytes
 demo4.txt | Bin 0 -> 14 bytes
 demo5.txt | Bin 0 -> 14 bytes
 5 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 demo2.txt
 create mode 100644 demo3.txt
 create mode 100644 demo4.txt
 create mode 100644 demo5.txt

What's important to remember is that you should tag the commit you ship, so in this case we're going to tag the merge result with the final release number. Let's see what GitVersion will do with that.

> git tag 1.0.0
> gitversion
"FullSemVer":"1.0.0"

This marks the end of the development cycle. Any hot-fixes should end up on master as well, and will have their last digit incremented, e.g. 1.0.1, 1.0.2. Any successive development should continue on develop again, so as a last step, let's switch back to that branch and see what happens.

> git checkout develop
Switched to branch 'develop'

> gitversion
"FullSemVer":"1.1.0.0-unstable"

Nice isn't it? GitVersion understands the concept of that tag on master and will assume you'll continue with the next minor version on the develop branch. If you really want to continue with a different version, there are ways to make that happen. And I've been just showing you the most common flow. I highly recommend checking out the examples in the GitVersion wiki.

In summary
In short, you just need to remember a couple of things:

  • Development happens on the develop branch
  • Stabilizing upcoming releases and shipping beta packages happens from release- branches
  • The master branch tracks production releases and hot-fixes.
  • Anytime you ship something, you must tag that commit. No need for tracking releases anywhere else.


So what happens if you don't have regular releases and your project needs to deliver continuously? Well, the guys at Github had the same questions and came up with an alternative to GitFlow called GitHubFlow. Fortunately, GitVersion supports this flow out-of-box as well.

So what branching strategy do you use? And how do you track your releases? Let me know by commenting below or tweeting me at @ddoomen.

Sunday, April 19, 2015

Prioritizing projects and tasks with minimum loss of time and money

Last week, I was so fortunate to attend a marvelous talk by Donald Reinertsen on a amazingly effective approach for prioritizing projects within an agile organization (and which is part of SAFe). Most managers will tend to prioritize their projects based on non-quantifiable attributes such as the strategic importance of a project or the risk of loosing a contract. But if you have a multitude of those projects, all equally important, how do you make a decision on what project should be done first? In his opinion, prioritization should happen on a principle named Weighted Shortest Job First. In this principle two figures are of upmost important:

  1. The duration of the project
  2. The cost of delaying that project

By dividing the former by the latter, you get the weighted value on which you prioritize. Consider for example three projects, A, B and C, all with the same cost of delay but with varying lengths. If you would put them on a graph like the picture below shows, it becomes pretty obvious which project should be done first. So although my first instinct would be to try to get that big project out of the way first, that's actually the least economical thing to do. And it doesn't matter whether you define your units in weeks, months, story points or cows, as long as you don't compare apples and oranges.

clip_image001

Now how do you deal with those strategic projects I started this post with? You still need a way to quantify those. One way is to try to estimate for how much money completing such a strategic project will enable other projects. Another possibility is to ask the involves stakeholder on how much money he or she is willing to pay for the advantage of starting this project first.

And what about projects you really can't predict the length of? Well, in that case, Donald recommends allocating fixed chunks of capacity to a project. When that chunk of capacity expires, you simply put that project back in your queue and reprioritize. This might work particularly well with technical innovation projects where you need a couple of those chunks to be able to reliably estimate the remainder of the work. And guess what you need to do when you have that information…

So, one particular question I tried to get an answer on is how this all applies to user story prioritization. Over the years, I have had many discussions on stories needed to bring down technical debt or architectural changes needed to handle non-functional requirements. Quite often, and despite of my efforts to convince the product owner of their value, I get overruled and other features get priority. By trying to estimate the cost of delay for those technical stories as well as their length and comparing those to the weighted values of the functional stories, you might make a better chance of convincing the product owner. You could even use this within the team to help determining whether taking a shortcut is worth the trouble to meet a deadline early. I haven't tried this myself, so I don't know if this would really work, but I'm sure going to try that soon. Anyway, if you want to learn more about the scientific aspects of this technique, I recommend reading the original article on the SAFe website.

So how do you do prioritize projects, tasks and technical debt? Let me know by commenting below or tweeting me at @ddoomen.

Monday, April 06, 2015

How to do a tech talk without utterly boring the audience

Over the last year or two I attended numerous sprint demos, product demos and technical talks hosted by technical teams and individuals. Although I can definitely improve as a speaker myself, standing at the side-line and observing other speakers have made me pretty opinionated. I also get bored pretty easily and have a very short attention span, so the things I'll be saying might not be applicable to everybody. So with this disclaimer out of the way, let's see what you can do to prevent people from getting bored to dead….

Adapt to your audience
Most experienced presenters know that they have to think about the intended audience when they create the slides and presentation structure. But I barely see people adopt their presentation style, their vocabulary and slides they really show to the actual audience. Sprint demos tend to attract a variety of people, so be prepared to change what you were planning to demo based on that. Don't bore that product owner or COO with technical terms or the number of story points you've finished. Just skip those slides if you feel nobody cares about them.

Don't read from your slides

The best thing you can do to move away any attention from you is to put lots of text on your slides and read from it. But if you want people to listen to you, keep them as empty as possible. Ideally, you don't have slides at all (if you've ever attended a Dan North session, you'll know how powerful that can be). I need my slides to keep some structure in my talks, so I prefer to use just keywords and tell my story around them.

Don't try to impress the audience with loads of little things

Pick a couple of features that you think will interest the actual audience or are interesting for the people represented by the audience. Don't demo or name all those little features nobody really cares about. Just invite them to join you after the meeting or visit you at your work place instead.

Cut of any discussions not relevant for the rest of the audience

In every demo, you'll find somebody that likes to profile himself by asking lots of questions and making statements about what you could or should have done instead. Unless you really believe the rest of audience is interested as well, cut of that guy gracefully by proposing to discuss his point after the demo. The reverse is also pretty common; the guy doing the demo taking the opportunity of a question to show off how much he knows or how difficult it has been been to complete a certain feature. Although some of that might include a couple of valuable lessons, don't forget that the audience is there to learn something, not to see how great you are.

Prepare your demo environment

If you need to demo an app on a mobile device or a tablet install some kind of screen sharing functionality, so you don't have to ask hordes of people to look at a little device. Likewise, if you need to use a remote desktop session to demo something, make sure you create shortcuts that automatically connect and logon using the correct credentials. Don't let people wait until you've found the right machine and have them see you filling in the credentials wrong a couple of times. If you demo something using an IDE such as Visual Studio, hide all unnecessary toolbars, tool windows, etc. to allow people to focus on one thing. Oh, and please hide your start menu as well.

Don't touch that freaking mouse

If I had to name the single most annoying thing I see people doing is moving the mouse using the laptop's track pad. No, scratch that. The most annoying thing is people moving the mouse in an erratic pattern, revealing the presenters lack of preparation or their nervousness. So, unless you really need to show the audience what you're doing, remember keyboard shortcuts and ditch that mouse. But….if you really need to use that mouse pointer, bring a real external mouse. And never ever use a trackpad…..ever….

Avoid the sound of silence

If I've ever experienced a cringe-making moment while attending a talk, it must be that moment where the speaker ran into an issue with his demo and the audience of 70 had to go through 5 minutes of total silence. I felt so ashamed for the guy, I had to restrain myself from breaking the silence with some (bad) jokes. Having a technical problem or forgetting what you were going to tell now is something that happens to everybody. Just don't make it too big of a deal and avoid the silence. Explain what you are doing or make a joke about it. Humor is in my opinion the best you can do at that point, especially if it's self-effacing.

Size does matter

Sure, that tool or IDE looks cool on a HD or HD-ready projector, but don't expect people to be able to read those tiny lines of code. So please crank up the font size to 13 or 14 if you want people to be able to read your code. The same goes for your slide deck. If you need a small font size to get all that content on your slide, you must have violated tip 2. Oh, and don't forget to be prepared to change your color scheme. Although your slides may shine on your expensive display monitor, they may get unreadable on a projector. I've made this mistake myself a couple of times, especially when the company I was visiting thought projecting on a wall was a good idea…

Don't bother people with your personal life

No, I'm talking about those cute pictures of your kids… That might actually work to connect to your audience. No, what I am referring to is all those notifications that appear while you do your talk. Do you really want to let the audience see that email your wife just send about her 'plans' for tonight's date while the kids are out of the house? Or worse (but less likely in a sprint demo), having somebody you follow on Twitter tweeting about the worst sprint demo ever. So enable Presentation Mode or whatever it is called on your platform to prevent any notification for an hour or so. As a nice side-effect it will also prevent the screen from going into your screensaver.

Delegate note taking

The most unprofessional thing to do is ask people for feedback during a sprint demo or discover problems in whatever you're showing and have those same issues or questions appear in the next demo. So make sure you ask somebody from your team to actively take notes about product issues, unanswered questions or anything that needs improving the next time you do your demo.

Now let's hope I don't violate any of these myself the next time I do a demo or talk….

So what do you do to make your sprint demos shine? Let me know by commenting below or tweeting me at @ddoomen.

Wednesday, April 01, 2015

Getting your teams to communicate effectively

Lets be honest here. For a very long time, if I had to choose between an averagely skilled but well-spoken developer and a very skilled and experienced introvert, I would probably choose the first. And yes, I do realize that these are two extremes and that most people have characteristics of both. So please don’t flame me for saying this. Nonetheless, I (still) believe that multi-disciplinary agile teams need to foster open communication. In such a setting, you just can't work in isolation that long. XP practices like pair programming and swarming on stories is the common thing people do.

Consequently, having somebody in the team that has difficulty expressing him or herself in Dutch or English can be considered as a impediment. But before I'm going to talk in solutions, let me share some of the symptoms I've observed first hand.

Communication Impediments

I think many experienced scrum masters will recognize this, but when I was still part of a Scrum team, we regularly had retrospective and sprint demos. Somehow, the same people were either always speaking or always silent. Even tricks like brain storming using post-its and dot voting didn’t seem to give the result we were hoping for. Some of the more quieter persons simply didn’t participate. If you would be really lucky, those guys would send you an email with their feedback afterwards.

Another issue I've seen happening in multiple teams is developers shutting themselves off by using headphones. I don't really mind headphones and I understand that some people simply don't switch their attention that easily. But in my experience, the people that do tend to wear headphones, are also the people that are least involved in team discussions. I've noticed several situations in which some team members were discussing a certain topic in an ad-hoc fashion with the guy wearing headphones completely oblivious of this. Sure, the guys in the discussion could have asked the headphones guy to get involved, but they might not think he or she would have anything to add or they simply don't want to disturb him or her. Either way, unless the headphones guy is very perceptive of what's happening around him, I would recommend against headphones at all.

I myself am very sensitive to people that don't share their progress pro-actively. It might be my tendency for over-understanding what's going on, but somehow I tend to have more trust issues with people working from home if they don't actively share what they are doing. In my opinion, it should not matter whether you're working from home or at the office. The difference is that your team can't tap you on your shoulder if they need you, so you need to compensate for that.

A final impediment that I've observed first-hand is that developers that have difficulty expressing themselves are often overruled by product owners, business people or more senior developers, even though their point is very valid. For the bigger part of my career I would treat people like that as irrelevant and kind of walked over them. I've even been reprimanded for that at some point. However, over time I've learned that giving them more room to make their point can result in much better solutions in the long run. And not only that, it will most definitely improve your professional relationship. However, not everybody is aware of this or has the patience to give the other guy some slack. Hey, even with this knowledge, I still have days I simply can't make myself patient enough. So in a way, I still see this as an impediment for effective collaboration.

Based on these experiences, you might be tempted to take the easy road and only select developers with great communication skills. But over the last year or so I've learned that some colleagues just need a different means of communication. It might require a bit of patience, but if do give them room enough, they might surprise you with great solutions, ideas and feedback. They sure managed to surprise me on more than one occasion. In retrospective, I was just plain wrong in my assumptions. In fact, my wrongness was the primary reason for writing this post in the first place.

Tips that can help

Now that I've cleared the air, let's see what you can do to improve on this.

  • Use a chat tool like Flowdock, Hipchat or Slack to have discussions about certain topics. You'll be surprised of how people change when they have time to put their thoughts together without the pressure of a face-fo-face discussion.
  • Invite people for certain tasks by email or Flowdock. Where they might not respond to a public invite, e.g. during a meeting or stand-up, they might turn out to be very eager if you approach them 'digitally'. Happened to us many times.
  • Try alternative techniques for retrospectives. Just doing a round table inquiry about the good and the bad isn’t very effective. I particularly like Sandi Mamoli’s Deep Tissue Massage Retro and the 5-Why Root Cause Analysis Retro.
  • Have one-to-one meetings before or after that team retrospective to make sure his or her feedback is listened too. Since I can be pretty direct sometimes, meeting up with individual colleagues in a private meeting helps create a better environment for a respectful conversion.
  • Set-up a pairing station outside the vicinity of the team. This allows two developers to work together and have discussions and ask each other questions without the whole team overhearing them. That might give an insecure developer just enough confidence to ask the right questions.
  • Try to create a couple of tasks for those developers that just don't work well with other developers so that you can still benefit from his or her unique skill set. I know that doesn't align well with multi-disciplinary teams swarming on stories, but sometimes thinking outside the box is worth the trouble.
  • Speak in a common language, even if the people involved in the discussion were not planning to include anybody else and speak the same language. They might not even realize the other guys have something valuable to add to the discussion. We have mixed Dutch and non-Dutch teams and we don't force people to learn Dutch. So in our case, I recommend teams to speak English at all times. If you don't, you'll never give the other guys a chance to join in on the topic.
  • When working from home, actively share progress, e.g. by email, but preferably through Flowdock, Slack or Hipchat. It will increase the trust levels within the team. If I look at myself, when I work from home, I start to over-share what I'm doing and make sure the threshold for getting in contact is as low as possible.

Those are plenty of examples that I’ve seen in action, so I hope this helps. But regardless of how you approach your team members, don't forget the fundamental principles of effective communication: safety, respect, ownership and intention.

So what do you do to improve the level of collaboration between team members and teams? Let me know by commenting below or tweeting me at @ddoomen.