Author Archives: jimblizzard

Code Reviews and fishing

First, a little story . . .

Years ago, before I joined Microsoft, a team at one of the companies I worked for decided to start doing code reviews. This was back before modern IDEs that would show you side by side code comparisons with color highlighting of the proposed changes. And before VSTS which allows you to annotate the code that you’re looking at — add questions, notes, or recommendations about the code you’re reviewing — which is kept as metadata for the code. All good stuff.

So, no, we didn’t have anything fancy, so up front we agreed that we’d print out the source code before the meeting. We’d have to find a spot on our calendars when all ten of us could meet. We’d book a room. Then we’d meet.

The first review was pretty awkward. Nobody wanted to be the first, then Tony relented and agreed to be the Guinea Pig. He printed out his code for everyone, we met in the room, and we all started looking over the code. Things started off OK. There was some nervous laughter, Tony described the section of code we were going to review, and people asked a few questions and made some general comments. It went on like this for several minutes. We didn’t really know what we were doing.

One of the senior people on the team was Steve. He’d had a lot of programming experience, had worked on a number of different systems, and could crank out code. He was also the team lead, and the other newbies and I would sort of look up to him. But, Steve had an especially sharp tongue.

Steve asked a question. “Why in the world did you write your code this way?” Then another. Then made a barbed comment about the code. And another one. During this first code review his questions and comments began to come out as grilling and accusations. He’d say stuff like, “That’s a horrible name for a variable.” And, “I could have written this in half the lines and it would be 10 times faster.”

It went on like this for what seemed like hours. Steve even said, “This is really bad stuff. Why did you become a programmer? How did you get a job here?” I was so glad that I hadn’t volunteered to go first. I looked over at Gregg. He was wincing. Sandy had a look of horror on her face. The others, same. And Tony. Poor, Tony. He was shrinking into his chair.

After about 15 minutes of this, Gregg finally got up the nerve and broke in. “Hey, wow. OK. I think it’s time for a break.” Everyone agreed. We all grabbed our stuff and got out of the conference room as fast as we could.

And we never had another code review.

Culture. . .

Developing software is so much more than language, syntax, patterns, IDEs, and mad technical chops. (Although they do come in handy.) Developing software is more about people. It’s about soft skills, being able to understand and communicate with others. It’s about solving problems.

Developers — even beginning developers — pour their souls into the code they write. They can be passionate about their code. They’re totally invested. It’s their baby, and nobody likes to have their baby called ugly. And nobody wants to be put down or humiliated.

So, some things to think about before the code review. . .

  • What’s the purpose? Why?
  • If the code has some issues, is that a good thing or a bad thing?
  • Is the code review for punishing or for teaching, mentoring? Blaming or training?
  • If issues are found, explain why. Reach an understanding. Teach.
    • What are the consequences of the way the code was written?
    • Help them figure it out. Don’t simply mandate or dictate. Teach them how to fish

Code reviews can be so beneficial to everyone if they’re done the right way. And so harmful if they’re not.

Be kind to each other. Play nice.

Simple things

Was in Olympia most of the week, followed by a night in Seattle. Avoided a long early morning drive to SeaTac. Walking into the DoubleTree saw a stunning tree. Colors that we don’t have in Tampa. Ever.

3AM Pacific Time alarm. Early morning flight back to Tampa. At the airport, breakfast in the Sky Club. Set the food on the table. “Huh. That looks pretty cool.” Happened to be delicious, too.

Saw this during my flight. Looks like I got away just in time.

VSTS–Mac build agent fail restoring NuGet packages

Heads up if you’re running VSTS build agent on a Mac for Xamarin.Forms iOS projects.

You may see this error message from the NuGet package restore step:
”To connect to NuGet feeds hosted in your Team Services account/TFS project collection with NuGet 3.1 or below, edit your build definition to specify a path to a NuGet.config containing the package sources you wish to use.”
And this error message in the agent’s _diag log file on the Mac:
                MsBuild.exe does not exist at ‘/Library/Frameworks/Mono.framework/Versions/4.4.2/lib/mono/4.5/msbuild.exe’.
It’s a closed issue on GitHub, but you’ll need to do a workaround.
See for details. The issue was opened about 10 days ago.
I hadn’t changed anything with my build definition, source code, or build agent, but the build failed this morning. (It had been a couple of weeks since I’d run it, and it had always worked before. Quite a surprise.
I ended up putting this in the VSTS NuGet package restore step and it resolved the issue for me:


Note from Joe Sauve:

You can also use:

Note the “Current” instead of a specific version number. There should be a symlinked “Current” folder in there that always points to the most recent version.

Thanks Joe!


Android Keystore file and password in VSTS builds

I was on site with a client last week working with them on DevOps for Xamarin.Forms builds using VSTS. The question came up of what to do about the Android Keystore file and its password – where to put them, keep them safe, etc.

Keystore file
If you’re running the build agent on a local build server (or Azure VM), the keystore file can be placed in a secure location on the build server. If you’re using the hosted build controller the Keystore file could be put into source control with limited access given to that file.

Keystore file password
For the Keystore file password, create a private variable in the Android build definition . Once the variable is set it cannot be displayed again. Then set the permissions in VSTS so only those who have Build Edit permissions can change this variable, and restrict who you give those permissions to accordingly.

The build step with a reference to the Keystore file in VSTS source control and a variable for the password.

The Keystore password saved as a Variable in the build definition.

Then you’ll need to set the security on the Build itself to limit who is allowed to edit the build definition.



And that’s it. Setting up the VSTS build in this way will keep the Keystore file and password safe in your Xamarin Android build definitions.


Building cross-platform Xamarin.Forms apps in VSTS

The other day I wanted to create a DevOps CI / CD pipeline for a simple Xamarin.Forms app that I’d created. The Visual Studio solution contains project files for the PCL, Android, iOS, and UWP projects. The CI / CD pipeline would include VSTS for source control, build, and release, my Mac for the actual compile and packaging of the iOS app, and HockeyApp for beta version management and beta user management. It’s not that difficult to set up, but there are a few places where it would be easy to get hung up.

For my Xamarin.Forms project I created three VSTS build definitions, one for each platform. This allowed me manage the pipeline for each platform separately. Two separate build agents are required to build the solution. The Hosted Pool and Agents can build for UWP, Android, and a number of other platforms, but they can’t build for iOS. A different Pool and Agent has to be set up for iOS, pointing to a Mac environment such as MacInCloud, or to your local Mac.

The solution in Visual Studio needed three Build Configurations: one for Android (without UWP or iOS), one for UWP (without Android or iOS), and one for iOS (without Android and UWP).

VSTS Agents and Build Definitions

So with that, let’s take a look, first with the VSTS Build setup. . . (FYI, I’m currently not using Release Management to publish the app to HockeyApp. I’m going to add that process later.)

I downloaded an Agent to my Mac and configured it to run using a pool other than the Hosted pool. I chose to use default pool. In the following image you can see that I have a number of Agents defined in the “default” pool. “MIC_VSTS_snow…” is set up to use MacInCloud. The other three point to different Agent configurations on my local Macs. (I’m going to write a future post about how I configured the Agent on my Mac.)


I defined a User Capabilities variable for each Agent so my build definitions could demand which particular Agent to use from the default pool. For instance, I created a User Capability called MacinCloud for the agent associated with MacInCloud. I created a Capability called NewMac for one of the agents that lives on my MacBook Pro.

image image

In the VSTS build definition I added a Demand for “NewMac” “exists” so it will run a particular agent on my MacBook Pro. (You can have multiple agents running on your Mac if you want to, and point to them this way.)


In my build definition I also created a variable called BuildConfiguration so I can identify which which Build Configuration in the VS solution I want the VSTS build to use. (I’ll show those settings in VS in just a bit.)


I pointed the build to my Xamarin project repo and set it to have a continuous integration trigger. In the Build Task I used the $(BuildConfiguration) variable for the Configuration.


I set up the Android and UWP VSTS build definitions similar to the iOS definition. Biggest difference was that I was able to use the Hosted agent.

Visual Studio Build Configuration

Let’s take a look at the Build Configuration in Visual Studio next.

As I mentioned I created three VS build configurations to be used by the three VSTS builds, “iOS Release”, “Android Release”, and “UWP Release”. In the VSTS build definition for iOS above, I used the “iOS Release” configuration. Here’s the definition in Visual Studio. The “XamarinFormsIosAndroid” project is the PCL project, and the “XamarinFormsIosAndroid.iOS” project is, yep, the iOS project. Notice that the Droid and UWP projects are not set to build (checkboxes are unchecked) in this configuration.


For the Android and UWP build configurations I took the same approach: build the PCL project and the .Droid or UWP project as appropriate. Here’s the screenshot for the Android build. Notice that I left the “Deploy” checkkbox unchecked for the .Droid project. There’s no need to deploy it during the Build task in VSTS.


And that’s pretty much it…. at least as far as setting up the build goes.  : )

I haven’t shown it here, but you can add a step for Xamarin Test Cloud (automated testing) and a step for deployment to HockeyApp (for beta distribution and user management). Or even better, create a Release Management definition to handle the deployment to HockeyApp. More about those topics in a future blog posts.


Here are some references you’ll probably find useful when setting up your VSTS builds for Xamarin.Forms.