Is there a way to download specific TFS build log? we’re using TFS 2013.
I’ve already tried to use the IBuildDetail, yet failed.
THX.
You can use the menthod “Get Build”. It returns IBuildDetail , use IBuildDetail.LogLocation property to get the log file for this build. Finally download or query it. Below is a demo code:
publicstaticvoid GetBuildLogAndReadThroughTheLog()
{
// Get all the team projects using the TFS API
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(ConfigurationManager.AppSettings["TfsUri"]));
var versionControlService = tfs.GetService<VersionControlServer>();
var teamProject = versionControlService.GetAllTeamProjects(false)[0];
// Use the build service to get build details for a team project
var buildService = tfs.GetService<IBuildServer>();
// Get the build details
var build = buildService.QueryBuilds(teamProject.Name)[0];
// Get the location of the build Log
var buildLogLocation = build.LogLocation;
// Get the log file
var logFile = versionControlService.GetItem(buildLogLocation);
// Do you want to download the file to a local path?
TextReader tr = new StreamReader(logFile.DownloadFile());
string input = null;
while ((input = tr.ReadLine()) != null)
{
}
}
}
The entire build log can be found in the Tfs_YourTeamProjectCollection database in the Tbl_BuildInformation. You can also query and get it from DataBase
More ways for you reference: https://paulselles.wordpress.com/2013/11/15/tfs-build-log-querying-build-log-data/
UPdate
Using "StreamReader" will read the log file line by line.
using (StreamReader sr = new StreamReader(buildLogLocation)
{
while (sr.Peek() >= 0)
{
// do your work here...
}
}
Related
I'm able to copy most test cases with this code (trying to copy shared steps to be part of the test case itself) but this one will not copy but I can not see any error message as to why - could anyone suggest anything else to try. See output from Immediate windows. Thanks John.
?targetTestCase.Error
null
?targetTestCase.InvalidProperties
Count = 0
?targetTestCase.IsDirty
true
?targetTestCase.State
"Ready"
?targetTestCase.Reason
"New"
foreach (ITestAction step in testSteps)
{
if (step is ITestStep)
{
ITestStep sourceStep = (ITestStep)step;
ITestStep targetStep = targetTestCase.CreateTestStep();
targetStep.Title = sourceStep.Title;
targetStep.Description = sourceStep.Description;
targetStep.ExpectedResult = sourceStep.ExpectedResult;
//Copy Attachments
if (sourceStep.Attachments.Count > 0)
{
string attachmentRootFolder = _tfsServiceUtilities.GetAttachmentsFolderPath();
string testCaseFolder = _tfsServiceUtilities.CreateDirectory(attachmentRootFolder, "TestCase_" + targetTestCase.Id);
//Unique folder path for test step
string TestStepAttachementFolder = _tfsServiceUtilities.CreateDirectory(testCaseFolder, "TestStep_" + sourceStep.Id);
using (var client = new WebClient())
{
client.UseDefaultCredentials = true;
foreach (ITestAttachment attachment in sourceStep.Attachments)
{
string attachmentPath = TestStepAttachementFolder + "\\" + attachment.Name;
client.DownloadFile(attachment.Uri, attachmentPath);
ITestAttachment newAttachment = targetTestCase.CreateAttachment(attachmentPath);
newAttachment.Comment = attachment.Comment;
targetStep.Attachments.Add(newAttachment);
}
}
}
targetTestCase.Actions.Add(targetStep);
targetTestCase.Save();
}
Since this code works for most test cases, this issue may come from the particular test case. In order to narrow down the issue, please try the following items:
Run the code on another client machine to see whether it works.
Try to modify this particular test case using the account API uses, to see whether it can be saved successfully.
Try validate the WorkItem prior to save. The validate() method will return an arraylist of invalid fields.
what I have found that the images uploaded by my application are not included in the project and that I have to include them manually image by image so what is the correct way of asp.net mvc project to let the images uploaded to be included in the project.
The following code is the one that upload the images to the folder and creates a unique name for each image. but still those images are not included in the project explorer.
public ActionResult Create(Job job, HttpPostedFileBase JobImage)
{
var value = "999999999";
var result4 = from app in db.Job where app.UniqueJobImageName.Contains(value) select app;
if(result4.FirstOrDefault() != null)
{
value = generateRandom();
}
if (ModelState.IsValid && CheckFileType(JobImage.FileName))
{
string ext = Path.GetExtension(JobImage.FileName);
var fileName = Path.GetFileName(JobImage.FileName);
job.JobImage = JobImage.FileName;
job.UniqueJobImageName = value + ext;
var path = Path.Combine(Server.MapPath("~/Images"), value + ext);
JobImage.SaveAs(path);
job.UserId = User.Identity.GetUserId();
job.jobUrl = "";
job.Month = DateTime.Now.ToString("MMMM");
job.DateAndTime = DateTime.Now;
AllJobModel all = new AllJobModel
{
JobTitle = job.JobTitle,
JobDescription = job.JobDescription,
JobImage = job.JobImage,
UniqueJobImageName = job.UniqueJobImageName,
locationName = job.locationName,
minimumSalary = job.minimumSalary.ToString(),
maximumSalary = job.maximumSalary.ToString(),
jobUrl = job.jobUrl,
PostedDate = DateTime.Now.ToString("dd/MM/yyyy"),
UserId= User.Identity.GetUserId(),
};
db.AllJobModel.Add(all);
db.SaveChanges();
db.Job.Add(job);
db.SaveChanges();
return RedirectToAction("Index","Home");
}else if (!CheckFileType(JobImage.FileName))
{
}
return View(job);
}
enter image description here
This doesn't make any sense. The uploaded images are content created by the user. They are not a deployable component of the site (or, they shouldn't be anyway). They are user-generated content, not developer resources.
If you are looking to effectively migrate your data (i.e. copy database entries and other user-generated content such as image files) from one environment to another, then that is a separate task for which you can create a separate process and/or automated script. Don't confuse it with the job of uploading a new version of your application code.
P.S. Even if what you were asking for was a sensible goal, it's impossible anyway - the executable version of your code is not the same as the code you see in Visual Studio in your project. In a modern ASP.NET application the executable code is in a different folder (even when you're running in debug mode in Visual Studio) and it has no concept or knowledge of the original project it was compiled from, or where to find it, or how to interact with it.
Background,
I am making a TFS merge tool to service out development and Branch requirements.
Withing this tool I have a business object layer that uses the Microsoft.Teamfoundation.ExtendedClient Package.
What I have
I currently have a function that does the checkin for my pending items
The 'changes' object has all my changes in it. Included and Excluded
Workspace workspace = _vcs.GetWorkspace(_workspaceName, _workspaceOwner);
WorkItemCheckinInfo checkInInfo = new WorkItemCheckinInfo(pbi, WorkItemCheckinAction.Associate);
PendingChange[] changes = workspace.GetPendingChanges();
ChangesetID = workspace.CheckIn(changes, checkInComment, null, new WorkItemCheckinInfo[] {
checkInInfo }, null);
What I need
I need to only get his list of 'Included' Pending changes.
Some have suggested using, bu this fails as ITS only has zero rows.
//get all candidate changes and promote them to included changes
PendingChange[] candidateChanges = null;
string serverPath = workspace.GetServerItemForLocalItem(_workspaceName);
List<ItemSpec> its = new List<ItemSpec>();
its.Add(new ItemSpec(serverPath, RecursionType.Full));
workspace.GetPendingChangesWithCandidates(its.ToArray(), true, out candidateChanges);
foreach (var change in candidateChanges)
{
if (change.IsAdd)
{
//ws.PendAdd(change.LocalItem);
}
else if (change.IsDelete)
{
//ws.PendDelete(change.LocalItem);
}
}
I have also tried this but SavedCheckin = null and i get an exception.
SavedCheckin savedCheckin = workspace.LastSavedCheckin;
// Create a list of pending changes.
var pendingAdds = new List<PendingChange>(workspace.GetPendingChanges());
List<PendingChange> excludedChanges = new List<PendingChange>();
for (int i = 0; i <= changes.Length - 1; i++)
{
if (savedCheckin.IsExcluded(changes[i].ServerItem))
{
excludedChanges.Add(changes[i]);
}
Console.WriteLine(changes[i].LocalItem.ToString() + " Change " + changes[i].ChangeType)
}
So I either need to iterate through the 'changes' list and remove 'Excluded' items
or there is bound to be something im missing here.
thanks in advance
Alan
There is no TFS API to get only Included changes, Included/Excluded changes sections exist in Visual Studio/Team Explorer. Visual Studio detects changes you make outside the system.
What you need is Visual Studio Extension API -- IPendingChangesExt Interface, you could refer to the article below or open a case on Visual Studio Extension side.
https://www.mztools.com/articles/2015/MZ2015007.aspx
I am trying to pass arguments to MSBuild 2.0. After research it appears that I need to do this using variables, but I cannot figure out how to incorporate this into my queue request below. I have tried parameters but that does not seem to work. Here is what I am trying to tell MSBuild #" /p:OctoPackPackageVersion=" + releaseNumber. This worked with the XAML build using IBuildRequest.ProcessParameters.
var buildClient = new BuildHttpClient(new Uri(collectionURL), new
VssCredentials(true));
var res = await buildClient.QueueBuildAsync(new Build
{
Definition = new DefinitionReference
{
Id = targetBuild.Id
},
Project = targetBuild.Project,
SourceVersion = ChangeSetNumber,
Parameters = buildArg
});
return res.Id.ToString();
vNext build system is different with legacy XAML build system, you cannot pass variable to build tasks in the build definition directly when queue the build. The code you used updated the build definition before queue the build which means that the build definition may keep changing if the variable changed.
The workaround for this would be add a variable in your build definition for example "var1" and then use this variable as the arguments for MSBuild Task:
With this, you will be able to pass the value to "var1" variable when queue the build without updating the build definition.
Build build = new Build();
build.Parameters = "{\"var1\":\"/p:OctoPackPackageVersion=version2\"}";
// OR using Newtonsoft.Json.JsonConvert
var dict = new Dictionary<string, string>{{"var1", "/p:OctoPackPackageVersion=version2"}};
build.Parameters = JsonConvert.SerializeObject(dict)
I have found this solution and it works for me excellent. I set custom parameters for convenience in build definition without updating on server:
foreach (var variable in targetBuildDef.Variables.Where(p => p.Value.AllowOverride))
{
var customVar = variables.FirstOrDefault(p => p.Key == variable.Key);
if (customVar == null)
continue;
variable.Value.Value = customVar.Value.TrimEnd('\\');
}
And then set variables values in build parameters:
using (TfsTeamProjectCollection ttpc = new TfsTeamProjectCollection(new Uri(tFSCollectionUri)))
{
using (BuildHttpClient buildServer = ttpc.GetClient<BuildHttpClient>())
{
var requestedBuild = new Build
{
Definition = targetBuildDef,
Project = targetBuildDef.Project
};
var dic = targetBuildDef.Variables.Where(z => z.Value.AllowOverride).Select(x => new KeyValuePair<string, string>(x.Key, x.Value.Value));
var paramString = $"{{{string.Join(",", dic.Select(p => $#"""{p.Key}"":""{p.Value}"""))}}}";
var jsonParams = HttpUtility.JavaScriptStringEncode(paramString).Replace(#"\""", #"""");
requestedBuild.Parameters = jsonParams;
var queuedBuild = buildServer.QueueBuildAsync(requestedBuild).Result;
First, the new build on TFS2015 which is called vNext build not MSbuild 2.0.
Which you are looking for should be Build variables. Variables give you a convenient way to get key bits of data into various parts of your build process. For the variable with Allow at queue time box checked you could be enable allow your team to modify the value when they manually queue a build.
Some tutorials may be helpful for using variables:
TFS Build 2015 (vNext) – Scripts and Variables
Passing Visual Studio Team Services build properties to MSBuild
Patrick, I was able to find a work around to my issue by updating the build definition. This is definitely not ideal but it works. As you can see below I am trying to add to the msbuild args already present. If you know a better way let me know. I really appreciate you taking the time to look at my question.
public static async Task<string> QueueNewBuild(string project, BuildDefinitionReference targetBuild, string collectionURL, string ChangeSetNumber, string ReleaseNumber, bool CreateRelease)
{
var buildClient = new BuildHttpClient(new Uri(collectionURL), new VssCredentials(true));
await Task.Delay(1000).ConfigureAwait(false);
var buildDef = await buildClient.GetDefinitionAsync(targetBuild.Project.Id, targetBuild.Id);
BuildDefinitionVariable OrigMSbuildvar = buildDef.Variables["MSBuildArgs"];
buildDef.Variables["MSBuildArgs"].Value = OrigMSbuildvar.Value + " /p:OctoPackPackageVersion=" + ReleaseNumber.ToString();
await Task.Delay(1000).ConfigureAwait(false);
buildDef = await buildClient.UpdateDefinitionAsync(buildDef);
await Task.Delay(1000).ConfigureAwait(false);
Build build = new Build
{
Definition = new DefinitionReference
{
Id = targetBuild.Id
},
Project = targetBuild.Project,
SourceVersion = ChangeSetNumber
};
await Task.Delay(1000).ConfigureAwait(false);
var res = await buildClient.QueueBuildAsync(build);
buildDef.Variables["MSBuildArgs"].Value = OrigMSbuildvar.Value;
await Task.Delay(1000).ConfigureAwait(false);
buildDef = await buildClient.UpdateDefinitionAsync(buildDef);
return res.Id.ToString();
}
I am looking for UFT and TFS integration (Run test from TFS like we did with HPQC)
I search on google but no help . If anyone know how to do this please let me know steps.
Thanks
You can use Generic Test to call QTP during the testing in TFS. Make sure QTP is installed on the test agent. See the code here for reference:
QTP TFS Generic Test Integration.
One more link for reference: Executing remote QTP scripts via Test Agents and Test Controllers.
Take a look at a solution from OpsHub.
More details:
Announcement:
http://blogs.msdn.com/b/visualstudioalm/archive/2013/05/16/enabling-seamless-integration-with-team-foundation-server-microsoft-test-professional-and-hp-alm-with-opshub-v5-3.aspx
Video:
http://opshub.com/ohrel/Resources/Videos/QTP_MTM_Video/QTP_MTM_Video.mp4
Case study:
https://customers.microsoft.com/Pages/CustomerStory.aspx?recid=17218
Take a look into this code:
import QTObjectModelLib dll from C:\Program Files (x86)\HP\Unified Functional Testing\bin location to your solution.
public void Fn_QTP()
{
qtApp.Launch();
qtApp.Visible = true;
qtApp.Options.Run.RunMode = "Fast";
qtApp.Options.Run.StepExecutionDelay = 0;
qtApp.Options.Run.ViewResults = false;
qtApp.Test.Settings.Run.OnError = "Stop";
//iterate for all test cases under selected module
// oTestSuiteDict : this dictionary conatins all the testsuites from TFS which meant to be executed.
//keys have their ID's
foreach (var item in oTestSuiteDict.Keys)
{
foreach (var TestCase in oTestSuiteDict[item].Keys)
{
Console.WriteLine("Executing TestCase : {0}", TestCase);
//update the XML file and upload in QTP
//this XML file is used to provide the data to QTP as a environment variables.
Fn_UpdateXMLFile(item, TestCase);
//Open the test Case
string scriptPath = #"path of script that will be opened in QTP (Action)";
qtApp.Open(scriptPath, true, false);
// Get a reference to the test object
qtTest = qtApp.Test; // Get reference to test object opened/created by application
qtTest.Settings.Run.OnError = "NextStep";
//check if the library is already associated.
if (qtTest.Settings.Resources.Libraries.Find(#"library path") == 1)
{
qtTest.Settings.Resources.Libraries.RemoveAll();
}
qtTest.Settings.Resources.Libraries.Add(#"Library Path");
//Console.WriteLine("Library is associated with Test");
// Get a reference to the Results Object for test results location
QTObjectModelLib.RunResultsOptions qtRRO = new QTObjectModelLib.RunResultsOptions();
// Run the test
//creates and start the instance of Stopwatch just to track the time period of testcase execution.
Stopwatch stopwatch = Stopwatch.StartNew();
qtTest.Run(qtRRO, true, null); // run the test
stopwatch.Stop();
string oTime = stopwatch.Elapsed.ToString();
oTestCaseTime.Add(TestCase, oTime);
string ostatus = qtTest.LastRunResults.Status;
oResults.Add(TestCase, ostatus);
qtTest.Close(); // Close the test
}
}
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(qtTest); // Cleanly release COM object
qtTest = null; // set object to null
//break;
//qtApp.Quit(); // Quit QTP
GC.Collect(); // Garbage collect
GC.WaitForPendingFinalizers(); // Wait for GC
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(qtApp); // Cleanly release COM Object
qtApp = null; // set to null
}
// Fn_UpdateXMLFile : function to update environment variables for qtp
//module name : the testsuite name(contains list of testcases); testcasename : testcases listed in modulename(test suite)
public void Fn_UpdateXMLFile(string modulename,string testcasename)
{
string oPath = #"path of xml file";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(oPath);
XmlNodeList nodes = xmlDoc.SelectNodes("Environment/Variable/Value");
nodes[0].InnerText = modulename;
nodes[1].InnerText = testcasename;
xmlDoc.Save(oPath);
}
//format of XML file :
<Environment>
<Variable>
<Name>ModuleName</Name>
<Value>ToolsMenu</Value>
</Variable>
<Variable>
<Name>""</Name>
<Value>""</Value>
</Variable>
</Environment>