Friday, June 27, 2014

TFS 2013 Source Code Structure and Permissions

Each company will have their own branch structure.  What works for them may not always work for other companies.  Below is an outline of a structure you could certainly adopt.  It is pretty basic and accounts for how we manage our branches and releases.

$/PD
     /TeamX (used interchangeably with a Product)
          /Trunk
          /Branches
          /NonBranchedAssets
     /OrProductX
          /Trunk
          /Branches
          /NonBranchedAssets

We went with one team project and all of our products and teams under it.  Each product and team has it's own area and are represented as folders under the root of the team project.  In the example above the team project is $/PD.  A team or product for example is the Architecture folder.

Under each of these are three base folders.  Each team has this same structure for consistency.  This helps as developers may move around and they won't have to learn a new structure (one big happy team.)

We use the branch structures one of two ways depending on what types of releases we do.  The first scenario, A,  is for some of our longer development cycles.  The other scenario, B,  is for teams who release every iteration.  In some of the images you will note another layer folders called Managed and Unmanaged.  We use this layer to distinguish branches that have a managed environment to go along with them and ones that do not (sandboxes or personal branches).  In my examples I will omit these for simplicity.


Branch Scenario A


In this scenario Trunk is used as the primary development branch for the next release.  Project or Feature branches would branch off of this and end up for example under /Branches/FeatureA.  When complete they would merge back into Trunk and be included in the next release.  Because of the nature of the cycles for this software line at code complete an Integration branch is created for the Release.  It would look like /Branches/Integration/1.0 for the first major release.  This frees up Trunk for work to be merged into it from project or features slated for the next release.  As regression testing completes and the project releases to production a release branch is created for any emergencies that may come up.  It would look like /Branches/Release/1.0.  Any fixes made on the release or integration branch are retrofitted back to Trunk as needed.  The last folder, NonBranchedAssets, is reserved for things the team would like to store in version control but are not part of the built product.

$/PD
     /ProductX
          /Trunk
          /Branches
               /Integration/1.0
               /Release/1.0
          /NonBranchedAssets


Branch Scenario B


This scenario is setup for products on short iteration cycles.  It almost works in reverse and seems to work for those teams.  Here the Trunk represents the latest that is in production or shortly will be.  Development's code-line for the current iteration resides on /Branches/Integration.  If they want to work on cards/features and are not sure it will be completed in that iteration they would create a branch from /Brances/Integration/ to /Branches/FeatureA.  Once FeatureA is DONE it would be integrated back in with the rest of the features being worked on that iteration.  Then when the current iteration comes to an end what has been merged and tested on that branch then gets merged to Trunk.  Some final testing is done on Trunk and that build is deployed to production.  Emergencies would be a branch from Trunk to /Branches/Release/NameOfRelease.  As with the previous scenarios any fixes done for an emergency are retrofitted back to Trunk so as not to create regressions.  An emergency hasn't happened yet but to get the fix I may just have them re-baseline from Trunk to the integration branch.
$/PD
     /ProductZ
          /Trunk
          /Branches
               /Integration
               /Release/ReleaseY
          /NonBranchedAssets


Locking Down Root Structure

To prevent random folders and branches the root structure created is locked down.  This is a deny on various rights to the Contributors group.  Then at the appropriate level this is granted back to the Contributors group (Allow).  The way inheritance and explicit permissions work gives you the flexibility to do this.  

Lock down the team project with a Deny (except for Read).

The folders I don't want people messing with inherit the deny.

Then at the right level grant permissions back with an Allow.  In this case I am showing Trunk.  This would also be done at Branches and NonBranchedAssets folders.

Does this sound like a good plan?  

Thursday, June 26, 2014

TFS 2013 Portfolio Management - Team Administrator

I have been working on setting up one TFS Team Project for all of our products to live under.  This included creating teams and corresponding areas.  Queries for each team (and their respective area) were also created.  The challenge I face today is granting permissions for the team's administrators to be able to add queries to their teams Shared Queries.  

Currently we do not have any TFS teams created and are just using the defaults.  All of our permissions are driven out of active directory.  For example each team has a corresponding AD security group as a member.  This keeps all of our user administration in one location (Active Directory) for the entire company.

To add a Team Administrator it appears you only have the option of adding AD users or groups.  Having a security group as a member would simplify the team administrator management.  I am torn at this point because it would mean a bunch more AD groups.  I can hear the IT guys now on that one. 

I thought about created a VSO TFS team for the administrators of each team but it does not look like you can add a TFS team as a team administrator.  This brings me back to either asking IT for more groups for them to manage or just adding individual users as team administrators.  The down side to the individual user part is then I will have to manage security on iterations and queries at the user level.  This could get messy.

This is the major downside to having everyone in the same team project.  PERMISSIONS!


The Solution


So that IT doesn't come after me for doubling the number of groups they have to managed I ended up creating a TFS group called TeamName Team Admin.  I set this group to have the same base permissions as Contributors.  I did this so if you are in both groups it will not mess up your permissions.  This will always be in sync with Contributors.

With this new group I gave it rights to edit shared queries for the team as well as iterations for the team. Both of these can be achieved by right-clicking on the object (example a query folder) and editing the security for it.  For queries I gave the TFS group Allow on Contribute and Read.  For the iteration (and sub iterations) they were given Allow on Create child nodes and Edit this node.  The Edit this node was needed so they could move sub-iterations between the 3 root iterations they have rights to.

The only downsides are if an admin changes I have to change it within the Team and the team admin TFS group.  My user security is now being managed in two tools instead of one (just Active Directory).  

Any questions please feel free to ask.

Monday, June 23, 2014

TFS 2013 Workspaces with UNC Path

Can you have TFS workspaces with UNC path as the local folder?

The answer is yes. I was able to setup the following and get latest on it:

Source Control Folder = $/My Project/TeamA/Folder B
Local Folder = \\networklocation\TeamA\Folder B

Note the names in the local folder mapping do not have to match exactly.

The security of the folder and files were assigned to me with Full control and the rest of the permissions where inherited from the parent as well.  This all assumes you have permission to write to the network location you are setting up for the workspace.  Ensure the owner has rights and test this out when setting it up.

Belonging to multiple TFS teams

What was happening.

Since I am the admin and created all of the teams I was apart of all of them.  Within Visual Studio 2013 I was connecting to the Team project and working from that in the Team Explorer bar.  By doing this my work for all teams was showing up.  I did not realize until today you could drill down even further and easily switch between teams you belong to right in Visual Studio or Team Explorer.

Switching Teams

If you click on the down arrow and go to Projects and My Teams.  From there you can select the team you want to "join".  Once there Team Foundation Server 2013 will start to reflect that in the sidebar information.


Thursday, June 19, 2014

Setting up Build Machines for Team Foundation Server 2013

Software Requirements on 64-bit Server
  1. Install TFS 2013 Team Explorer
    1. Not supported on Server 2003, http://msdn.microsoft.com/en-us/library/dd997788.aspx
  2. Install TFS 2013 Power Tools

Software Requirements on 32-bit Server (yes we still use a 2003 OS)
  1. Navigate to %temp% or C:\Users\[Username]\AppData\Local and right click on the Temp folder and choose properties, then click the security tab and click advanced.
  2. On the permissions tab you should see the permissions that are there. There should 3 which are:
'SYSTEM' with Full control which applies to 'This folder, subfolders and files'
'Administrators' with Full control which applies to 'This folder, subfolders and files'
'Your Username' with Full control which applies to 'This folder, subfolders and files'
and all 3 should be inherited from the C:\Users\[Username]\ folder.
  1. If you don't have the 'Include inheritable permissions from this object's parent' option ticked, then tick it and click continue if there are any problems, then remove the permissions that aren't inherited.
  2. Unblock all exe's copied to server for installation
     
  1. Install TFS 2010 Team Explorer
    1. You will have to copy all installs locally to the server before running them
    2. Right-click on the setup.exe and perform a Run As (in unrestricted mode)
  2. Install TFS 2010 SP1 by double clicking on the VS10sp1-KB983509.exe.  There is no SP1 for Team Explorer 2010 and Microsoft says SP1 is required.
    1. You will have to copy all installs locally to the server before running them
    2. Right-click on the VS10sp1-KB983509.exe and perform a Run As (in unrestricted mode)
  3. Install Visual Studio 2010 Service Pack 1 TFS Compatibility GDR
  4. Install TFS 2010 Power Tools
     

I included the Power Tools on our build machines because of the extra commands like undo unchanged and the Windows Explorer integration.

Wednesday, June 18, 2014

Moving Multiple Files in Team Foundation Server 2013 Source Control

Moving Multiple Files in Team Foundation Server 2013 Source Control

My team was reorganizing some of our folders moved over from SVN into TFS today.  One of my teammates asked if he could move multiple files from a folder to another.  We wanted to preserve the history so hoping it was a new feature I told him to select all the files and do a move.  To my dismay this still is not possible in the Source Control Explorer GUI or Windows Explorer (Power Tools).  The Move option is grayed out.

The command line does allow for wildcards so this is what I will be telling our user base to use.  Sometimes this happens when a developer accidentally adds a bunch of files in the wrong folder.  There may be other files in the folder that need to remain so you can move the whole folder.

Checking the help this is now just an alias of rename:

C:\>tf.exe move /?
Microsoft (R) TF - Team Foundation Version Control Tool, Version 12.0.30501.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Changes the name or the path of a file or folder. You can use the rename
command or the alias move, to move a file or folder to a new location.

tf rename [/lock:(none|checkout|checkin)] [/login:username,[password]]
          olditem newitem

The wildcard way

It is short and sweet.  Just remember to add the path to the tf.exe to your PATH environment variable to make it easier to use in the future.  Something you can't do (and why would you) is move a parent folder into a child.

tf move "$/TeamProject/FolderA/*.dll" "$/TeamProject/FolderB/lib"


Vote

Please vote this up so Microsoft gets it in soon.

Thursday, June 12, 2014

TFS 2013 Source Control Permissions to Lock Down A Folder

TFS 2013 Source Control Permissions to Lock Down A Folder

Things Tried

The way I have things structured for this Team Project is each team is mapped to an area and I also created a folder in source control for there source code.

Defualt Team Project Team -> Team Project -> $/TeamProject
Team A -> Area A -> $/TeamProject/Product A
Team B -> Area B -> $/TeamProject/Product B

All of the teams are part of the Contributors VSO Group
I have an Active Directory group for each team.  This is where we managed users (and not in Team Foundation Server/TFS).

I noticed that when I created each of the teams it automatically placed then in the contributors group as well.  This is the default when you create a team.  I wonder if I should have not placed the teams in any group at this time.  That may be a future article as I think I have made permissions more complex than they need to be.

Initially I had thought to deny the Team Projects default team (everyone in our department) and allow just a specific team to have access to their folder.  I found that did not work as it locked me out of my team's folder even though I am a Team Collection and Project administrator.

Then I tried add my team in explicitly Allowing the actions I set to Deny for the team project team.  This did not work.  When I look at the permissions of a file I am trying to get latest on it shows both teams.  The problem is I am a member of both teams and it looks like Deny overrides Allow permissions.

Next I removed both teams from the version control security for that folder and set Contributors back to Deny.  I added my team group and set it to Allow.  After saving the changes it red flagged all of them.  It says it is overriding explicit allow.  This is because my teams group is part of the Contributors group.  Guess you can't do that either.


This Works

First what you need to understand about permissions in TFS is they use the most restrictive permissions wins principle.  What that means is if you belong to multiple groups the one with the most restrictive permission applies to that folder or file.

Since I am a Collection and Project administrator this will be tough to accomplish.  Basically I will need to completely lock my self out of that folder and only grant permissions to the team that needs access to the files.  To do that I had to make one of the team members administrator for the team (I was it by default since I created the team.) Then I had to stop inheritance on the folder.  Last I removed all of the groups (including admins) and added just the team's VSO group.  That did the trick!
Image courtesy of  Stuart Miles FreeDigitalPhotos.net

Tuesday, June 10, 2014

Modifying Other Workspaces as an Admin in TFS 2013

There was a need to modify my build machines TFS 2013 workspace from the default (local) to a server workspace.  Since the workspace was private I could not view it in the UI so I had to turn to the command line.  This will be useful as other users will have issues and as an administrator I need to know how to do this.

To get a list of workspaces you can use the following command.  This will help in finding the workspace you need to alter.  This assumes you have added the path to tf to your PATH environment variable.  It also assumes your DNS to your TFS farm is called tfs

tf workspaces /computer:NameOfComputerWhereWorkspaceResides /owner:* /format:detailed /server:http://tfs:8080/tfs/YourCollectionName

Once you have located the name of the workspace and it's owner you can now alter the workspace.

tf workspace WorkspaceToModify;OwnerOfWorkspace /location:server /collection:http://tfs:8080/tfs/YourCollectionName 

The above command will change it to a server workspace.  Another thing you might want to change for build machine workspaces is the File Time field.  The File Time is set to current which will set all the files to the current time on Get Latest.  The preferred settings for a build machine is Checkin.  That way any files packed for release have a more realistic time of when they were created or last modified.

Friday, June 6, 2014

What is a WIQL variable?

What is a WIQL variable?


In TFS 2013 there are variables you can use in the queries that link to some predetermined Microsoft value.  I always wondered what they were called.  Recently I was reading an excellent post regarding a workaround for the Current query dilemma.

This was the number one hit for it...
WIQL (Work Item Query Language) is the query language for Work Items that Test Management adopts for querying test objects. In Microsoft Test Manager (MTM), WIQL queries are hidden away from users and only the query results are displayed.

It gives a pretty good description.  It is from 2010 so there have probably been many updates to the language and variables available.  Unfortunately @Current still isn't one of them.

Thursday, June 5, 2014

CruiseControl.NET and TFS 2013

CruiseControl.NET and TFS 2013

So in our move to TFS 2013 from SVN we do not initially plan to change our build process over to TFS yet.  Currently we are on CruiseControl.NET 1.8.3.  Upon research this release doesn't officially support TFS 2013.  That was a later enhancement in 1.8.5.  However we are not prepared to upgrade to 1.8.5 (one change at a time).  What I am left with is trying to get 1.8.3 to work with TFS 2013.  It does have a "vsts" source control provider.  Below are my notes on getting this working.

Source Control Path Filters

If you specify a workspace name CCNET will create it but it doesn't appear to be in a format 2013 UI or command lines understand.  What I mean is if you list the workspaces via command line or in the UI you will not see it.  However it is there.  When I checked a file in no build triggered.  I recommend manually creating the workspace on your server and specifying it in the name.  Even with that I get this error when I forced a build (it never triggered):
ThoughtWorks.CruiseControl.Core.CruiseControlException: Warning default.htm - Unable to perform the get operation because the file already exists locally Warning help.htm - Unable to perform the get operation because the file already exists locally Warning D:\Dev\SCM\main\WebSites\SCM\default.htm - Unable to perform the get operation because the file already exists locally Warning D:\Dev\SCM\main\WebSites\SCM\help.htm - Unable to perform the get operation because the file already exists locally at ThoughtWorks.CruiseControl.Core.Sourcecontrol.Vsts.LookForErrorReturns(ProcessResult pr) at ThoughtWorks.CruiseControl.Core.Sourcecontrol.FilteredSourceControl.GetSource(IIntegrationResult result) at ThoughtWorks.CruiseControl.Core.Sourcecontrol.MultiSourceControl.GetSource(IIntegrationResult result) at ThoughtWorks.CruiseControl.Core.IntegrationRunner.Build(IIntegrationResult result) at ThoughtWorks.CruiseControl.Core.IntegrationRunner.Integrate(IntegrationRequest request)
I had to go into the TFS Explorer UI and override the files.  I wonder if it was because I forgot to set the workspace to a server workspace with Checkin times.  After fixing the workspace and editing the file again I was able to force a build with no issue.  However it still is not picking up on changes and triggering automatically.

I believe it has something to do with my path filters or project in the ccnet.config or my workspace mappings in TFS.

In SVN my path filter appended to the URL so if you specified your <turnkURL> as http://svnserver/svn/trunk you could use a path filter of /branchUnderTrunk/**/*.  This would trigger a build for any file under http://svnserver/svn/trunk/branchUnderTrunk.  This doesn't work for TFS.  Below are some examples of what did work for me.  They include wild cards before the path and using the full TFS path.

<inclusionFilters>
   <pathFilter>
      <pattern>/Processes/**/*.*</pattern> <!-- Does not work -->
   </pathFilter>
   <pathFilter>
      <pattern>**/Scripts/General/**/*.*</pattern> <!-- Does work -->
   </pathFilter>
   <pathFilter>
      <pattern>$/TFSProject/TRUNK/WebSites/**/*.*</pattern> <!-- Does work -->
   </pathFilter>

</inclusionFilters>


Source Control Project and Working Directory

This is what I have learned about the <project> and <workingDirectory> elements in the ccnet config for the vsts source control block.  The <project> element doesn't necessarily have to the just the project root ($/TeamProject).  It can be a subdirectory.  This matches up to the Source Control Folder mapping in the TFS workspace UI.  The <workingDirectory> then maps to the Local Folder.

As I changed these settings and did an edit on the workspace I would see the changes.  Keep this in mind as what ever you initially set in the workspace you manually created may not be what it is after Cruisecontrol.NET alters it.

If your workspace in SVN only had certain subfolders locally and not the whole folder structure you can mimic that by cloaking the folders you don't want to sync by editing the TFS workspace.  After doing this and kicking off another build CCNET did not alter the workspace config.

Monday, June 2, 2014

TFS 2013 Administration Tool and SharePoint 2013 Permissions

Team Foundation Server 2013 Administration Tool and SharePoint 2013 Permissions

I was following all of the instructions throughout the internet about the best way to manage users in TFS.  I landed on using AD groups and managing the roles those groups played using the TFS Administration Tool.

This is a matrix describing each role to assign in the tool.
Software
Readers
Contributors
Project Leads
Team Foundation Server
Readers
Contributors
Project Administrators
SharePoint Foundation or SharePoint Server
Visitors
Members
Owners
SQL Server Reporting Services
Browser
Browser
Team Foundation Content Manager

I setup all of our teams and the corresponding AD group and assigned these roles.  Everything worked fine except the SharePoint permissions.  No one was able to view the sites I had created except for me.  I could not figure out why because when I looked in SharePoint they were assigned.  The odd thing was when I did a Check Permissions on the user in SharePoint Site Settings -> Site Permissions the user showed as having no permissions.

When I added the user in SharePoint I then had two users and really started scratching my head (I am not a SharePoint administrator so not that familiar with it besides the out of the box settings).

Luckily I was not the only person having this issue.  Vote this up as it will make our (TFS Admins) lives easier.  It turns out there are multiple authentication methods you can use with SharePoint 2013.  The default happens to be Claims Based Authentication.  Most likely the TFS Administration Tool only works with Windows Authentication.  So for now I will have to use SharePoint to assign user permissions for TFS and not the tool.

Any other SharePoint kinks I need to be aware of?  Let me know.  Otherwise I will post them as I come upon them.

Image courtesy of  Stuart Miles / FreeDigitalPhotos.net