Reputation: 1
I'm currently exchanging SOAP Code to REST (6.0) Code of an ADOS OnPremise Application.
private void SetIntegratedStatusForBranch(ChangesetModel changeset, Branch changesetBranch, List<Branch> allBranches)
{
VersionControlServer sourceControl = (VersionControlServer)_tfs.GetService(typeof(VersionControlServer));
ItemIdentifier[] everyBranch = allBranches.Select(b => new ItemIdentifier(GetMainBranchOfTfsPath(b).TfsPath)).ToArray();
var merges = sourceControl.TrackMerges(
new int[] { changeset.Id },
new ItemIdentifier(changesetBranch.TfsPath),
everyBranch,
null);
Branch mainBranch = GetMainBranch(changesetBranch);
IntegrationModel integrationModel = new IntegrationModel();
if (changesetBranch.TfsPath.Contains("dev-main") && !merges.Any(m => m.TargetItem.Item == mainBranch.TfsPath))
{
integrationModel.IntegrationState = IntegratedState.NotIntegrated;
integrationModel.IntegrationDate = DateTime.MinValue;
integrationModel.IntegrationChangesetId = -1;
changeset.AddIntegratedBranch(mainBranch, integrationModel);
}
if (mainBranch.TfsPath == changesetBranch.TfsPath)
{
integrationModel.IntegrationState = IntegratedState.Integrated;
integrationModel.IntegrationDate = changeset.CreationDate;
integrationModel.IntegrationChangesetId = changeset.Id;
changeset.AddIntegratedBranch(mainBranch, integrationModel);
}
else if (changesetBranch.TfsPath.Contains("dlv"))
{
integrationModel.IntegrationState = IntegratedState.Integrated;
integrationModel.IntegrationDate = changeset.CreationDate;
integrationModel.IntegrationChangesetId = changeset.Id;
changeset.AddIntegratedBranch(changesetBranch, integrationModel);
}
foreach (var merge in merges)
{
IntegrationModel integration = new IntegrationModel
{
IntegrationState = IntegratedState.Integrated,
IntegrationDate = merge.TargetChangeset.CreationDate,
IntegrationChangesetId = merge.TargetChangeset.ChangesetId
};
Branch branch = allBranches.FirstOrDefault(x => (!merge.TargetItem.Item.Contains("dlv") && merge.TargetItem.Item.Contains(x.TfsPath)) || x.TfsPath == merge.TargetItem.Item);
changeset.AddIntegratedBranch(branch, integration);
}
}
I just can't find a solution to refactor the code above. Has anyone any ideas how I could solve my issue?
In the Background we're using VS2022 and the pipeline is set, if a commit runs without errors through the pipeline it will be automatically merged (with same exceptions but those are not relevant).
I've already tried to get the merges with trying out following .NET Rest approaches:
with using snippets from: https://github.com/microsoft/azure-devops-dotnet-samples/tree/main.
I'm mainly using:
VssConnection _connection;
_connection = new VssConnection(new Uri("https://" + Settings.Default.TfsServerUri), new VssClientCredentials());
GitHttpClient gitClient = _connection.GetClient<GitHttpClient>();
etc...
I was expecting to create a workaround which basically exchanges mainly this part of the code:
var merges = sourceControl.TrackMerges(
new int[] { changeset.Id },
new ItemIdentifier(changesetBranch.TfsPath),
everyBranch,
null);
Upvotes: 0
Views: 84
Reputation: 1
So, Miao Tian was on the right Track. There are two approaches:
I. Use the REST API:
to 2:
string apiUrl = $"https://{Settings.Default.TfsServerUri}/_apis/tfvc/changesets/{responseChangesetId}/changes?api-version=6.0";
HttpResponseMessage response = HttpHelper.Client.GetAsync(apiUrl).GetAwaiter().GetResult();
if (!response.IsSuccessStatusCode)
{
return (false, $"Failed to retrieve changeset changes: {response.StatusCode}", "");
}
string responseBody = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var changesResponse = JsonConvert.DeserializeObject<ChangesetChangesResponse>(responseBody);
foreach (var changesResponseItem in changesResponse.Value)
{
if ((changesResponseItem.ChangeType.Contains("merge") ||
changesResponseItem.ChangeType.Contains("rollback")) && ...
to 1:
DateTime updatedToDateTime = toDateTime.AddDays(7);
string baseApiUrl = $"https://{Settings.Default.TfsServerUri}/{Settings.Default.ProjectName}/_apis/tfvc/changesets";
TfvcChangesetSearchCriteria searchCriteria = new TfvcChangesetSearchCriteria()
{
FromDate = fromDate.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
ToDate = updatedToDateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"),
ItemPath = "$/ProjectName"
};
string apiUrl = $"{baseApiUrl}?api-version=6.0";
apiUrl += $"&fromDate={searchCriteria.FromDate}&toDate={searchCriteria.ToDate}&itemPath={searchCriteria.ItemPath}";
int skip = 0;
const int top = 100;
while (true)
{
string pagedUrl = $"{apiUrl}&$top={top}&$skip={skip}";
HttpResponseMessage response = HttpHelper.Client.GetAsync(pagedUrl).GetAwaiter().GetResult();
if (!response.IsSuccessStatusCode)
{
Console.WriteLine($"Failed to retrieve changesets: {response.StatusCode}");
break;
}
string responseBody = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var changesetResponse = JsonConvert.DeserializeObject<ChangesetResponse>(responseBody);
etc. You need to iterate through all pages (pagination) because ADOS only gives 100 entries at the time.
II. Use .NET
The second approach would be using .NET. Basically the same approach but without the need of the PAT. I had though the issue that .NET performance was worse and the checking for the merges took longer. More information on this: https://github.com/microsoft/azure-devops-dotnet-samples/blob/main/ClientLibrary/Samples/Tfvc/ChangesetChangesSample.cs
P.S. It is better to use a synchronous method. I had the issue that values where looked after couple of times unnecessarily.
Upvotes: 0
Reputation: 5642
I checked the document of Microsoft.TeamFoundation.SourceControl.WebApi but seems no direct one-to-one mapping for the TrackMerges
method.
This is TfvcMergeSource. You can explore the available methods to achieve similar functionality.
Upvotes: 0