We are trying to have ReSharper's cleanup code run on TFS Checkin. Ideally, when you right click on the solution / project and select Source Control > Check in all the files in the "Included Changes" should run cleanup code. I've got the custom checkin policy to work to some extent, works fine if you select a single file to check in but when you select the solution or project, it tries to run cleanup code on the entire solution / project and not just the files selected in TFS Pending Changes "Include Changes".
I'm running VS 2013 with R# 8.2. My policy evaluate code:
public override PolicyFailure[] Evaluate()
{
if (PendingCheckin.Policies.EvaluationState == PolicyEvaluationState.Unevaluated)
{
DTE2 dte = PendingCheckin.GetService(typeof (DTE)) as DTE2;
foreach (EnvDTE.Document doc in dte.Documents)
{
doc.DTE.ExecuteCommand("ReSharper_SilentCleanupCode");
}
}
return new PolicyFailure[0];
}
I don't think this only applies to ReSharper, executing "Edit.FormatDocument" here would most likely run on all files as well.
Is there a way to run ExecuteCommand on only 1 file / document?
It seems like
PendingCheckin.GetService(typeof (DTE))
only gets files that are open in the Visual Studio editor not all the files that are in the "Include Changes" list. I can get a list of PendingChange through
PendingCheckin.PendingChanges.CheckedPendingChanges
But I don't know how to execute a command on PendingChange. Recommendations here would help
PS: I've read that the check in policy is meant to be used for checking documents only, however this workflow is what we need.
Related
Is there a way to check if a specific .xml file exists in build directory when TFS build runs?
I'm trying to get a Boolean result true/false based on the result found/not found
I tried creating a variable that would store this result (I'm guessing that is the way to do it). However I get an error when trying to use it.
You can try writing a script to check if the specific file exist, then check in the script and run as Pre-build script in your build process:
e.g.:
$Source = $Env:TF_BUILD_BUILDDIRECTORY
$filename = "*.xml"
if (!(Test-Path "$Source\$filename"))
{
Write-Warning "$filename absent from build directory"
# Write-Error "$filename absent from build directory"
#exit 1
}
Reference Using Environment Variables in Visual Studio 2013 and TFS 2013
The expression editor uses standard VB.NET, so you can call into System.IO.File.Exists(path) to detect whether a file already exists.
Found the solution. I added a new variable "dcMatchedFile" - which is a IEnumerable type. Use this dcMatchedFile as "Result" option for FindMatchingFiles" item (see images below)
Then you can simply use "If" statement to check Any().
I'm used to working with TeamCity so it might be that I should completely change my workflow, in that case answer with a suggestion of a new workflow instead.
In TeamCity I usually build and run unit tests as one build task (at every commit). Longer running tests are scheduled nightly and are run in the same way. So far I've manged to replicate the process in TFS. But on top of this I have a build task to deploy/publish a package. This is something I start manually once we are ready for it. This script references the artifact from a previous build (i.e. a drop folder or a drop zip in TFS).
I've read this article about deployment scripts but I can't find any information about how I can trigger them in TFS.
So the question in short: How do I reference a "drop as zip" or a drop folder instead of the source when building in TFS?
You can "Get Specific Build" or the "Latest Successful Build" on a specific Build, and then you can refer to that build's drop location.
Using TFS API, getting latest one should look something like this:
using (TfsTeamProjectCollection tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://tfsserver:8080/tfs/DefaultCollection")))
{
var buildServer= tpc.GetService<IBuildServer>();
var buildSpec = buildServer.CreateBuildDetailSpec(teamProjectName, buildDefinition);
buildSpec.InformationTypes = null;
buildSpec.MinFinishTime = DateTime.Now.AddHours(-lastXHours);
buildSpec.MaxBuildsPerDefinition = 1;
buildSpec.QueryOrder = Microsoft.TeamFoundation.Build.Client.BuildQueryOrder.FinishTimeDescending;
buildSpec.Status=Microsoft.TeamFoundation.Build.Client.BuildStatus.Succeeded;
var buildDetails = buildServer.QueryBuilds(buildSpec).Builds;
if (buildDetails.Length ==1){var dropLocation= buildDetails[0].DropLocation; }
else { Console.WriteLine("No builds found." );}
}
I am building a VS2010 addin. This addin will work only for our custom project types and create a menu item that will copy the output assembly from the current solution to another solution. Both are under TFS control.
I have the following code:
var tfs = new TeamFoundationServer(address);
var version = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
var workspace = version.GetWorkspace(System.Net.Dns.GetHostName().ToString(), version.AuthorizedUser);
workspace.PendEdit(dest);
System.IO.File.Copy(source, dest, true);
Now I want to checkin the change. The problem is that I don't know how to select only that file I checked out just now? I have other pending changes in the same project and also in other projects. Will this checkin EVERYTHING I have checked out?
Can I be more selective?
PendingChange[] pendingChange = workSpace.GetPendingChanges(dest);
workSpace.CheckIn(pendingChange, comments);
Workspace.GetPendingChanges Method (String)
http://msdn.microsoft.com/en-us/library/bb139277(v=vs.100).aspx
Parameters
item: The path, local or server, to the item that is being queried.
And
Workspace.CheckIn Method
http://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.workspace.checkin(v=vs.100).aspx
Parameters
changes
The set of pending changes to check in. If you do not specify this parameter, all changes in the workspace are checked in.
comment
The comment to be associated with this check-in. May be null.
I've setup teamcity with my sln file and got the unit tests to show up with the CppUnit plugin that teamcity has. And I get test results in the TeamCity UI.
Now I'm trying to get trending reports to show up for my unit tests and code coverage.
As of code coverage, we're using vsinstr.exe and vsperfmon.exe which produces an XML file.
I'm not quite sure as of what steps I should be taking to make the trending reports and code coverage(not as important) to show up.
I've already seen this post, but the answer seems to require editing the build script, which I don't think would work for my case since I'm building through MSBuild and the .sln file, and the tests are being ran through that build.
So basically I'm trying to get the Statistics tab to show up, and I'm not sure where to begin.
Just add simple Powershell step into your build configuration. Something like this:
function TeamCity-SetBuildStatistic([string]$key, [string]$value) {
Write-Output "##teamcity[buildStatisticValue key='$key' value='$value']"
}
$outputFile = 'MetricsResults.xml'
$xml = [xml] (Get-Content $outputFile)
$metrics = $xml.CodeMetricsReport.Targets.Target[0].Modules.Module.Metrics
$metrics.Metric
| foreach { TeamCity-SetBuildStatistic "$($_.Name)" $_.Value.Replace(',', '') }
It uses XML output from FxCop Metrics. You have to update the script for your actual schema.
In order to retrieve the information which Changeset was included in which Build, we use "Label Sidekick" of Team Foundation Sidekicks, where we place the Label of the Build & expect to find the newly built Changeset.
Our development process in TFS 2010 is making use of 'Gated' checkins, so we are faced with the situation that the latest checkins are not presented in Sidekicks (we actually receive the changeset of the previous build). This is explainable, since at the time the labeling takes place, the latest changes have not yet been committed.
The BuildLog does report the associated Changeset correctly.
I 've made several experiments in our Build Process Template but can't seem to get what we need.
Placing, for example, the Labeling activity out of the "Run On Agent" scope, lead me to a build that fails at the very start with an "Object reference not set to an instance of an object." (I suppose this is related with fact I had to widen the scope for 'Label' & 'Workspace' variables to get the second part running).
The 'before' state of the build process template for this attempt is here (this works), the 'after' state ("Object ref not set..") is here.
So, to summarize, two different types of input could help me out:
How should I change our build process template so that the labeling happens after the Gated checkins have been committed? (-- This would rationalize the display in Sidekicks)
or
How can I programmatically retrieve the associated Changeset of each Build? (-- This would enable me to write a small app that could obsolete the Sidekicks angle)
You can use the TFS API to get this done.
public static void GetBuild()
{
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://tfsdevlonuk:8080/tfs/gazprom.mt"), new UICredentialsProvider());
tfs.EnsureAuthenticated();
var buildServer = tfs.GetService<IBuildServer>();
// Get Project Name
var versionControl = tfs.GetService<VersionControlServer>();
var teamProjects = versionControl.GetAllTeamProjects(true);
// Get Builds for a team project
var buildDetails = buildServer.QueryBuilds(teamProjects[0].Name);
// For each build
foreach (IBuildDetail buildDetail in buildDetails)
{
// Get the build details
var buildInfor = buildDetail.Information;
// More build infor like shelveset, etc
Debug.Write(buildDetail.LabelName + buildDetail.ShelvesetName);
}
The above code will help you get the build details programatically. I have some blog posts on how to connect to tfs programmatically and use the tfs api. http://geekswithblogs.net/TarunArora/archive/2011/06/18/tfs-2010-sdk-connecting-to-tfs-2010-programmaticallyndashpart-1.aspx