Complete TFS Pull Request programmatically - tfs

Using the Microsoft.TeamFoundationServer.Client (15.112.1) to connect to a TFS 2017 Update 2 server we can get details about an existing PR like this:
var connection = new VssConnection(collectionUri, credentials);
var client = connection.GetClient<GitHttpClient>();
var pr = await client.GetPullRequestByIdAsync(pullRequestId);
Also, we can create new PR like this:
var pr = await client.CreatePullRequestAsync(
new GitPullRequest
{
SourceRefName = "master",
TargetRefName = "develop",
Title = "[Automatic Merge]"
},
projectName, repositoryName);
In addition, we can vote on the PR like this:
var pr = await client.CreatePullRequestReviewerAsync(
reviewer, projectName, repositoryName, pullRequestId, authorizedIdenity.Id.ToString());
Is there any way to complete the PR (overriding or not existing branch
policies) and proceed with the merge operation?

The GitHttpClient has an UpdatePullRequestAsync method.
To complete the pull request you need to update the Status property of your pull request. and use the UpdatePullRequestAsync method to complete your PR.
Please make sure that to set the the CompletionOptions property to specify whether you are merging the commit, delete the source branch etc.
So your code would look like following
pr.Status = PullRequestStatus.Completed
pr.CompletionOption = new GitPullRequestCompletionOption() { SquashMerge = true };
client.UpdatePullRequest(pr, repositoryId, pullRequestId);
EDIT:
The ByPassPolicy is not available for the released version of Microsoft.TeamFoundationServer.ExtendedClient yet.
However, if you install the pre-release NuGet Package v15.122.1-preview of library Microsoft.TeamFoundationServer.ExtendedClient, you will see the option ByPassPolicy as a property in the GitPullrequestCompletionOptions class. You can set it to true to by pass policy.

Related

How do I get TFS wiki page attachment over API

I need to download TFS wiki page attachment via the TFS API.
From MS Docs, it looks like the API alows to create it but I can't seem to find a way to get it.
Calling GET on /_apis/wiki/wikis/{wikiIdentifier}/pages/{pageId}/attachments/{attachmentId} returns Method not allowed
Then I tried to use the WIT attachments API /_apis/wit/attachments/{id} but that one does not find the attachment and returns 404. (I suspect it can access only work items attachments.)
use GitHttpClient.GetItemContentAsync({project}, {repositoryId}, path:{path})
where
path is "/.attachments/my attached file-89553727-xxx-yyy-zzz-829fbe167411.docx" as found in the wiki page content (note the leading /)
Found this completely by accident once I moved to experimenting with GitHttpClient and listed all items in my repo. One of the items was an attachment and it had this path populated which I then plugged into the GetItemContentAsync method and voila.
My piece of code:
var uri = new Uri(_tfsBaseUri);
var credentials = GetCredentials();
using (var tpc = new TfsTeamProjectCollection(uri, credentials))
{
var wikiClient = tpc.GetClient<WikiHttpClient>();
var gitClient = tpc.GetClient<GitHttpClient>();
var mypage = wikiClient.GetPageAsync(_tfsProject, _tfsWiki, "My page name", includeContent: true).GetAwaiter().GetResult();
var pageContent = mypage.Page.Content;
if (pageContent.Contains("(.attachments"))
{
var path = "";// parse out the attachment path
var attachmentContent = gitClient.GetItemContentAsync(_tfsProject, new Guid("_tfsWiki repo ID"), path: path).GetAwaiter().GetResult();
}
}
private static VssCredentials GetCredentials()
{
return new VssCredentials(new Microsoft.VisualStudio.Services.Common.WindowsCredential(CredentialCache.DefaultCredentials));
}
Actually the TFS/Azure DevOps Server Wiki are just Git repos, so if you want you can clone them and get all the content by using
Git clone "https://{instance}/{collection}/{project}/_git/{projectName}"
If it's the default project wiki. If you want to get a wiki based on a git repo, then you just clone the repo in question and get the content.
Update:
Your attachments will be in the .attachments folder.

How access message of git commits from Microsoft.TeamFoundation.WorkItemTracking.Client?

I'm using TFS 2017 update 1 on premises. I'm using #ID in log comments of commits in order to associate workitem ID (of User Story, Task etc.) with GIT commits of source code. It properly works (I can see links to commit from workitem interface).
I'd like to use TFS SDK API with tfs aggregator in order to better manage GIT commits (e.g. automatic transition to custom state of workitem when a specific custom git commit message is done by programmers).
How can access message/log of git commits from Microsoft.TeamFoundation.WorkItemTracking.Client in order be able to parser custom message in addition to those described here (e.g. "Fixes #123" or "Close #123")?
You can't get the commit comment only with WorkItemHttpClient, you can get it along with GitHttpClient. first of all get the work item links with WorkItemHttpClient, than get the commit id and get the comment with GitHttpClient.
A working example:
VssClientCredentials cred = new VssClientCredentials();
VssConnection tfs = new VssConnection(new Uri("http://tfs-server:8080/tfs/collection"), cred);
var workItemClient = tfs.GetClient<WorkItemTrackingHttpClient>();
var gitClient = tfs.GetClient<GitHttpClient>();
int workItemId = 1213;
var workItem = workItemClient.GetWorkItemAsync("Project-Name", workItemId, expand: WorkItemExpand.Relations).Result;
// We need to retrieve the commit id from the links, debug the following line to understand what I did
var commitId = wit.Relations.Where(r => r.Url.Contains("Git")).FirstOrDefault().Url.Split('%')[2].Remove(0,2);
var commit = gitClient.GetCommitAsync("Project-Name", commitId, "Repo-Name").Result;
string comment = commit.comment;
By the way, you can't use the Fixes #123 syntax because is not supported in TFS 2017.

Getting #Mention to work with a TFS Extension on TFS 2017.3

I am trying to programmatically add the mention of users that are members of groups in TFS in the discussion area of work items. We were using the 1.0 version with TFS 2017 update 2 with success:
#{id.DisplayName}
However upgrading to TFS 2017 update 3 fails to send emails on the notifications. We also tried all of the "user ids" we could find on the TeamFoundationIdentitiy object for the solutions found here:
VSTS - uploading via an excel macro and getting #mentions to work
So how can we get emails for #mentions to work again in TFS 2017.3?
Update: 9/11/2018
Verified service account fails to send emails while my account running the same code will send emails for mentions:
using (var connection = new VssConnection(collectionUri, cred))
using (var client = connection.GetClient<WorkItemTrackingHttpClient>())
{
var wi = new JsonPatchDocument
{
new JsonPatchOperation()
{
Operation = Operation.Add,
Path = "/fields/System.History",
Value = $"#{id.DisplayName} <br/>"
}
};
using (var response = client.UpdateWorkItemAsync(wi, workItemId, suppressNotifications: false))
{
response.Wait();
}
}
We solved by dropping use of the WorkItemHttpClient and going back to loading the SOAP WorkItemStore as the user that submitted the changes instead of the service account. It would be nice if we could use impersonation of a user with TFS's WebApi

How access git commits from Microsoft.TeamFoundation.WorkItemTracking.Client

I'm using TFS 2017 update 1 on premises. I'm using #ID in log comments of commits in order to associate workitem ID (of User Story, Task etc.) with GIT commits of source code. It properly works (I can see links to commit from workitem interface) but I'd like to use TFS SDK API with tfs aggregator in order to better manage GIT commits (e.g. dashboards using custom fields) . How can access git commits from Microsoft.TeamFoundation.WorkItemTracking.Client ?
The git commits are linked to workitems with "ExternalLink" type. So you can get the links of the work item to query that information.
WorkItemStore wis = ttpc.GetService<WorkItemStore>();
int workitemid = 1;
WorkItem wi = wis.GetWorkItem(workitemid);
foreach (Link w in wi.Links)
{
if (w.GetType().ToString() == "Microsoft.TeamFoundation.WorkItemTracking.Client.ExternalLink")
{
ExternalLink el = (ExternalLink)w;
Console.WriteLine(el.LinkedArtifactUri);
}
}
The LinkedArtifactUri will include the ID of the git commit. And then you can get the commit information via:
GitHttpClient ght = ttpc.GetClient<GitHttpClient>();
GitCommit gc = ght.GetCommitAsync("CommitID", "RepoID",99).Result;
Console.WriteLine(gc.Committer.Date);
Console.WriteLine(gc.Committer.Name);
foreach (GitChange gch in gc.Changes)
{
Console.WriteLine(gch.Item.Path);
}
Console.ReadLine();

TFS2018 path to api

I have a TFS2018 setup on a server and I am trying to figure out what is the path to the api. Should the path look look like this? Do I have to enable the API on the server?
https://myserver/tfs/DefaultCollection/MyProject/_apis
If I run this in code like this
var cred = new VssCredentials(
new WindowsCredential(new NetworkCredential("username", "Pass")));
var buildClient = new BuildHttpClient(new Uri("https://myserver/tfs/DefaultCollection/MyProject/_apis", UriKind.Absolute), cred);
await buildClient.CreateDefinitionAsync(buildDef);
I get the following error
Web method running:
[https://myserver/tfs/DefaultCollection/MyProject/_apis]
(OPTIONS)_apis[]
It depends on how the server was setup. If it's a fresh install, the /tfs/ is no longer used. If it's an upgrade the /tfs/ is retained to not break existing clients. And I suspect you can leave off the /_api/ part as well, as that should be automatically added.
The best way to get to the BuildCLient is to use the TFS Server or Collection object and request the server:
var collection = new TfsTeamProjectCollection(tfsCollectionUri, credential);
var buildClient = collection.GetClient<BuildHttpClient>();

Resources