Enable new Work Item Form in TFS “15”

If you installed TFS 15 Preview, one of the news you expected to see is the new Work Item Layout (already available in VSTS). You could get disappointed that actually your existing Work Items still are shown with the old interface, as you can see in Figure 1

image

Figure 1: After upgrade TFS still shows the old Work Item Form

The new Work Item Form is installed with an opt-in method so it is disabled by default. To enable it you should navigate to the Project Collection administration page. From here you should see that this feature is actually disabled (Figure 2), but you have the link to Enable it.

image

Figure 2: New Work Item form is disabled by default after upgrade

If you click the “Enable the new work item form” link, you are informed that this operation will create a new layout for the Work Item, but you can choose, after the creation of the new layout, if you want to use the new model, and the opt-in model, as you can see in Figure 3.

image

Figure 3: Enabling the new Work Item layout starts with the creation of the new Layout.

Thanks to the opt-in method, you are not forced to use the new layout, but you can activate it only if you want to use it

After the creation of the Layout you should configure the Opt-in model, or you can disable entirely the new Work Item Form.

image

Figure 4: Options to enable the new Work Item form with the opt-in model

The opt-in model basically allows you to decide who can view the new Work Item form layout. You have three options, as shown in Figure 5, you can give the ability to use the new layout only to administrators, to all user, or you can force everyone to use the new Layout, disabling the old layout entirely.

image

Figure 5: Opt-in model options to enable the new Layout form

Opt-in model for the new Layout Form is really flexible because you can leave the decision up to each single user.

The central option is usually the less impacting, because each member of the team can choose to evaluate the new layout or stick with the old one. A new link appears on the head of the Work Item Form, in the far right part, as you can see in Figure 6.

image

Figure 6: Opt in model allows each user to choose to evaluate the new form.

If the user choose to preview the new form, the page refresh and the Work Item is rendered with the new layout. The user has the option to return to the old form if he do not like the new form, giving the whole team the time to evaluate the feature and decide if using it or not.

SNAGHTML7928e8

Figure 8: New form is active and the user can back to old form if the do not like it.

This settings is “per collection” so you can decide different opt-in model for each collection of your TFS.

Gian Maria.

Keep Git repository in sync between VSTS / TFS and Git

Scenario: you have a repository in Git, both open source or in private repository and you want to keep a synchronized mirror in VSTS / TFS.

There are some legitimate reason to have a mirrored repository between Github or some external provider and an instance of VSTS / TFS, probably the most common one is keeping all development of a repository private and publish in open source only certain branches. Another reason is having all the code in Github completely in open source, but internally use VSTS Work Item to manage work with all the advanced tooling VSTS has to offer.

The solution to this problem is really simple, just use a build in VSTS that push new commits from GitHub to VSTS or the opposite. Lets suppose that you have a GitHub repository and you want it to be mirrored in VSTS.

Step 1 – install extension to manipulate variables

Before creating the build you should install Variable Toolbox extension from the marketplace. This extension allows you to manipulate build variable and it is necessary if you use GitFlow.

From the list of Build Variables available in the build system there are two variables that contains information about the branch that is to be build. They are  called Build.SourceBranch and Build.SourceBranchName, but noone of them contains the real name of the branch. The SourceBranch contains the full name refs/heads/branchname while SourceBranchName contains the last path segment in the ref. If you use gitflow and have a branch called hotfix/1.2.3 the full name of the branch is refs/heads/hotfix/1.2.3 and the variable SourceBranchName contains the value 1.2.3 …. not really useful.

Thanks to the Variable Toolbox Extension you can simple configure the task to replace the refs/heads part with null string, so you can have a simple way to have a variable that contains the real name of the build even if it contains a slash character.

Step 2 – configure the build

The entire build is composed by three simple task, the very first is a Transform Value task (from Variable Toolbox ) followed by two simple command line.

SNAGHTML3a85c0

Figure 1: The entire build is three simple tasks.

The first task is used to remove the refs/heads/ part from the $(Build.SourceBranch) and copy the result to the GitBranchName variable (you should have it defined in the variables tab).

image

Figure 2: Transformation variable configured to remove refs/heads

Now we need a first command line task that checkout the directory, because the build does not issue a checkout in git, but it simple works in detatched HEAD.

image

Figure 3: Checkout git through commandline

As you can see in Figure 3 this operation is really simple, you can invoke git in command line, issuing the command checkout $(GitBranchName) created in precedent step, finally you should specify that this command should be executed in $(Build.SourcesDirectory).

The last command line pushes the branch to a local VSTS Repository.

image

Figure 4: Git command line to push everything on VSTS

The configuration is really simple, I decided to push to address https://$(token)@myaddress.visualstudio.com. Token variable (2) is a custom secret variable where I store a valid Personal Access Token that has right to access the code. To push on remote repository the syntax $(GitBranchName):$(GitBranchName) to push local branch on remote repository with –force option to allow forcing the push.

Do not forget to make your token variable as a secret variable and configure the continuous integration to keep syncronized only the branch you are interested to.

image

Figure 5: Configure branches you want to keep syncronized

If you need also to keep tags syncronized between builds you can just add another command line git invokation that pushes all tags with the push –tags option.

The result

Thanks to this simple build, whenever we push something on GitHub, a build starts that automatically replicate that branch in VSTS without any user intervention.

image

Figure 5: Build result that shows command line in action during a build.

Thanks to the free build minutes on the hosted build, we have a complete copy in VSTS of a GitHub repository with automatic sync running in few minutes.

The very same configuration can be reversed to automatically push to GitHub some branches of your VSTS account, useful if you want to publish only some branches in open source, automatically.

Gian Maria.

Re-indexing source in TFS “15” preview

If you installed TFS “15” preview you should give a try to code search, because it is surely one of the coolest feature introduced in this new release.

If for some reason the indexing went wrong, or code is not indexed, you can try reindexing using some powershell scripts that are described in this post.

Happy TFS.

Using PAT to authenticate your tools

One of the strength point of VSTS / TFS is the extensibility through API, and now that we have a really nice set of REST API, it is quite normal to write little tools that interacts with your VSTS / TFS instances.

Whenever you write tools that interact with VSTS / TFS you need to decide how to authenticate to the server. While for TFS is quite simple because you can simply run the tool with Active Directory user and use AD integration, in VSTS integrating with your AD requires more work and it is not always a feasible solution.

Actually the best alternative is to use Personal Access Tokens to access your server even if you are using TFS and you could use AD authentication.

PAT acts on behalf of a real user

You can generate Personal Access Token from security section of your user profile, and this gives you immediately idea that the token is related to a specific account.

image

Figure 1: Accessing security information for your profile

From Personal access tokens section of your profile you can generate tokens to access server on behalf of your user. This means that the token cannot have more rights that your user have. This is interesting because if you revoke access to a user, all PATs related to that user are automatically disabled, also, whatever restriction you assign to the user (ex deny access to some code path), it is inerently applied to the token.

PAT expires in time

You can see from point 1 of Figure 2 that the PAT has an expiration (maximum value is 1 year) and this imply that you have no risk of forgetting some tool authenticated somewhere during years.

This image shows how to create a PAT, and point out that the token expires, is bound to a specific account and you can restrict permission of the PAT to given area.

Figure 2: PAT Creation page in VSTS

A tipical security problem happens when you create in your TFS / VSTS a user to run tools, such as TFSTool or similar one. Then you use that user in every tool that need to do unattended access your TFS instance and after some years you have no idea how many tools are deployed that have access to your server.

Thanks to PAT you can create a different PAT for each tool that need to unattendely authenticate to your server, after one year maximum the tool will lose authentication and it need to have a new Token. This will automatically prevent  the risk of having old tools that after year still have access to your data even if they are not actively used anymore.

For VSTS (point 2) you should also specify the account that the PAT is able to access if your user have rights to access more than one account.

PAT Scope can be reduced

In Figure 2 the point 3 highlight that you can restrict permission of PAT based on TFS / VSTS area. If your tool need to manipulate work items and does not need to access code or other area of TFS, it is a best practice to create the token and give access only to Work Items. This means that, even if the user can read and write code, the token can have access only to Work Item.

Another really important aspect is that many areas have the option to specify access in read-only mode. As an example, if your tool needs only to access Work Items to create some reports, you can give PAT only Work Item (read) access, so the tool will be able to access only Work Item in read-only way.

The ability to reduce the surface of data that can be accessed by a PAT  is probably the number one reason to use PAT instead of  AD authentication for on-premise TFS.

PAT can be revoked

Any PAT can be revoked any time with a single click. This means that if you use the pattern of one PAT for each tool you can selectively revoke authentication to any tool revoking associated PAT. This capability is really interesting for on-premise TFS, because if you want to selectively revoke access to specific tool without PAT, you need to use a different user for each different tool and disable that specific user.

Conclusion

Using PAT is not only useful if you want to create token used by tools that need to do an unattended authentication to the server, but you can use PAT even for tools that you use, if you want to be sure that the tool will not have access to certain part of your account (you can use a PAT that can only access code to use with Git tools), or if the tool does not support MSA or AAD authentication.

Import a Git Project with REST API between VSTS Team Projects

I’ve got an interesting question about the possibility to import via REST API a Git Repository between Team Projects of VSTS. Actually the problem is: you want to import a private git repository from a Source repository (in this situation is another VSTS git repository but it could be hosted everywhere) to a VSTS Target  repository using only REST API.

The operation is quite simple thanks to the new api described here (https://www.visualstudio.com/en-us/docs/integrate/api/git/import-requests#create-a-request-to-import-a-repository) and in this post I’ll give you all the details.

Step 1 – create a PAT

To access VSTS through REST API you have many option to authenticate the call, but the easiest one is using PAT (Personal Access Token). If you do no already have a valid PAT you can create one using security page of your account.

image

Figure 1: Open security page of your account

Creating a PAT is really simple, you should only select Personal Access Token (1), then give a description, an expiration time, and the account where PAT is valid into. Since I have more than one VSTS Account I have a combo where all of my account are listed (2).

Finally you should select only the permission you want to give to the token. The default option is All Scopes, and this will imply that the token can do pretty much anything you can do. If you need this token to manage import of repositories you can simply select only code related permission.

image

Figure 2: Create a PAT to access your account.

Personal Access Token are the most secure way to authenticate an application in VSTS because they can be revoked, you can choose the permission you want to give to the token and they have an automatic expiration.

If your Source Account is on a different account from the Target Account you need to create PAT both in Source Account VSTS Instance and in Target Account VSTS Instance. In this example VSTS instance is the very same, so I need only one PAT.

Step 2 – Create endpoint to access Source Repository

My target repository is called ImportTest, and it is important that this repository is created empty. This is my Target Repository, the repository where I want to import the Source Repository.

image

Figure 3: Create Target Repository with standard Web Interface

The import routine should be able to access Source Repository and this imply that it needs to be authenticated. To maximize security you need to create an Endpoint that point to the Source Repository in the Team Project of Target Repository. This can be easily done from the administration page of the Team Project that contains the Target Repository. The team project that contains my ImportTest repository is contained in GitMiscellaneous Team Project, and I can proceed to manually create the endpoint.

image

Figure 4: Create an endpoint of type External Git

image

Figure 5: Specify endpoint details

In Figure 5 you can see all the options needed, you should specify a connection name, then the URL parameter is the url of the Source Repository, the same url you use to clone the repository. Finally you need to use the PAT as username, then you can press OK.

This service endpoint should be created in the Team Project that contains the Target Repository, because it will be used by the import routine to authenticate to the Source Repository to take data to import.

An endpoint is basically an URL and an authentication that is used by the server to access an external service

If you need to automate the whole process, the endpoint can be created easily with REST API  (https://www.visualstudio.com/en-us/docs/integrate/api/endpoints/endpoints) here is a simple call in Postman.

image

Figure 6: Creation of the endpoint with REST API

This does not need any explanation because it is a simple call with the very same option that you specify on the UI.

Step 3 – Create the call to import repository

To create the call to start repository import routine you need some parameters: first of all you need the id of the Endpoint you created in step 2. If you created the endpoint through REST API this is not a problem, because the Id is present in the response

image

Figure 7: Response of the request shown in Figure 6 contains endpoint Id

If you created the endpoint through Web UI the id can be grabbed by the url in the administration page of the endpoints, but a simpler and better method is to list all endpoint of the Team Project through REST API. In my situation is a simple GET call to this url https://gianmariaricci.VisualStudio.com/GitMiscellaneous/_apis/distributedtask/serviceendpoints?api-version=3.0-preview.1

The answer is the very same of Figure 7, and this gives me the id of the endpoint that points to the Source Repository: df12f2e3-7c40-4885-8dbd-310f1781369a

Now I need to create the import request, as described here (https://www.visualstudio.com/en-us/docs/integrate/api/git/import-requests#create-a-request-to-import-a-repository). And the only information I’m missing is the Id of the Target Repository

image

Figure 8: Repository part of the url in the call should be replaced by repository ID

As shown in Figure8 the only annoying part of the request is the Id of the Target Repository because it is the GUID of the repository not the name. Obtaining this value is not difficult, because with REST API this is a simple GET call to this url: https://gianmariaricci.VisualStudio.com/DefaultCollection/GitMiscellaneous/_apis/git/repositories?api-version=1.0. From the answer of this call the ID of the ImportTest repository is: 3037268a-0c91-4fe1-8435-a76e9b731f5e

Now I have everything to create the import request, just forge the request in Postman or similar tool and fire the request.

image

 Figure 9: The import request where 1 is the ID of Target Repository and 2 is the ID of the endpoint.

If you are quick enough and refresh the page of Target Repository while the import routine is running, you should be able to see this image

image

Figure 10: Importing is running

After a little bit (depending on the source of Source Repository) the Target Repository will be a perfect clone of the Source Repository .

If there are errors during the import process in the source code page of Target Repository  you are warned with the error, as shown in Figure 11.

image

Figure 11: Error in the importing routing were shown to source  code page of Target Repository

As an example the error in the above image is due to a misconfiguration of the Endpoint (done in part 2), as an example if you created the endpoint with wrong credentials.

Gian Maria