mirror of
https://github.com/actions/runner.git
synced 2025-12-12 05:37:01 +00:00
Remove old "v1" artifact download/publish code (#212)
* Remove old v1 artifact download/publish code * Remove the Build2 REST API SDK
This commit is contained in:
@@ -1,58 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Runner.Sdk;
|
||||
using GitHub.Services.WebApi;
|
||||
using GitHub.Build.WebApi;
|
||||
|
||||
namespace GitHub.Runner.Plugins.Artifact
|
||||
{
|
||||
// A client wrapper interacting with Build's Artifact API
|
||||
public class BuildServer
|
||||
{
|
||||
private readonly BuildHttpClient _buildHttpClient;
|
||||
|
||||
public BuildServer(VssConnection connection)
|
||||
{
|
||||
ArgUtil.NotNull(connection, nameof(connection));
|
||||
_buildHttpClient = connection.GetClient<BuildHttpClient>();
|
||||
}
|
||||
|
||||
// Associate the specified artifact with a build, along with custom data.
|
||||
public async Task<BuildArtifact> AssociateArtifact(
|
||||
Guid projectId,
|
||||
int pipelineId,
|
||||
string jobId,
|
||||
string name,
|
||||
string type,
|
||||
string data,
|
||||
Dictionary<string, string> propertiesDictionary,
|
||||
CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
BuildArtifact artifact = new BuildArtifact()
|
||||
{
|
||||
Name = name,
|
||||
Source = jobId,
|
||||
Resource = new ArtifactResource()
|
||||
{
|
||||
Data = data,
|
||||
Type = type,
|
||||
Properties = propertiesDictionary
|
||||
}
|
||||
};
|
||||
|
||||
return await _buildHttpClient.CreateArtifactAsync(artifact, projectId, pipelineId, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
// Get named artifact from a build
|
||||
public async Task<BuildArtifact> GetArtifact(
|
||||
Guid projectId,
|
||||
int pipelineId,
|
||||
string name,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return await _buildHttpClient.GetArtifactAsync(projectId, pipelineId, name, cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Build.WebApi;
|
||||
using GitHub.Services.Common;
|
||||
using GitHub.Runner.Sdk;
|
||||
|
||||
@@ -40,70 +39,31 @@ namespace GitHub.Runner.Plugins.Artifact
|
||||
|
||||
targetPath = Path.IsPathFullyQualified(targetPath) ? targetPath : Path.GetFullPath(Path.Combine(defaultWorkingDirectory, targetPath));
|
||||
|
||||
// Project ID
|
||||
Guid projectId = new Guid(context.Variables.GetValueOrDefault(BuildVariables.TeamProjectId)?.Value ?? Guid.Empty.ToString());
|
||||
|
||||
// Build ID
|
||||
string buildIdStr = context.Variables.GetValueOrDefault(BuildVariables.BuildId)?.Value ?? string.Empty;
|
||||
string buildIdStr = context.Variables.GetValueOrDefault(SdkConstants.Variables.Build.BuildId)?.Value ?? string.Empty;
|
||||
if (!int.TryParse(buildIdStr, out int buildId))
|
||||
{
|
||||
throw new ArgumentException($"Run Id is not an Int32: {buildIdStr}");
|
||||
}
|
||||
|
||||
// Determine whether to call Pipelines or Build endpoint to publish artifact based on variable setting
|
||||
string usePipelinesArtifactEndpointVar = context.Variables.GetValueOrDefault("Runner.UseActionsArtifactsApis")?.Value;
|
||||
bool.TryParse(usePipelinesArtifactEndpointVar, out bool usePipelinesArtifactEndpoint);
|
||||
string containerPath;
|
||||
long containerId;
|
||||
|
||||
context.Output($"Downloading artifact '{artifactName}' to: '{targetPath}'");
|
||||
|
||||
if (usePipelinesArtifactEndpoint)
|
||||
// Definition ID is a dummy value only used by HTTP client routing purposes
|
||||
int definitionId = 1;
|
||||
|
||||
var pipelinesHelper = new PipelinesServer(context.VssConnection);
|
||||
|
||||
var actionsStorageArtifact = await pipelinesHelper.GetActionsStorageArtifact(definitionId, buildId, artifactName, token);
|
||||
|
||||
if (actionsStorageArtifact == null)
|
||||
{
|
||||
context.Debug("Downloading artifact using v2 endpoint");
|
||||
|
||||
// Definition ID is a dummy value only used by HTTP client routing purposes
|
||||
int definitionId = 1;
|
||||
|
||||
var pipelinesHelper = new PipelinesServer(context.VssConnection);
|
||||
|
||||
var actionsStorageArtifact = await pipelinesHelper.GetActionsStorageArtifact(definitionId, buildId, artifactName, token);
|
||||
|
||||
if (actionsStorageArtifact == null)
|
||||
{
|
||||
throw new Exception($"The actions storage artifact for '{artifactName}' could not be found, or is no longer available");
|
||||
}
|
||||
|
||||
containerPath = actionsStorageArtifact.Name; // In actions storage artifacts, name equals the path
|
||||
containerId = actionsStorageArtifact.ContainerId;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Debug("Downloading artifact using v1 endpoint");
|
||||
|
||||
BuildServer buildHelper = new BuildServer(context.VssConnection);
|
||||
BuildArtifact buildArtifact = await buildHelper.GetArtifact(projectId, buildId, artifactName, token);
|
||||
|
||||
if (string.Equals(buildArtifact.Resource.Type, "Container", StringComparison.OrdinalIgnoreCase) ||
|
||||
// Artifact was published by Pipelines endpoint, check new type here to handle rollback scenario
|
||||
string.Equals(buildArtifact.Resource.Type, "Actions_Storage", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
string containerUrl = buildArtifact.Resource.Data;
|
||||
string[] parts = containerUrl.Split(new[] { '/' }, 3);
|
||||
if (parts.Length < 3 || !long.TryParse(parts[1], out containerId))
|
||||
{
|
||||
throw new ArgumentOutOfRangeException($"Invalid container url '{containerUrl}' for artifact '{buildArtifact.Name}'");
|
||||
}
|
||||
|
||||
containerPath = parts[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException($"Invalid artifact type: {buildArtifact.Resource.Type}");
|
||||
}
|
||||
throw new Exception($"The actions storage artifact for '{artifactName}' could not be found, or is no longer available");
|
||||
}
|
||||
|
||||
FileContainerServer fileContainerServer = new FileContainerServer(context.VssConnection, projectId, containerId, containerPath);
|
||||
string containerPath = actionsStorageArtifact.Name; // In actions storage artifacts, name equals the path
|
||||
long containerId = actionsStorageArtifact.ContainerId;
|
||||
|
||||
FileContainerServer fileContainerServer = new FileContainerServer(context.VssConnection, projectId: new Guid(), containerId, containerPath);
|
||||
await fileContainerServer.DownloadFromContainerAsync(context, targetPath, token);
|
||||
|
||||
context.Output("Artifact download finished.");
|
||||
|
||||
@@ -4,9 +4,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Build.WebApi;
|
||||
using GitHub.Services.Common;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Sdk;
|
||||
|
||||
namespace GitHub.Runner.Plugins.Artifact
|
||||
@@ -45,11 +43,8 @@ namespace GitHub.Runner.Plugins.Artifact
|
||||
throw new ArgumentException($"Artifact name is not valid: {artifactName}. It cannot contain '\\', '/', \"', ':', '<', '>', '|', '*', and '?'");
|
||||
}
|
||||
|
||||
// Project ID
|
||||
Guid projectId = new Guid(context.Variables.GetValueOrDefault(BuildVariables.TeamProjectId)?.Value ?? Guid.Empty.ToString());
|
||||
|
||||
// Build ID
|
||||
string buildIdStr = context.Variables.GetValueOrDefault(BuildVariables.BuildId)?.Value ?? string.Empty;
|
||||
string buildIdStr = context.Variables.GetValueOrDefault(SdkConstants.Variables.Build.BuildId)?.Value ?? string.Empty;
|
||||
if (!int.TryParse(buildIdStr, out int buildId))
|
||||
{
|
||||
throw new ArgumentException($"Run Id is not an Int32: {buildIdStr}");
|
||||
@@ -65,7 +60,7 @@ namespace GitHub.Runner.Plugins.Artifact
|
||||
}
|
||||
|
||||
// Container ID
|
||||
string containerIdStr = context.Variables.GetValueOrDefault(BuildVariables.ContainerId)?.Value ?? string.Empty;
|
||||
string containerIdStr = context.Variables.GetValueOrDefault(SdkConstants.Variables.Build.ContainerId)?.Value ?? string.Empty;
|
||||
if (!long.TryParse(containerIdStr, out long containerId))
|
||||
{
|
||||
throw new ArgumentException($"Container Id is not an Int64: {containerIdStr}");
|
||||
@@ -73,7 +68,7 @@ namespace GitHub.Runner.Plugins.Artifact
|
||||
|
||||
context.Output($"Uploading artifact '{artifactName}' from '{fullPath}' for run #{buildId}");
|
||||
|
||||
FileContainerServer fileContainerHelper = new FileContainerServer(context.VssConnection, projectId, containerId, artifactName);
|
||||
FileContainerServer fileContainerHelper = new FileContainerServer(context.VssConnection, projectId: Guid.Empty, containerId, artifactName);
|
||||
var propertiesDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
long size = 0;
|
||||
@@ -89,38 +84,20 @@ namespace GitHub.Runner.Plugins.Artifact
|
||||
// if any of the results were successful, make sure to attach them to the build
|
||||
finally
|
||||
{
|
||||
// Determine whether to call Pipelines or Build endpoint to publish artifact based on variable setting
|
||||
string usePipelinesArtifactEndpointVar = context.Variables.GetValueOrDefault("Runner.UseActionsArtifactsApis")?.Value;
|
||||
bool.TryParse(usePipelinesArtifactEndpointVar, out bool usePipelinesArtifactEndpoint);
|
||||
// Definition ID is a dummy value only used by HTTP client routing purposes
|
||||
int definitionId = 1;
|
||||
|
||||
if (usePipelinesArtifactEndpoint)
|
||||
{
|
||||
// Definition ID is a dummy value only used by HTTP client routing purposes
|
||||
int definitionId = 1;
|
||||
PipelinesServer pipelinesHelper = new PipelinesServer(context.VssConnection);
|
||||
|
||||
PipelinesServer pipelinesHelper = new PipelinesServer(context.VssConnection);
|
||||
var artifact = await pipelinesHelper.AssociateActionsStorageArtifactAsync(
|
||||
definitionId,
|
||||
buildId,
|
||||
containerId,
|
||||
artifactName,
|
||||
size,
|
||||
token);
|
||||
|
||||
var artifact = await pipelinesHelper.AssociateActionsStorageArtifactAsync(
|
||||
definitionId,
|
||||
buildId,
|
||||
containerId,
|
||||
artifactName,
|
||||
size,
|
||||
token);
|
||||
|
||||
context.Output($"Associated artifact {artifactName} ({artifact.ContainerId}) with run #{buildId}");
|
||||
context.Debug($"Associated artifact using v2 endpoint");
|
||||
}
|
||||
else
|
||||
{
|
||||
string fileContainerFullPath = StringUtil.Format($"#/{containerId}/{artifactName}");
|
||||
BuildServer buildHelper = new BuildServer(context.VssConnection);
|
||||
string jobId = context.Variables.GetValueOrDefault(WellKnownDistributedTaskVariables.JobId).Value ?? string.Empty;
|
||||
var artifact = await buildHelper.AssociateArtifact(projectId, buildId, jobId, artifactName, ArtifactResourceTypes.Container, fileContainerFullPath, propertiesDictionary, token);
|
||||
|
||||
context.Output($"Associated artifact {artifactName} ({artifact.Id}) with run #{buildId}");
|
||||
context.Debug($"Associated artifact using v1 endpoint");
|
||||
}
|
||||
context.Output($"Associated artifact {artifactName} ({artifact.ContainerId}) with run #{buildId}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
src/Runner.Sdk/SdkConstants.cs
Normal file
19
src/Runner.Sdk/SdkConstants.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace GitHub.Runner.Sdk
|
||||
{
|
||||
public class SdkConstants
|
||||
{
|
||||
public static class Variables
|
||||
{
|
||||
public static class Build
|
||||
{
|
||||
// Legacy "build" variables historically used by the runner
|
||||
// DO NOT add new variables here -- instead use either the Actions or Runner namespaces
|
||||
public const String BuildId = "build.buildId";
|
||||
public const String BuildNumber = "build.buildNumber";
|
||||
public const String ContainerId = "build.containerId";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using GitHub.Build.WebApi;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.DistributedTask.Logging;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
@@ -63,7 +62,7 @@ namespace GitHub.Runner.Worker
|
||||
|
||||
// DO NOT add file path variable to here.
|
||||
// All file path variables needs to be retrive and set through ExecutionContext, so it can handle container file path translation.
|
||||
public string Build_Number => Get(BuildVariables.BuildNumber);
|
||||
public string Build_Number => Get(SdkConstants.Variables.Build.BuildNumber);
|
||||
|
||||
#if OS_WINDOWS
|
||||
public bool Retain_Default_Encoding => false;
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
using System;
|
||||
using GitHub.Services.Common;
|
||||
|
||||
namespace GitHub.Build.WebApi
|
||||
{
|
||||
public static class ArtifactResourceTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// Build container reference
|
||||
/// E.g. #/2121/drop
|
||||
/// </summary>
|
||||
public const String Container = "Container";
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Services.Common;
|
||||
using GitHub.Services.WebApi;
|
||||
using GitHub.Services.WebApi.Patch;
|
||||
using GitHub.Services.WebApi.Patch.Json;
|
||||
|
||||
namespace GitHub.Build.WebApi
|
||||
{
|
||||
public class BuildHttpClient : BuildHttpClientBase
|
||||
{
|
||||
static BuildHttpClient()
|
||||
{
|
||||
}
|
||||
|
||||
public BuildHttpClient(
|
||||
Uri baseUrl,
|
||||
VssCredentials credentials)
|
||||
: base(baseUrl, credentials)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildHttpClient(
|
||||
Uri baseUrl,
|
||||
VssCredentials credentials,
|
||||
VssHttpRequestSettings settings)
|
||||
: base(baseUrl, credentials, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildHttpClient(
|
||||
Uri baseUrl,
|
||||
VssCredentials credentials,
|
||||
params DelegatingHandler[] handlers)
|
||||
: base(baseUrl, credentials, handlers)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildHttpClient(
|
||||
Uri baseUrl,
|
||||
VssCredentials credentials,
|
||||
VssHttpRequestSettings settings,
|
||||
params DelegatingHandler[] handlers)
|
||||
: base(baseUrl, credentials, settings, handlers)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildHttpClient(
|
||||
Uri baseUrl,
|
||||
HttpMessageHandler pipeline,
|
||||
Boolean disposeHandler)
|
||||
: base(baseUrl, pipeline, disposeHandler)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace GitHub.Build.WebApi
|
||||
{
|
||||
public static class BuildResourceIds
|
||||
{
|
||||
public const String AreaId = "5D6898BB-45EC-463F-95F9-54D49C71752E";
|
||||
public const String AreaName = "build";
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace GitHub.Build.WebApi
|
||||
{
|
||||
public static class BuildVariables
|
||||
{
|
||||
public const String TeamProjectId = "system.teamProjectId";
|
||||
|
||||
public const String BuildId = "build.buildId";
|
||||
public const String BuildNumber = "build.buildNumber";
|
||||
public const String ContainerId = "build.containerId";
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using GitHub.Services.WebApi;
|
||||
|
||||
namespace GitHub.Build.WebApi
|
||||
{
|
||||
[DataContract]
|
||||
public class ArtifactResource : BaseSecuredObject
|
||||
{
|
||||
public ArtifactResource()
|
||||
{
|
||||
}
|
||||
|
||||
public ArtifactResource(
|
||||
ISecuredObject securedObject)
|
||||
: base(securedObject)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The type of the resource: File container, version control folder, UNC path, etc.
|
||||
/// </summary>
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public String Type
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Type-specific data about the artifact.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For example, "#/10002/5/drop", "$/drops/5", "\\myshare\myfolder\mydrops\5"
|
||||
/// </remarks>
|
||||
[DataMember(EmitDefaultValue = false)]
|
||||
public String Data
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Type-specific properties of the artifact.
|
||||
/// </summary>
|
||||
[DataMember(IsRequired = false, EmitDefaultValue = false)]
|
||||
public Dictionary<String, String> Properties
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using GitHub.Services.WebApi;
|
||||
|
||||
namespace GitHub.Build.WebApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an artifact produced by a build.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class BuildArtifact : BaseSecuredObject
|
||||
{
|
||||
public BuildArtifact()
|
||||
{
|
||||
}
|
||||
|
||||
internal BuildArtifact(
|
||||
ISecuredObject securedObject)
|
||||
: base(securedObject)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The artifact ID.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public Int32 Id
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the artifact.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public String Name
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The artifact source, which will be the ID of the job that produced this artifact.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public String Source
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The actual resource.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public ArtifactResource Resource
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* ---------------------------------------------------------
|
||||
* Copyright(C) Microsoft Corporation. All rights reserved.
|
||||
* ---------------------------------------------------------
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GitHub.Services.Common;
|
||||
using GitHub.Services.WebApi;
|
||||
|
||||
namespace GitHub.Build.WebApi
|
||||
{
|
||||
[ResourceArea(BuildResourceIds.AreaId)]
|
||||
public abstract class BuildHttpClientBase : VssHttpClientBase
|
||||
{
|
||||
public BuildHttpClientBase(Uri baseUrl, VssCredentials credentials)
|
||||
: base(baseUrl, credentials)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildHttpClientBase(Uri baseUrl, VssCredentials credentials, VssHttpRequestSettings settings)
|
||||
: base(baseUrl, credentials, settings)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildHttpClientBase(Uri baseUrl, VssCredentials credentials, params DelegatingHandler[] handlers)
|
||||
: base(baseUrl, credentials, handlers)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildHttpClientBase(Uri baseUrl, VssCredentials credentials, VssHttpRequestSettings settings, params DelegatingHandler[] handlers)
|
||||
: base(baseUrl, credentials, settings, handlers)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildHttpClientBase(Uri baseUrl, HttpMessageHandler pipeline, bool disposeHandler)
|
||||
: base(baseUrl, pipeline, disposeHandler)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [Preview API] Associates an artifact with a build.
|
||||
/// </summary>
|
||||
/// <param name="artifact">The artifact.</param>
|
||||
/// <param name="project">Project ID</param>
|
||||
/// <param name="buildId">The ID of the build.</param>
|
||||
/// <param name="userState"></param>
|
||||
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
|
||||
public virtual Task<BuildArtifact> CreateArtifactAsync(
|
||||
BuildArtifact artifact,
|
||||
Guid project,
|
||||
int buildId,
|
||||
object userState = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
HttpMethod httpMethod = new HttpMethod("POST");
|
||||
Guid locationId = new Guid("1db06c96-014e-44e1-ac91-90b2d4b3e984");
|
||||
object routeValues = new { project = project, buildId = buildId };
|
||||
HttpContent content = new ObjectContent<BuildArtifact>(artifact, new VssJsonMediaTypeFormatter(true));
|
||||
|
||||
return SendAsync<BuildArtifact>(
|
||||
httpMethod,
|
||||
locationId,
|
||||
routeValues: routeValues,
|
||||
version: new ApiResourceVersion(5.2, 5),
|
||||
userState: userState,
|
||||
cancellationToken: cancellationToken,
|
||||
content: content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [Preview API] Gets a specific artifact for a build.
|
||||
/// </summary>
|
||||
/// <param name="project">Project ID</param>
|
||||
/// <param name="buildId">The ID of the build.</param>
|
||||
/// <param name="artifactName">The name of the artifact.</param>
|
||||
/// <param name="userState"></param>
|
||||
/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
|
||||
public virtual Task<BuildArtifact> GetArtifactAsync(
|
||||
Guid project,
|
||||
int buildId,
|
||||
string artifactName,
|
||||
object userState = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
HttpMethod httpMethod = new HttpMethod("GET");
|
||||
Guid locationId = new Guid("1db06c96-014e-44e1-ac91-90b2d4b3e984");
|
||||
object routeValues = new { project = project, buildId = buildId };
|
||||
|
||||
List<KeyValuePair<string, string>> queryParams = new List<KeyValuePair<string, string>>();
|
||||
queryParams.Add("artifactName", artifactName);
|
||||
|
||||
return SendAsync<BuildArtifact>(
|
||||
httpMethod,
|
||||
locationId,
|
||||
routeValues: routeValues,
|
||||
version: new ApiResourceVersion(5.2, 5),
|
||||
queryParameters: queryParams,
|
||||
userState: userState,
|
||||
cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user