Developer 0.0

The successful warrior is the average man, with laser-like focus.

–Bruce Lee

Why?

Last December I did a presentation on Netponto, a Portuguese .Net user group. It was a very atypical presentation for me, since it had zero technical content.

The presentation served several purposes (and different objectives). First it was meant to fulfill a promise I had made to Caio Proiete that I would do another presentation at a Netponto meeting. That was the first part of the promise, the second one, was that I would do an offensive presentation which would lead to no further invitations for talks (both a promise and an objective Smile). Thirdly it was a presentation that I wanted to do for a long time (with perhaps opposing motivations).

The talk was simply named Developer 0.0, it starts with the basic premise that we (as developers or an industry) are viewed as fungible assets.

Justly or not, it is a perception that we deserve because it is something we have positioned ourselves into, with our practices and attitudes.

Perhaps we do have a tendency to place ourselves into rat holes, that is certainly one of the reasons why we are viewed the way we are, we tend to fixate on the problem solved and in the end we lose sight of what the problem is and why we are solving it. But it’s not the only reason.

We tend to see software development as coding practices, patterns and programming languages syntax. We close ourselves into our on domain when we should me more multi disciplinary, there are a lot of problems that have been solved hundred years ago by other disciplines, we just don’t look at them or dismiss them as not important.

In this presentation, I try to argue that developers can only change this, if they change their posture by following some rules/principles. I say developers, but I think this could be adapted to almost any other profession, since most of them are not specific to our industry (but seems very prevalent).

Common sense is the most fairly distributed thing in the world, for each one thinks he is so well-endowed with it that even those who are hardest to satisfy in all other matters are not in the habit of desiring more of it than they already have.

– René Descartes

Some people would say, these are just common sense. Perhaps they are, but common sense seems to be been abused to a point, that is almost useless to use as an arguing point. Smile

I opted for an offensive and provocative attitude by trying to show that we normally have a posture that doesn’t bring us any benefits (on the contrary) and try to question why such practices are widespread, specially since I wouldn’t tolerate them if they were imposed on ourselves by other people.

As to dancing, my dear, I never dance, unless I am allowed to do it in my own peculiar way. There is no use trying to describe it: it has to be seen to be believed.

–Lewis Carroll

The meeting organizers didn’t had a clue about the content of the presentation. I only shared the title and no abstract (and yet I had an audience. Probably because they didn’t knew what they were coming for Smile which was the point of not having an abstract).

In the end the presentation generated much more debate than I had anticipated and most people said they weren’t insulted and were expecting me to be much harsher. (to my dismay and disappointment Smile)

The  Content

The content the combination of three things: wishing, my failures and for (my) future reference.

Life itself is your teacher, and you are in a state of constant learning.

–Bruce Lee

By wishing, I mostly meant these are things I wished I was taught a little earlier (instead of learning it the hard way), I think these should be taught straight out of college (heck I think this is High School material) in facts it’s the theme of the whole presentations, these are the things (not all since I have material for at least one more presentation perhaps two) that all developers should master before they are allowed to even touch a keyboard.

They are also a reminder of my own failures, failure to apply some of these principles (due to ignorance), failure to apply them due to inability and/or lack of mere tactical reasons when strategically it made totally sense (let’s call it management debt).

In Jeet Kune Do, it’s not how much you have learned, but how much you have absorbed from what you have learned. It is not how much fixed knowledge you can accumulate, but what you can apply livingly that counts. ‘Being’ is more valued than doing

– Bruce Lee

And specially to serve me as future reference for the road ahead. To keep me on the path and avoid the pitfalls of the past.

These views may represent (or not) best practices, economical,political ideology, human behavior observation, societal organization or just a cynical view of the world (take your pick), but the fact as humans tend to organize as a society at the end of the day, it will all come to Thomas Mann phrase “everything is politics”.

Regrets

If I had to present it again,I would remove just one slide (I regretted having that slide the moment I’ve seen it on the projector Sad smile ) slide 41 with the title “A evitar”  (~minute 54) . Which contains the traits we should avoid while hiring someone.

It has too much personal opinion (although it is clearly stated as so) in hindsight it seems too personal and even a little disrespectful.

Just have only kept myself to (fact based) opinions (still opinions, but more defensible).

In a nutshell

Use only that which works, and take it from any place you can find it.

– Bruce Lee

If I had to summarize the presentation in a few bullets, I guess this is how I would do it.

  • What is the purpose of software
  • The reality of software development
    • Incapacity to deliver on schedule
    • Incapacity to deliver on budget
    • Incapacity to deliver what the business needs
  • Why do developers exist?
  • Being a commodity VS delivering value
  • The costs of context switching
  • Opportunity costs
  • Don’t follow the trends just because….
  • The theory of comparative advantage
  • Understanding context
  • Accountability

Watch it

If you have one hour and thirty seven minutes to spare the video of the presentation is now available (the presentation is about one hour. The rest is just discussion with the audience).

The presentations is in Portuguese. The dim lighting, the quality of the video and the sound are not my responsibility. The rest of the crap are my responsibility (the questionable content, the bad jokes and my humpty dumpty stage presence (really need to work on that)).

The video is now public

 

The presentation can be seen here (full fidelity)

 

or on Slideshare which tends to corrupt the animations

On Founder Mistakes…

 

This post is not technical. If you are looking for technical content post then you might skip this one.

goodchoicebadchoice

Recently my former business partner Bruno Camara (I say former because we no longer own any shares of the company we the company we  co-founded (a Portuguese consultancy shop focused on Microsoft products) ) [re] started blogging.

When we started the company (8 years ago), we knew it wouldn’t be an easy task. Specially in a country where those who succeed are not viewed with pride but with envy, whose success has surely arrived due to luck,scams or some shady patronage. Work, talent or risk taking are variables that are never considered to be part the equation.

When I, and my co-founders, founded Agilior, we did an exercise where each one had to describe the reasons (personal or professional), for starting our own company. In my case, there were basically two main reasons.

I really have no recollection what I’ve wrote in the first exercise Bruno mentioned (actually that was the second exercise, we did another one first but that is a story for another time), but it probably could be summoned in a single and very simple sentence “To have fun”. But I’m already digressing…

After the customary introductory post, he went for the jugular and wrote a post about the biggest mistake he ever made as a founder.

I’m not exactly sure if he wrote it for cathartic reasons or merely trying to seek redemption from his (alleged) sins. Smile

I’m neither in position to provide therapeutic help nor absolution <g>, however I can expose my take of the described event and move up the stakes with a bigger mistake.

First of all, the “mistake” (like all mistakes we did) doesn’t has any ownership (the motivations might have been different, but the decision has been jointly made). When you run a company in co-ownership (doesn’t matter the proportions), after the fact has been consummated it doesn’t really made who had the idea, was the bigger or smaller proponent (or even opposed). Once a decision has been made (it doesn’t really matter if you _were_ against or in favor), it’s made and it’s a joint decision; it should be pushed as hard as it can by everyone no matter who had it or fomented it.

This should be lesson number one when running a company, it will save a lot of grief, infighting, waste of energy and resentment down the line (which is probably the most wasteful sentiment there is). But this is surely a mistake we _never_ made.

From the beginning we always viewed mistakes, not as a negative but as a positive thing , as long as as the following premises were true

  1. Making mistakes, it’s a sign you are doing something. The only person who doesn’t makes mistakes is the one who does nothing (which paradoxically is the biggest mistake of all)
  2. Make sure a mistake is not the last one. Fail (preferably fast) but make sure it’s not the last one and you live another day (to make more mistakes Smile)
  3. Mistakes HAVE to serve as a teaching experience, to err and learn from it should the. To make the same mistake twice is tragic.

From inexperience and natural exploration of new territories, mistakes are bound to happen. Obviously they are a thing to avoid, for that you should try learning from the experiences of others so you don’t have to make them as well (to paraphrase Newton  “try to live on the shoulders of giants”).

Some mistakes have to be made on your own, they are a fact of life, so you better learn from them.

(Amber Rae argues that failure is the path to mastery)

With this in mind I wouldn’t say the referred mistake was the biggest one we made (on this particular case relying on wishful thinking,not putting in writing some of the goals/objectives and the consequences of not meeting them were surely among our biggest mistakes, but not the decision itself). It has been a life lesson, which I happen not to repeat again.

We made some mistakes (not a single fatal one and not an awful number of them) but we also had a lot of good decisions. In hindsight we probably had more good decisions than bad ones.

But since we are talking about mistakes, we had a bigger one. (the biggest one). One that was big enough to haunt till this day.

It has been clear from the start that we needed to have processes and metrics to evaluate progress and objectives, if we wanted to grow & scale . Either you are starting a lifestyle business , a startup that will grow exponentially and wants to change the world or something in between; a process is fundamental. Unless you want to end up managing the growth pains instead of focusing on your business.

And this was (what I consider) our biggest mistake. Although we knew this, and implemented most of them from the starte, we failed the in what should be simplest part of the equation. The human one.

Perhaps we drank the Agile kool aid in excess or just made a too loose interpretation of some parts, perhaps we believed too much in the human nature or it was just wishful thinking (or I’m wrong and life has made me a cynical person).

Once we realized the mistake, it was practically unfixable. Like trying to close Pandora’s box or putting back the worms in the can, you can do damage control and try to mitigate it, but to reverse it required measures we didn’t want or simply couldn’t take.

Our biggest mistake was not setting clear expectations and not implementing up accountability mechanisms for the people we that worked with us. This was probably due too much wishful thinking, believing too much in human nature and relying on people maturity and waiting for them to right thing.

Probably due to the fact that’s not our nature to work in a command and control manner and my belief that people should do things because it is intrinsically right and not because of fear or extrinsic reasons. In hindsight more transparency would probably have helped (but would not be enough), but failing to implement these two things have been probably our biggest mistake, something that would too hard to revert once a certain culture has been established and too ingrained almost as if it was part of the DNA.

In hindsight it’s even more tragic, since I’ve always considered myself more as an Hobbesian, than on Rousseau camp. Betrayed by wishful thinking (oh well, never again, at least until the next time Smile)

To summon it up the mistake was not, not going into a top down command and control approach, it neither was our nature and we intuitively knew command and control wouldn’t scale. We did the right things and the ideas were right (I would do it again) it’s just that the execution wasn’t adequate.

My Blogging in 2011

 

Lately I haven’t had the time to blog, so I thought I could wrap the year with some of (my) blogging from 2011. A kind of retrospective

March

Restarted blogging (third round) on this domain with the Bootstrapping my blog. Round III post

April

Visual Studio and TFS Books. if I wrote this today I would necessarily have to add Agile Software Engineering with Visual Studio: From Concept to Continuous Feedback (you can read my review on Amazon) and probably Professional Scrum With Team Foundation Server 2010 (which I haven’t read)

Organizing your build definitions in foldersA great team explorer addon to allow you to view your build definitions in an hierarchical manner. A must if your team projects have a medium to high number of build definitions.

Improving Visual Studio source offline support with TFS Some nifty Visual Studio addon to allow you to put TFS in offline mode without having to restart Visual Studio

OData Service for Team Foundation Server 2010: Beta now availableWrote about the OData Service for TFS. Since version 1.0 has been released.

Getting updated info on TFS and Visual Studio with little effortHow to easily get up to date information and Visual Studio and TFS for people with little time

TFS and Windows Phone 7  and TFS Phone Explorer. Another TFS client for WP7Two WP7 clients for TFS. Since two new clients have been released ThinFS and TFS On The Road (haven’t tried them).

Controlling Lab Management VM Placement Policy  How to change the way Lab Management decides which machines will host the VMS

Getting Visual Studio installation directoryHow to get the installation folder for several Visual Studio versions

Getting Visual Studio version of a Solution fileHow to determine the Visual Studio version that created/can open a given Visual Studio solution file

These last two posts, were written to document some little info that I would later use on a Community TFS Build Extensions activity for building code with devenv. I thought this was of little interest but worth documenting. Quite to my surprise, everyday someone lands on one of these posts through search engines. Looking specifically for these info.

MS Test Manager– Registering why a test is blockedHow you can declare in MS test manager that a test is blocked and why it is blocked.

May

Look the good news that MS Teched US is bringing us for Visual StudioWhen the news about Visual Studio dev11 were still scarce, some news were announced at Teched US.

TeamCompanion 4 has been releasedAnnouncing version 4 of Team Companion. The best way to interact with TFS using Outlook. Meanwhile version 4.1 , 4.2  and 4.3 has been released.

Help Improve Visual Studio performanceHow to help Visual Studio team to improve it’s performance by installing an add in. This is no longer necessary, since then the team already collected enough information, and it has been used to add performance gains to dev 11.

Test Manager fails to load after installing Test Scribe – If Test Manager no longer loads after installing Test Scribe, this is how you can fix it.

June

My upcoming talks for June – Some public presentations I was going to do in June.

ALM Rangers shipped Lab Management Guide and ALM Rangers shipped Build Customization Guide

Node.js on Azure or the importance of knowing history – Some mini rant (minus the rage Smile) and a swim down memory lane. With a lot of people buzzing on running javascript on the server as if it was some grand novelty. IIS supports if for well over a decade. Smile

July

Give Feedback to the Visual Studio Team – How you can (in even more ways) give feedback to the Visual Studio team in order to influence the things that get implemented in the product. (still valid today Smile).

August

Team Foundation Build: Enhancing the experience with built-in custom editors – How you can improve Team Build usage with little effort by using the built-in editor for better data editing (eg: source control picker to easily enter a file in source control).

Team Foundation Build: Reducing the amount of log of your own activities calls – How to fine grain the amount of logging when customizing/writing a build template definition.

September

Meanwhile… – While everyone was busy downloading the Windows 8 preview from Build I was busy downloading the dev11 preview. Smile

Community TFS 2010 Build Extensions–September Release – In September we had a release of the Community TFS Build Extensions. A bunch (bunch is an understatement they are over an 100 probably) of activities for Team Build. In December we were also greeted with a new release which shamefully I haven’t blogged about. The December release also moved from the activities only foray and has added Community TFS Build Manager which is a wonderful tool that will allow easier management of your builds. (for example the ability to see all running builds on your controller(s) which right now it’s not possible in Visual Studio and you had to resort to a power shell script to do it).

October

Team Build: Building code with Visual Studio – How to build code with devenv if you have project types that are not buildable with msbuild. This was the post that explained the activity that I’ve build and has been included in the Community TFS build extensions.

November

Using Team Foundation Server Registry–Part I The concepts and Using Team Foundation Server Registry–Part II the API – How to access the TFS registry (read,write and manage permissions) and how you can leverage this in Team Build by using an activity that has been included in Community TFS build extensions.

 

This has been my 2011 blogging. A total of 29 posts

Team Foundation Build: Sharing parameters between several build definitions

 

Team Foundation Build provides us with a nice editor where we can define parameters (both at design time and queue time) to influence the behavior of our builds and it is really easy to change them.

However sometimes we need to have a parameter shared across several build definitions. Using out of the box features we are forced to place the same value on all build definitions and if we wish to change the value we have to manually change all of them (we can always write some one off code that will replace the value in bulk).

If we want to share a parameter value across more than one build definition we have several choices at our disposal

  1. “hard code” the value in the build definition template, and when we need to change the value we just have to update the build definition template once. Simple, effective but not very visible since the value is hidden inside the build definition (not to mention it cannot be easily changed by non-power users)
  2. Store the parameters in a file stored in source control (for example an XML file or a file with an easy to manage format using a simple text editor). This way when the configuration file is changed every build definition that uses will pick it up immediately. This requires that you change your build definition to get the file from source control (you can use the built in activity DownloadFiles) and read the parameters from the file. This also has the traceability advantage  (by having the parameters stored in source control, we have history, auditability and the ability to easily revert to previous versions).
  3. Store the configuration an a SQL database. For this you can write your own activity or use the SQL Server activities from the Community TFS Build Extensions
  4. Store the configuration on an external system accessible via Web Services (WF has built in support for this)
  5. Store the configuration in the TFS Registry, I’m not talking about the windows registry. I’m talking about the TFS registry, which is a feature that allows you to store settings (in a hierarchical manner) on a registry. There are two scopes for the registry, a collection registry or a server wide registry (also known as the configuration registry). The advantage of the registry is that it’s stored within TFS. Everything is integrated, when the database is backed so are your settings, everything is self-contained. The disadvantage of this approach is the fact there are no tool (out of the box) to read and write settings into the registry.

This post is all about option 5), to read values stored in the registry from your own build definition templates, you can use an activity that I’ve just committed to the Community TFS Build Extensions. The activity is called GetValueFromRegistry

SNAGHTML42e8aec4

To use the activity all you have to do is drag it to the canvas and provide two parameters (one of them being optional).

image

The Path parameter is mandatory and represents the path of the value you wish to read (for example TFS email notification address (if notifications are enabled) is stored in /Service/Integration/Settings/EmailNotificationFromAddress)

There are no rules regarding the use of paths, but it is wise to use a convention (but using /Configuration or /Service is not recommended).

You can use for example /Extensions/<CompanyName>/  as the base path for all your key values.

The  Default Value parameter contains the default value that will be returned if the value is not defined (or if the user doesn’t have permission to read it).

The registry value or the default value will be returned on the Result parameter.

All parameters (including return) are strings.

Please notice registry reading as a little quirk. If the user doesn’t has permissions to read a given value no error will be returned, but no value will be returned either. So if the build user doesn’t has permissions to read a given value it will return the default value (or an error if no default value has been defined, see error below). Which means the build may fail if you can’t read a value and if have set the FailBuildOnError parameter to true.

image

The activity will first attempt to read the value from the collection registry, if no value is found then the server registry is attempted and if not found it will returned the default value (if defined).

Note: this activity is not yet available on the latest released version (v  1.1 released on September 2011), so if you want to use it you will need to download the source code and compile it yourself or wait for the next public release (v 1.2) that is scheduled for December

If you want to learn more about the TFS Registry, some of its semantics and how you can store values on the registry you can read more about on these two posts:

Using Team Foundation Server Registry–Part I The concepts

Using Team Foundation Server Registry–Part II the API

Thanks to Mike Fourie  for proofreading and suggesting some improvements to this post.

Using Team Foundation Server Registry–Part II the API

 

On the first part of this series I talked about what is the registry and some basic scenarios usage, on this post I want to talk about how you manipulate registry entries.

You have two choices, using an utility to manipulate entries or using TFS object model (or SDK as it is officially called) using a .Net language or Powershell

Using an utility

Neno Loje wrote tfsreg.exe that you can use to manipulate (both read and write) registry values.

You can see an example of how to use it on a blog post  where Neno explains how to change the email notification delay (a setting that is stored in the configuration registry)

You can download the tool from the mentioned post.

Note: Although it is not clear on the post or on the utility itself, this tool only allows you to manipulate registry entries from the configuration registry (at least for now Smile) .

Reading/Writing values

All code is using the client object model, but most (if not all) calls also have a counterpart server object model that can be used on server scenarios.

You can manipulate registry entries using the ITeamFoundationRegistry interface.

Assuming you are already connected to TFS and have in your possession a valid reference to

TfsTeamProjectCollection object all you need to do to get a value is this (assuming you have enough permissions)

ITeamFoundationRegistry service = tfs.GetService<ITeamFoundationRegistry>();

service.GetValue(key);

You can also have at your disposal the generic methods GetValue<T> there are also overloads that can return a default value if the key is not found (OR you don’t have permissions to read it)

To write a value all you need is to use the SetValue member.

Pretty simple huh?

This is to access the a project collection registry, if you want to access the configuration registration instead you (if you have a connection to a project collection) you can get a reference like this

var regService = tfs.ConfigurationServer.GetService<ITeamFoundationRegistry>();

All the rest remains equal (you can also connect directly to the server using the class TfsConfigurationServer and then obtaining a reference to ITeamFoundationRegistry

Setting Permissions

Setting permissions requires a bit of more work,since there are (that I know of) not utilities to do this. It is still simple anyways. In order to read/set/remove a permission you need to use SecurityNamespace to manipulate objects from Registry Namepace, we can obtain it  via ISecurityService.

So in order to get a security namespace that can manipulate permissions from registry objects you need to something like this snippet:

var server = tfs.GetService<ISecurityService>();
var securityNamespace = server.GetSecurityNamespace(FrameworkSecurity.RegistryNamespaceId);

We can then use the SetPermissions method to set out permission, the following snippet

securityNamespace.SetPermissions("/", identity.Descriptor ,RegistryServicePermissions.AllPermissions, 0, true);

Now to dissect these parameters.

The signature for the method is:

public abstract AccessControlEntry SetPermissions(
    string token,
    IdentityDescriptor descriptor,
    int allow,
    int deny,
    bool merge
)

 

  • token paremeter we will pass / which means we will be granting access to the entire registry. If you want to grant just access to a part of the tree, this is the place to do it
  • identityDescriptor we will pass the account/group for which we will be granting the parameter (more on this later)
  • allow parameter we pass the value the value RegistryServicePermissions.AllPermissions since we want to grant read/write access
  • deny parameter we will pass 0 since we don’t wan to deny anything
  • merge we will pass true, since we want this permissions to be merged with existing ones (just in case)

Note: the value 1 and 2 on the allow/deny parameter depends on the type of security namespace we are dealing with, and it can be obtained from the security catalog.

To get and identity descriptor you need to use IIdentityManagementService, this snippet will allow you to get the identity of the group [DefaultCollection]\Project Collection Build Service Accounts


var identityService = tfs.GetService<IIdentityManagementService>();

var identity = identityService.ReadIdentity(
    IdentitySearchFactor.DisplayName,
    @"[DefaultCollection]\Project Collection Build Service Accounts",
    MembershipQuery.Direct,
    ReadIdentityOptions.None);

Notice the first parameter is key to the search, you can either search the user by it’s display name or by account name (IdentitySearchFactor.AccountName), but if you use Account name, the account will have to be in the format

vstfs:///Framework/IdentityDomain/<ID>\\<Name>

so using the same example the account name would be

String.Format("vstfs:///Framework/IdentityDomain/{0}\\Project Collection Build Service Accounts", tfs.InstanceId.ToString());

It is very important that specify the searchFactorValue in the right format or you won’t find the identity descriptor you are looking for.

Using Team Foundation Server Registry–Part I The concepts

 

Since the beginning Team Foundation Server uses a registry to store it’s settings (like Sharepoint location,external address,database configuration, etc), with the introduction of the 2010 version, the registry has been revamped to be much easier to use (pre 2010 it was a XML file that you had to manager yourself. Including the values that didn’t pertain you).

So starting with 2010, we have a nice API to manipulate the registry in a easier way. The registry is not only used by TFS to store it’s settings but it can also be used to store your settings.

There are many scenarios for which you can use the registry. If you need to store metadata that is project related and needs to be shared globally among several users you can use the registry to store those values instead of storing them on your own database.

The advantages are obvious, no need to manage an external storage mechanism, the data is contained within TFS with all the associated advantages (backup/restore, if you move a collection to another server they follow the collection, etc.).

The registry is not a database, you don’t (formally) define a schema for your settings. The registry is an hierarchical key/value database. You can define your keys in an hierarchical manner and the registry is agnostic about your data values (so you can use it to store, .Net types (being string the most common) or XML).

For example TFS uses the registry to store the email notifications settings on the following keys:

  • /Service/Integration/Settings/EmailEnabled
  • /Service/Integration/Settings/SmtpServer
  • /Service/Integration/Settings/EmailNotificationFromAddress

Notice the trend? Service –> Integration –> Settings stores a bunch of TFS related settings.

The API is public and you are free to use the registry, unfortunately the registry is not widely documented. I hope with this post demystify the registry, it’s semantics and how you can manipulate it.

There are two types of values in the registry. values and user values.

The values are registry scoped and anyone can read/write them (as long as they have the appropriate permissions), so it is appropriate to use when you have a setting that is going to be shared among all users.

User values are scoped to the user, they are private to the user and only the user can read/write them. This is great if you want to store settings for a user independent of it’s location, so you can store values in the user registry and he/she can roam around machines having the same settings everywhere (when you say application you can also say Fat client (eg: visual studio) and web. In fact this is exactly what Web Access does, it stores user preferences in the user registry.

There are two different registry storages, the project collection registry and the server registry (stored on the configuration database). The collection registry is stored along with all data of the project collection, so if you detach the collection and move it to another server the registry follows the collection, the configuration registry is stored on the configuration database, so you should use it to store parameters that are server related. If you move collection to another server and you are relying on some values on the configuration registry, it will be your responsibility to recreate them on the other server.

There are two kinds of security constraints applied to the registry. To read/write registry (depending on the registry) enters you need the following permissions

  • View collection-level information for a collection registry
  • View instance-level information for a configuration registry

These permissions are the first barrier, then you need permission to access the object itself (but since this is hierarchical you can grant/deny permission to a branch of tree). By default these are permissions to registry keys.

For the configuration registry

Permission Path Read Write
Team Foundation Service Accounts

/

X

X

SharePoint Web Application Services

/

X

 
Team Foundation Administrators

/

X

X

For a collection registry

Permission Path Read Write
Project Collection Service Accounts

/

X

X

Project Collection Administrators

/

X

X

Project Collection Valid Users

/Service/Registration/RegistrationExtendedAttribute/

X

 

Note: reading the registry has a semantic that is not common, if don’t you have first level of permissions (View collection-level information for example) the operation will fail with an exception. If you don’t have permission at the object level any read operation will not fail with an exception but it won’t return anything (even if the object exists).

This happens to avoid disclosing information that a node exists (it’s mere existence) to people who do not have access to it. It’s a typical technique of multilevel security systems to avoid leakage of information with inference atacks. For example if you have a value with a key /Settinga/OnToBeFiredList/JohnDoe I may not have access to it’s value due to lack of permission but if an error was flagged we could know it exists. Sometimes the mere acknowledge of the existence of information is reason enough to be denied.

It is debatable if the existence of such semantics doesn’t out weight the costs of not having errors being flagged when we don’t have access to information that we want to access. But such discussion is pointless since that the way things are. Smile

As of today (to be read, it is like it is today it can change tomorrow) access to the registry on Team Foundation Services (AKA as tfspreview.com or TFS on Azure)  has been hardened so you can’t read/write no matter what kind of permissions you have.

On the second part of this series I will delve into the registry API, how we can read/write values to the registry and now we can manage permissions to it.

Team Build: Building code with Visual Studio

 

Little Synopse (so you don’t give up on the first boring paragraph Smile). On this post I’m intend to explain how you can build your code in Team Build using Visual Studio, for project types or for solutions that contains projects not supported by MSBuild.

A few months ago (ok more than a few) I wrote two posts (Getting Visual Studio installation directory and Getting Visual Studio version of a Solution file) where I explained how we could get the installation folder of a given version of Visual Studio and how you can determine the version of Visual Studio (solution) file.

This was part of a bigger plan, and at the time I promised this would culminate in a post where I would develop a team build workflow activity that could be leveraged to build solutions using Visual Studio.

At first sight it may seem strange to use Visual Studio to build a solution, when Team Build supports building solutions out of the box using MSBuild (which requires no further installations since it’s part of the .Net Framework). That is the recommended way to go, unfortunately not all project types are supported by MSBuild. So we need to resort to Visual Studio to build them (which is a pain since it requires installing Visual Studio on the build agent machine(s)).

There a bunch of project types that are not buildable with MSBuild, to name just a few

  • Setup Projects (vdproj) (which are no longer part of Visual Studio starting from (not yet released) dev11)
  • Biztalk 2004, 2006 and 2006R2
  • Business Intelligence Studio Projects (reports, analysis services, etc) (commonly known as BIDS)

If you need to build a solution which contains one or more of these project types you will need to compile your code with Visual Studio (devenv). The easiest approach is call devenv.exe by using the activity InvokeProcess. This requires you to know the installation path of Visual Studio  (which varies on 32 and 64 bit machines), the correct version to use (you may have more one version installed), you lose logging of errors and output, the open the log file experience from the build logs….

There is plenty of literature on the web how to achieve this, for example example here , here or here

In order to help with this task, I had promised a post with working code for an activity that would easily allow you to do this. But I’ve reconsidered, instead of providing with a sample on the blog, I’ve proposed the maintainers of Community TFS Build Extensions to let me add this activity the already big arsenal of activities that they have. Since they were foolish enough to accept my code, you can use this activity along with other great activities in a single install.

So this post, will not get into great details of the code itself, but will focus how you can use this activity. You can download it in binary form from the Codeplex site or the source code (also from codeplex) if you wish to dissect it. (be sure to download the latest version, I’ve replaced the previous version of the activity (with the same name). It has more features than the previous one, but it also breaks backward compatibility).

When I designed the activity I had the following objectives

  • Support all VS build related actions (clean, build, rebuild and deploy)
    • This can be useful not only for compilation but also for deployment which needs to be done using Visual Studio (eg: Biztalk or SQL Server Reports)
  • Automatic detection of the version of Visual Studio to use (with the opportunity for manual fallback). This allows building using several Visual Studio Versions in a single box (e.g.: use VS2005 for Biztalk projects and VS2008 for SQL2008 BIDS projects)
  • Control the level of logging (separate from the general level) to include in the build logs itself the output of Visual Studio invocation results
  • The Log should also be stored in the in the drops folder, this log should be easily accessible from the logs build with a link for easy inspection
  • Support activity cancellation. For activities that may take a long time, it is advisable that then can be cancellable. Otherwise if the user tries to cancel them and they don’t respond in two minutes it may (not necessarily but it may) leave the agent in an inconsistent state.

The activity aims for simplicity of use. As with all Community TFS Build Extensions the activity appears in the Workflow activity toolbox

 wfactivitytoolbox

To use the activity just drag it into to WF canvas, it has the following parameters that you can use to define it’s behavior (I will only comment on this activity specific parameter. I will omit all parameters that are common to all activities present in the Community TFS Build Extensions.

VSDenvActivity-Parameters

  • Action – The action you want Visual Studio to perform. Possible values
    • Build
    • Rebuild
    • Clean
    • Deploy
  • Configuration – The configuration definition it will be used by VS to perform this action. (eg: Debug, Release,etc.)
  • Platform –The platform definition it will be used by VS to perform this action (eg: .Net, Any CPU,etc.)
  • FilePath – The complete path of the file we wish to perform the action upon. Either a VS solution file (.sln) or a project file (eg: .csproj, .vbproj, etc.) (this is a local path on disk)
  • Version –The Visual Studio version used to perform the action on the selected file. The are the market values for which the VS versions are known. Possible Values
    • Auto – Automatically use the appropriate VS version for performing the requested action  (Note: This can be only be used for .sln files)
    • VSNet2002
    • VSNet2003
    • VS2005
    • VS2008
    • VS2010
    • Dev11 – Yes we already support Visual Studio Dev11 Preview
  • OutputFile – the complete path (including filename) where the execution log file will be store. Use only this for a very specific reason. If you leave this parameter empty the system will automatically write the output to a file called <filebeingbuilt><configuration><platform>.log that will be stored in the logs folder of the drops folder.
  • OutputLoggingLevel –The minimum logging level to log the output of visual studio in the builds logs details (the log fill will still hold the output).

I think this is enough to get you started. Let me know if you have any suggestions or suggestions to improve the activity.

Future Plans: Add an activity that will allow to determine if a given solution can be built with MSBuild or it requires Visual Studio. This will allow to use a single template to build solutions with msbuild (as the out of the box template does) as well as solutions that require Visual Studio without having to parameterize it.

Community TFS 2010 Build Extensions–September Release

 

The Community TFS Build Extensions just released a new version, these are a set of Team Build WF Activities that will ease the work of build masters. It has a over 100 activities that range from file activities, VMs (Hyper-V and Virtual PC, TFS objects manipulation, VB6 compiling, IIS7, code metrics, stylecop,assembly info file manipulation and powershell execution  (to name just a few).

You can read announcement in Mike Fourie’s post.

The maintainers were foolish enough to include in the latest release an activity that I wrote to build and deploy code using Visual Studio, but that is material for a soon to be published blog post.

You can go to the Codeplex project site to download the binaries or the source code.

Meanwhile…

 

While everyone seems to be downloading the Windows 8 developer preview from http://dev.windows.com I’m downloading Visual Studio 11 developers preview and TFS 11 developers preview from MSDN. Smile (only for registered subscribers)

Go get it

[Update] Brian Keller just posted the hyper-v images with Dev11 pre installed including hands on labs. You can read more here

Team Foundation Build: Reducing the amount of log of your own activities calls

 

When customizing a build definition you will soon discover that the logs may be pretty noise. Even if the activities don’t emit any logging information, just invoking an activity will result in it’s Display Name being logged.

This can be quite verbose, specially when you start nesting activities within containers.

SNAGHTML1fe2c1fe

Look at this simple (perhaps a little convoluted example) whereas a simple FTP issues too much information.

Unfortunately there is no way to disable this logging on an activity by activity basis by just using the Workflow Designer, however if you are willing to edit the build XAML in a text editor you can disable the logging by activity.

Suppose you have a sequence activity called Copy Files to FTP and you don’t want it logged

    <Sequence DisplayName="Copy Files to FTP"  >

  You just need to edit the XAML file and set the attribute BuildTrackingParticipant.Importance with the minimum level of activity you want to log

So the XAML for this snippet would become

<Sequence DisplayName="Copy Files to FTP" mtbwt:BuildTrackingParticipant.Importance="Low">

You can read all about this on more detail on this Jason’s Pricket post

But this is for activities that you use on the designer, what about code activities that you write, wouldn’t be nice to have make them less noisy when they are invoked, without requiring people to edit the XAML file manually ?

Not only would be nice, but it is also possible to do it. All you need to do is add the

Microsoft.TeamFoundation.Build.Workflow.Tracking.ActivityTracking attribute with the right level of logging.

For example with this snippet, everytime the MyActivity is invoked, the call is never logged on Team Foundation Build

    [ActivityTracking(ActivityTrackingOption.None)]
    [BuildActivity(HostEnvironmentOption.All)]     [BuildExtension(HostEnvironmentOption.Agent)]     public sealed class MyActivity : CodeActivity

This achieves the same effect as editing the XAML file to add the BuildTrackingParticipant.Importance on all calls to MyActivity

So if you are writing workflow custom activities and the fact that was called appears in the logs doesn’t add any value (for example if are writing a logger or you already log useful information), be a good citizen and add this attribute to reduce the noise.