Dears
Please help me to work with VssConnection from Microsoft.VisualStudio.Services.Client.15.134.0-preview package
I need to get pending changes for workspace, query it for conflict and commit
This is how i do it with TfsTeamProjectCollection and
var vssCred = new VssClientCredentials();
using (TfsTeamProjectCollection collection = new TfsTeamProjectCollection(uri, vssCred))
{
collection.Authenticate();
var scs = collection.GetService<VersionControlServer>();
var scsProject = scs.GetTeamProject(teamProjectName);
var workspace = scsProject.VersionControlServer.GetWorkspace(localPath);
var pending = scs.QueryPendingSets(new string[] { "$/" }, RecursionType.Full, workspace.Name, loginName);
if (pending.Any())
{
var pendingChanges = new[] { pending.First().PendingChanges.First() };
var validation = workspace.EvaluateCheckin2(CheckinEvaluationOptions.Conflicts, pendingChanges, "", null, null);
var conflicts = validation.Conflicts;
if (conflicts != null && conflicts.Any())
{
var message = string.Join("\r\n", conflicts.Select(_ => string.Format("{0} {1}", _.Message, _.ServerItem)));
throw new ArgumentException(string.Format("conflict was found\r\n{0}", message));
}
var res = workspace.CheckIn(pendingChanges, "test checkin");
TestContext.WriteLine("checked in {0}", res);
}
}
However there are vsts integration samples that uses VssConnection object
How can I get the same VersionControlServer from VssConnection instance?
I've tried to find Microsoft.TeamFoundation.VersionControl.Client.WebAPi (like Microsoft.TeamFoundation.WorkItemTracking.WebApi) but failed.
var vssCred = new VssClientCredentials();
using (VssConnection connection = new VssConnection(uri, vssCred))
{
var prj = connection.GetClient<ProjectHttpClient>();
var p = prj.GetProject(teamProjectName).Result;
//i'd like to get prj.VersionControl here
//or something like var scs = connection.GetService<VersionControlServer>();
}
Is it possible to get versionControlServer from VssConnection? Should I continue to use TfsTeamProjectCollection to do this task?
You could use TfsTeamProjectCollection as before, as there is no workspace method in VssConnection:
TfvcHttpClient tfvcClient = connection.GetClient<TfvcHttpClient>();
List <TfvcItem> tfvcItems = tfvcClient.GetItemsAsync("$/", VersionControlRecursionType.OneLevel).Result;
More examples, you can refer to the link below:
https://learn.microsoft.com/en-us/vsts/integrate/get-started/client-libraries/samples?view=vsts
Related
Here is the case. I wrote a tool to create a task WorkItem (version 12.0.0.0), it can run normally and create TFS task last month. But Today, when I rerun it, it doesn't create TFS task and show error message: The field "Assigned To" contains the value "email address" that is not in the list of supported values.
NetworkCredential credential = new NetworkCredential("user", "password");
TfsConfigurationServer configurationServer = new TfsConfigurationServer(tfsUri, credential);
ReadOnlyCollection<CatalogNode> collectionNodes = configurationServer.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None);
foreach (CatalogNode collectionNode in collectionNodes)
{
Guid collectionId = new Guid(collectionNode.Resource.Properties["InstanceId"]);
TfsTeamProjectCollection teamProjectCollection = configurationServer.GetTeamProjectCollection(collectionId);
ReadOnlyCollection<CatalogNode> projectNodes = collectionNode.QueryChildren(new[] { CatalogResourceTypes.TeamProject }, false, CatalogQueryOptions.None);
foreach (CatalogNode projectNode in projectNodes)
{
Console.WriteLine("Team Project: " + projectNode.Resource.DisplayName);
}
WorkItemStore workstore = teamProjectCollection.GetService<WorkItemStore>();
Project project = workstore.Projects["SpecifiedProject"];
WorkItemType itemtype = project.WorkItemTypes["Task"];
WorkItem workItem = new WorkItem(itemtype);
string assignedTo;
assignedTo = String.Format("{0}#***.com", task.User);
workItem.Fields["Assigned to"].Value = assignedTo;
workItem.Fields["Priority"].Value = task.Priority;
workItem.Fields["Area Path"].Value = AREAPATH;
workItem.Fields["Iteration path"].Value = task.IterationPath;
workItem.Title = task.Title;
workItem.Fields["DESCRIPTION"].Value = task.Description;
workItem.Fields["Original Estimate"].Value = task.EstimatedTime.ToString();
workItem.Fields["Completed Work"].Value = task.ActualTime.ToString();
workItem.Fields["Remaining Work"].Value = task.RemainTime.ToString();
// get the link type for hierarchical relationships
var linkType = workstore.WorkItemLinkTypes[CoreLinkTypeReferenceNames.Hierarchy];
//var linkType = workstore.WorkItemLinkTypes[CoreLinkTypeReferenceNames.Dependency];
RelatedLink rl = new RelatedLink(linkType.ReverseEnd, task.UserStoryID);
workItem.Links.Add(rl);
ArrayList ValidationResult = workItem.Validate();
I think this code block "ArrayList ValidationResult = workItem.Validate();" has some issues, for detail error: enter image description here
I'm trying to install Umbraco without using the visual interface, in order to increase my productivity.
Currently my code looks like this:
var installApiController = new InstallApiController();
var installSetup = installApiController.GetSetup();
var instructions = new Dictionary<string, JToken>();
var databaseModel = new DatabaseModel
{
DatabaseType = DatabaseType.SqlCe
};
var userModel = new UserModel
{
Email = "my#email.com",
Name = "My name",
Password = "somepassword",
SubscribeToNewsLetter = false
};
foreach (var step in installSetup.Steps)
{
if (step.StepType == typeof(DatabaseModel))
{
instructions.Add(step.Name, JToken.FromObject(databaseModel));
}
else if (step.StepType == typeof(UserModel))
{
instructions.Add(step.Name, JToken.FromObject(userModel));
}
}
var installInstructions = new InstallInstructions
{
InstallId = installSetup.InstallId,
Instructions = instructions
};
InstallProgressResultModel progressInfo = null;
do
{
string stepName = "";
if (progressInfo != null)
{
stepName = progressInfo.NextStep;
}
try
{
progressInfo = installApiController.PostPerformInstall(installInstructions);
}
catch (Exception e)
{
throw new Exception(stepName, e);
}
}
while (progressInfo.ProcessComplete == false);
The code fails at this line: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7.8/src/Umbraco.Web/Install/InstallSteps/NewInstallStep.cs#L47, and I believe it's because the ApplicationContext isnt updated for each of the installation steps (e.g. not updated after the database is created).
Is it possible to update the ApplicationContext manually after each step in the installation progress, or do I have to trigger all installation steps in separate HTTP requests?
The code works, if I run each step in separate HTTP requests.
Trying to fetch latest checked in information using TfvcHttpClient class from a specific folder in Team Foundation Server using its client API from a console application.
Please help how can I achieve it? I have personal access token and below mentioned is able to connect by using it:
Code:
string uri = _uri;
string personalAccessToken = _personalAccessToken;
string project = _project;
string credentials = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", personalAccessToken)));
//create wiql object
var wiql = new
{
query = "Select [State], [Title] " +
"From WorkItems " +
"Where [Work Item Type] = 'Bug' " +
"And [System.TeamProject] = '" + project + "' " +
"And [System.State] <> 'Closed' " +
"Order By [State] Asc, [Changed Date] Desc"
};
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(uri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
//serialize the wiql object into a json string
var postValue = new StringContent(JsonConvert.SerializeObject(wiql), Encoding.UTF8, "application/json"); //mediaType needs to be application/json for a post call
//send query to REST endpoint to return list of id's from query
var method = new HttpMethod("POST");
var httpRequestMessage = new HttpRequestMessage(method, uri + "/_apis/wit/wiql?api-version=2.2") { Content = postValue };
var httpResponseMessage = client.SendAsync(httpRequestMessage).Result;
}
I have tried below mentioned code for achieving:
VssConnection connection = new VssConnection(serverUrl, new
VssBasicCredential(string.Empty, _personalAccessToken));
var buildServer = connection.GetClient<BuildHttpClient>(); // connect to the build server subpart
var sourceControlServer = connection.GetClient<Microsoft.TeamFoundation.SourceControl.WebApi.TfvcHttpClient>(); // connect to the TFS source control subpart
var changesets = buildServer.GetChangesBetweenBuildsAsync("client-rsa", 1, 5).Result;
foreach (var changeset in changesets)
{
var csDetail = sourceControlServer.GetChangesetAsync("client-rsa", Convert.ToInt32(changeset.Id.Replace("C", string.Empty).Trim()), includeDetails: true).Result;
var checkinNote = csDetail.CheckinNotes?.FirstOrDefault(_ => _.Name == "My check-in note");
if (checkinNote != null)
{
Console.WriteLine("{0}: {1}", changeset.Id, changeset.Message);
Console.WriteLine("Check-in note: {0}", checkinNote.Value);
}
else
Console.WriteLine("Warning: {0} has no check-in note", changeset.Id);
}
Here is the simple sample code which use TfvcHttpClient to get the latest changeset information:
string purl = "https://xxx.visualstudio.com";
string projectname = "projectname";
VssCredentials creds = new VssClientCredentials();
creds.Storage = new VssClientCredentialStorage();
VssConnection vc = new VssConnection(new Uri(purl),creds);
TfvcHttpClient thc = vc.GetClient<TfvcHttpClient>();
TfvcChangesetSearchCriteria tcsc = new TfvcChangesetSearchCriteria();
//Specify the server path of the folder
tcsc.ItemPath = "$/XXXX/XXXX";
//Get the entire history of the specified path
List<TfvcChangesetRef> changerefs = thc.GetChangesetsAsync(projectname,null,null,null,null,tcsc).Result;
//Get the latest changeset ref
TfvcChangesetRef changeref = changerefs.First();
//Get the changeset
TfvcChangeset changeset = thc.GetChangesetAsync(projectname,changeref.ChangesetId).Result;
//Get the detailed changes
List<TfvcChange> changes = thc.GetChangesetChangesAsync(changeref.ChangesetId).Result;
foreach (TfvcChange cg in changes)
{
//Code to read detail information
}
I am trying below C# code to create TFS test run. But every time I am getting below error. Though I have given test plan details. I couldnt even find documentations on this.
Error
An exception of type 'Microsoft.TeamFoundation.TestManagement.WebApi.TestObjectNotFoundException' occurred in mscorlib.dll but was not handled in user code
Additional information: Test plan {0} not found.
Code
public async Task CreateTestRun()
{
TestManagementHttpClient witClient = connection.GetClient<TestManagementHttpClient>();
TestCaseResultUpdateModel TestCaseResultUpdateModel = new TestCaseResultUpdateModel();
ShallowReference testPlanReference = new ShallowReference();
testPlanReference.Id = "{TestPlanId}";
testPlanReference.Name = "{TestPlanName}";
testPlanReference.Url = "http://{TFSInstance}/{Project}/_apis/test/plans/{TestPlanID}";
RunCreateModel RunCreateModel = new RunCreateModel("SWAT-Run","",new int[] {2304187},testPlanReference,
null,0,"",false,"Error Message","","","","","comment","","", "",
null, null, null, null,null,"","","","",new TimeSpan(0,0,10,0,0),"",null);
TestRun testRun = await witClient.CreateTestRunAsync(this.Project, RunCreateModel, null);
}
I have done it succssful with below code, hope it can be helpful to you.
var tfsRun = _testPoint.Plan.CreateTestRun(false);
tfsRun.DateStarted = DateTime.Now;
tfsRun.AddTestPoint(_testPoint, _currentIdentity);
tfsRun.DateCompleted = DateTime.Now;
tfsRun.Save(); // so results object is created
var result = tfsRun.QueryResults()[0];
result.Owner = _currentIdentity;
result.RunBy = _currentIdentity;
result.State = TestResultState.Completed;
result.DateStarted = DateTime.Now;
result.Duration = new TimeSpan(0L);
result.DateCompleted = DateTime.Now.AddMinutes(0.0);
var iteration = result.CreateIteration(1);
iteration.DateStarted = DateTime.Now;
iteration.DateCompleted = DateTime.Now;
iteration.Duration = new TimeSpan(0L);
iteration.Comment = "Run from TFS Test Steps Editor by " + _currentIdentity.DisplayName;
for (int actionIndex = 0; actionIndex < _testEditInfo.TestCase.Actions.Count; actionIndex++)
{
var testAction = _testEditInfo.TestCase.Actions[actionIndex];
if (testAction is ISharedStepReference)
continue;
var userStep = _testEditInfo.SimpleSteps[actionIndex];
var stepResult = iteration.CreateStepResult(testAction.Id);
stepResult.ErrorMessage = String.Empty;
stepResult.Outcome = userStep.Outcome;
foreach (var attachmentPath in userStep.AttachmentPaths)
{
var attachment = stepResult.CreateAttachment(attachmentPath);
stepResult.Attachments.Add(attachment);
}
iteration.Actions.Add(stepResult);
}
var overallOutcome = _testEditInfo.SimpleSteps.Any(s => s.Outcome != TestOutcome.Passed)
? TestOutcome.Failed
: TestOutcome.Passed;
iteration.Outcome = overallOutcome;
result.Iterations.Add(iteration);
result.Outcome = overallOutcome;
result.Save(false);
We are using TFS 2015. I'm having a problem in retrieving non XAML build information from my C# console App using the TFS API. Actually, for one project we have setup for XAML Build definations and for another project, it is non-XAML one. I am able to connect the TFS projects and able to get the XAML defination lists. However, while trying to fetch the Non-XAML definations or builds, it is always an empty array.My code is below,
static void Main(string[] args)
{
try
{
var tfsUri = (args.Length < 1) ? new Uri(ConfigurationManager.AppSettings["ServerUri"]) : new Uri(args[0]);
var userCreds = new NetworkCredential(
ConfigurationManager.AppSettings["Tfs.User"], ConfigurationManager.AppSettings["Tfs.Password"], ConfigurationManager.AppSettings["Tfs.Domain"]);
// var tfsServer = TfsConfigurationServerFactory.GetConfigurationServer(tfsUri, userCreds);
var tfsServer = new TfsConfigurationServer(tfsUri, userCreds);
tfsServer.EnsureAuthenticated();
//// Get the catalog of team project collections
var collectionNodes = tfsServer.CatalogNode.QueryChildren(new[] { CatalogResourceTypes.ProjectCollection }, false, CatalogQueryOptions.None);
//// List the team project collections
foreach (var collectionNode in collectionNodes)
{
//// Use the InstanceId property to get the team project collection
var collectionId = new Guid(collectionNode.Resource.Properties["InstanceId"]);
var teamProjectCollection = tfsServer.GetTeamProjectCollection(collectionId);
//// Get a catalog of team projects for the collection
var projectNodes = collectionNode.QueryChildren(new[] { CatalogResourceTypes.TeamProject }, false, CatalogQueryOptions.None);
foreach (var projectNode in projectNodes)
{
/*
Console.WriteLine("Collection: " + teamProjectCollection.Name); // Print the name of the team project collection
Console.WriteLine(" Team Project: " + projectNode.Resource.DisplayName); // List the team projects in the collection
Console.WriteLine(" Team Project Id: " + projectNode.Resource.Identifier);
*/
//// Get a catalog of team builds for the collection
var buildDefinitions = new BuildDefinition();
// var buildDetailList = buildDefinitions.GetBuildDefinitionListFromProject(teamProjectCollection, projectNode.Resource.DisplayName);
buildDefinitions.GetBuildDetailsFromProject(teamProjectCollection, projectNode.Resource.DisplayName, projectNode.Resource.Identifier);
}
}
}
catch (Exception ex)
{
ErrorLogger.LogError(ex);
}
}
public class BuildDefinition
{
public void GetBuildDetailsFromProject(TfsTeamProjectCollection tfsProjectCollection, string projectName, Guid projectId)
{
var buildService = tfsProjectCollection.GetService<IBuildServer>(); // (IBuildServer)tfs.GetService(typeof(IBuildServer));
var buildDefinitionsList = GetAllBuildDefinitionsFromTheTeamProject(buildService, projectName);
foreach (var buildDefinition in buildDefinitionsList)
{
var bdentities = new BuildDefinitionEntities
{
ProjectId = projectId,
ProjectName = buildDefinition.TeamProject,
BuildTypeId = Convert.ToInt32(buildDefinition.Id),
BuildTypeName = buildDefinition.Name,
ProjectDetailPath = string.Format("{0} > {1}", buildDefinition.TeamProject, buildDefinition.Name)
};
var buildDetailSpec = buildService.CreateBuildDetailSpec(buildDefinition);
buildDetailSpec.InformationTypes = null; // for speed improvement
buildDetailSpec.MinFinishTime = DateTime.Now.AddDays(-21); // to get only builds of last 3 weeks
buildDetailSpec.MaxBuildsPerDefinition = 1; // get only one build per build definintion
buildDetailSpec.QueryDeletedOption = QueryDeletedOption.ExcludeDeleted; // get only active builds
buildDetailSpec.QueryOrder = BuildQueryOrder.FinishTimeDescending; // get the latest build only
buildDetailSpec.QueryOptions = QueryOptions.All;
var buildDetailList = buildService.QueryBuilds(buildDetailSpec).Builds;
//// List the team builds for the collection
foreach (var buildDetail in buildDetailList)
{
bdentities.BuildId = buildDetail.RequestIds[0];
bdentities.BuildName = buildDetail.BuildNumber;
bdentities.ArtefactsPath = buildDetail.DropLocation ?? "No Artefacts";
bdentities.BuildCompleted = Convert.ToDateTime(buildDetail.FinishTime) > Convert.ToDateTime(buildDetail.StartTime)
? Convert.ToDateTime(buildDetail.FinishTime)
: Convert.ToDateTime(buildDetail.StartTime);
bdentities.BuildStatus = buildDetail.Status.ToString();
bdentities.SourceGetVersion = buildDetail.SourceGetVersion ?? string.Empty;
if (!string.IsNullOrEmpty(buildDetail.Quality))
{
bdentities.BuildQuality = buildDetail.Quality;
bdentities.BuildQualityChangedDate = Convert.ToDateTime(buildDetail.LastChangedOn);
}
BuildDefinitionDbOperations.ManageTfsBuildDefinitions(bdentities);
}
}
}
private static IBuildDefinition[] GetAllBuildDefinitionsFromTheTeamProject(IBuildServer buildServer, string projectName)
{
var buildDefinitionSpec = buildServer.CreateBuildDefinitionSpec(projectName);
buildDefinitionSpec.TriggerType = DefinitionTriggerType.All;
buildDefinitionSpec.Options = QueryOptions.Definitions;
return buildServer.QueryBuildDefinitions(buildDefinitionSpec).Definitions;
}
}
Actually, I am new to this Tfs system. Would you please guide me where I am wrong?
For the vNext/non-XAML build system you have to use the TFS REST API; you can find the details here