Azure DevOps SDK(非API) – 获取构建的发布

huangapple go评论76阅读模式
英文:

Azure DevOps SDK (not API) - getting releases for a build

问题

我正在编写一个Web应用程序,该应用程序使用Azure DevOps的.NET SDK包。我正在显示来自特定团队迭代的更改集(目前仅支持TFS)。我查看任务并检查更改集和链接的构建,然后检查这些构建的状态并显示构建是否成功。

我的问题是如何找到与每个单独构建相关的发布。如果您进入组织中的某个构建,就会看到一个"发布"选项卡,显示了相关的发布以及其各个阶段的状态,因此Microsoft正在使用某种方法/ API来实现这一点。我正在尝试使用旧的XAML管道,而不是YAML。

查看我提到的选项卡的链接如下:“https://dev.azure.com/organizationName/projectName/_build/results?buildId=22224&view=ms.vss-releaseManagement-web.deployments-tab”,其中22224是构建ID。

我想知道是否有用于此的SDK方法,作为最后的手段,如果SDK没有提供,我可以直接使用API。

目前,我正在获取构建信息如下:

build = await buildClient.GetBuildAsync(projectId, int.Parse(buildId));

这个构建有一个RetainedByRelease属性,即使发布失败,并且构建中没有任何与发布相关的内容,它也可能为true。如果我首先查看发布并通过构建定义ID进行筛选,这不是理想的,因为可以有多个发布管道使用相同构建定义的工件。此外,可能会连续发生多次发布,因此通过构建的FinishDate进行筛选效果不佳。有时发布是手动完成的,距离构建结束1天后。

有什么方法可以精确定位从特定构建执行的确切发布吗?

NuGet包使用情况如下:

<PackageReference Include="Microsoft.TeamFoundationServer.Client" Version="16.205.1" />
<PackageReference Include="Microsoft.VisualStudio.Services.InteractiveClient" Version="16.205.1" />
<PackageReference Include="Microsoft.VisualStudio.Services.Release.Client" Version="16.205.1" />
英文:

I'm writing a web app that makes use of the .NET SDK packages for Azure DevOps. I'm displaying changesets (TFS only currently) from a specific team's iteration. I look into the tasks and check for changesets and linked builds.Then I check the status of those builds and display whether the build was successful.

My problem is finding the releases related to each individual build. If you go to a build in your organization, there's a Release tab that shows the related release and the status of its stages so Microsoft are using some method/API to do that. I'm trying this with the older XAML pipelines, not YAML.

The link to view that tab I mentioned would be: "https://dev.azure.com/organizationName/projectName/_build/results?buildId=22224&amp;view=ms.vss-releaseManagement-web.deployments-tab" where 22224 is the build ID.

I would like to know if there's an SDK method for that, and as a last resort, if the SDK doesn't have it, I could use the API directly.

Currently, I'm getting the build info like that:

build = await buildClient.GetBuildAsync(projectId, int.Parse(buildId));

This has a property RetainedByRelease which could be true even if a release failed and there's nothing in the build linking it to a Release. If I go looking into the releases first and filtering them by the Artifacts (using the build definition ID), it's not ideal because there could be multiple release pipelines using artifacts from the same build definition. Also, there could be multiple releases happening almost immediately one after the other so filtering by the FinishDate of the build doesn't work great. Sometimes a release is done manually, 1 day after the build.

Any ideas how to pinpoint the exact Release that was done from a specific build?

NuGet packages used:

&lt;PackageReference Include=&quot;Microsoft.TeamFoundationServer.Client&quot; Version=&quot;16.205.1&quot; /&gt;
&lt;PackageReference Include=&quot;Microsoft.VisualStudio.Services.InteractiveClient&quot; Version=&quot;16.205.1&quot; /&gt;
&lt;PackageReference Include=&quot;Microsoft.VisualStudio.Services.Release.Client&quot; Version=&quot;16.205.1&quot; /&gt;

答案1

得分: 0

好的,以下是翻译好的部分:

首先,这是我最终完成的方式。首先,我会获取过去30天内完成的所有发布(未按定义筛选),然后筛选出前100个。

var releases = await pipelinesHttpClient2.GetReleasesAsync2(projectId, minCreatedTime: DateTime.Now.AddDays(-30),
                    expand: ReleaseExpands.Artifacts | ReleaseExpands.Environments, top: 100, statusFilter: ReleaseStatus.Active);

在此之后,我使用foreach循环获取构建信息,但如果可能的话,首先获取构建信息并检查构建是否成功,然后再查找发布。无论如何,首先获取构建:

build = await buildClient.GetBuildAsync(projectId, int.Parse(buildId));

您可以检查它是否成功:

build.Result == BuildResult.Succeeded || build.Result == BuildResult.PartiallySucceeded

现在,使用我们之前获取的releases,我们将检查具有与构建ID相同ID的Artifact的发布,可以这样找到它:

var releasesForBuild = releases.Where(x => Convert.ToInt32(x.Artifacts.Where(a => a.IsPrimary)
                                        .SingleOrDefault()?.DefinitionReference["version"].Id) == build.Id);

另一个有用的属性是DefinitionReference["version"].Name,请查看一下。

我们编写的表达式可能会为该Artifact返回多个发布,但让我们假设我们只关心一个,我们可以使用FirstOrDefault()来获取它。

var specificRelease = releasesForBuild.FirstOrDefault();

现在,下一个要点是,此发布可能有多个阶段,在某些情况下,您可能根本不关心某些阶段。我还没有在阶段上添加筛选条件,但如果您想检查至少有一个阶段是否成功,可以这样做:

isReleasedSuccessfully = specificRelease?.Environments
                                 .Any(x => x.Status == EnvironmentStatus.Succeeded || x.Status == EnvironmentStatus.PartiallySucceeded) ?? false;

希望这对您有所帮助,我花了一些时间来编写这个。

英文:

OK, so here's how I ended up doing it. First of all, I'd get all releases (not filtered by definition) that were done in the last 30 days and I will filter the top 100.

var releases = await pipelinesHttpClient2.GetReleasesAsync2(projectId, minCreatedTime: DateTime.Now.AddDays(-30),
                expand: ReleaseExpands.Artifacts | ReleaseExpands.Environments, top: 100, statusFilter: ReleaseStatus.Active);

I have a foreach after that where I get the build info but if you could, first get the build info and check if the build succeeded and only then look for a release. Anyway, get the build:

build = await buildClient.GetBuildAsync(projectId, int.Parse(buildId));

You can check if it succeeded or not:

build.Result == BuildResult.Succeeded || build.Result == BuildResult.PartiallySucceeded

Now using the releases we got earlier, we will check for releases that have an Artifact with the same Id as the build Id, and you can find that like so:

var releasesForBuild = releases.Where(x =&gt; Convert.ToInt32(x.Artifacts.Where(a =&gt; a.IsPrimary)
                                    .SingleOrDefault()?.DefinitionReference[&quot;version&quot;].Id) == build.Id);

Another useful property would be DefinitionReference[&quot;version&quot;].Name, check it out.

The expression we wrote could return multiple releases for that Artifact but let's assume we care for one, we can use FirstOrDefault() to get it.

var specificRelease = releasesForBuild.FirstOrDefault();

Now the next point is that this release could have multiple stages, in some cases, stages you don't even care about. I haven't added filtering on the stages yet, but if you'd like to check if at least one succeeded, you could do it like so:

isReleasedSuccessfully = specificRelease?.Environments
                             .Any(x =&gt; x.Status == EnvironmentStatus.Succeeded || x.Status == EnvironmentStatus.PartiallySucceeded) ?? false;

I hope that was helpful, it took me some time.

huangapple
  • 本文由 发表于 2023年7月27日 18:29:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76778842.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定