从代码中排队 Azure devops YAML 管道不接受运行时参数
Queue Azure devops YAML pipeline from code does not accept runtime parameters
YAML 管道如下所示
parameters:
- name: parameter1
type: string
steps:
task: PowerShell@2
inputs:
targetType: 'inline'
script: |
# Write your PowerShell commands here.
Write-Host ${{ parameters.parameter1 }}
排队构建的 C# 代码类似于
var build = new Build()
{
Definition = definition,
Project = project
};
var dict = new Dictionary<string, string> { { "parameter1", "parametervalue" } };
build.Parameters = JsonSerializer.Serialize(dict);
buildClient.QueueBuildAsync(build).Wait();
我遇到异常 无法对构建进行排队,因为存在验证错误或警告。必须提供 'parameter1' 参数的值。
解决此问题的任何想法都会有所帮助。
目前看来,通过 C# SDK 传递 运行 时间参数,运行 管道是不可能的。您找到了使用 REST API.
的解决方法
这不是 SDK 的问题。它们按照自己的节奏发展。因此,在 REST API 中可用的功能在 SDK 中并不总是在同一时刻可用。它可能在将来可用,但目前如果您想以编程方式 运行 它,您需要使用 REST API.
我设法对一些可能对其他人有帮助的客户端代码进行了逆向工程。它可能尚未完全投入生产,但请随时对其进行改进:
public class PipelineHttpClient : VssHttpClientBase
{
public PipelineHttpClient(Uri baseUrl, VssCredentials credentials)
: base(baseUrl, credentials)
{
}
public PipelineHttpClient(Uri baseUrl, VssCredentials credentials, VssHttpRequestSettings settings)
: base(baseUrl, credentials, settings)
{
}
public PipelineHttpClient(Uri baseUrl, VssCredentials credentials, params DelegatingHandler[] handlers)
: base(baseUrl, credentials, handlers)
{
}
public PipelineHttpClient(Uri baseUrl, VssCredentials credentials, VssHttpRequestSettings settings, params DelegatingHandler[] handlers)
: base(baseUrl, credentials, settings, handlers)
{
}
public PipelineHttpClient(Uri baseUrl, HttpMessageHandler pipeline, bool disposeHandler)
: base(baseUrl, pipeline, disposeHandler)
{
}
public async Task<PipelineRun> RunPipelineAsync(Guid project, int pipelineId, object parameters, string refName = "refs/heads/master")
{
var method = HttpMethod.Post;
var locationId = Guid.Parse("7859261e-d2e9-4a68-b820-a5d84cc5bb3d");
object routeValues = new
{
project,
pipelineId,
//pipelineVersion = ""
};
var version = new ApiResourceVersion("6.0");
// ensure that the refName is prefixed correctly.
refName = refName.StartsWith("refs/heads/", StringComparison.InvariantCultureIgnoreCase)
? refName
: $"refs/heads/{refName}";
var content = (HttpContent) new ObjectContent<object>(new
{
StagesToSkip = new object[0],
TemplateParameters = parameters,
Variables = new object(),
Resources = new
{
Repositories = new
{
Self = new
{
RefName = refName
}
}
}
},
new VssJsonMediaTypeFormatter(true));
var queryParameters = new Dictionary<string, string>();
return await SendAsync<PipelineRun>(method, locationId, routeValues, version, content, queryParameters, cancellationToken: CancellationToken.None);
}
}
public class Pipeline
{
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("revision")]
public int Revision { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("folder")]
public string Folder { get; set; }
}
public class Repository
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
}
public class Self
{
[JsonProperty("repository")]
public Repository Repository { get; set; }
[JsonProperty("refName")]
public string RefName { get; set; }
[JsonProperty("version")]
public string Version { get; set; }
}
public class Repositories
{
[JsonProperty("self")]
public Self Self { get; set; }
}
public class Resources
{
[JsonProperty("repositories")]
public Repositories Repositories { get; set; }
}
public class PipelineRun
{
[JsonProperty("pipeline")]
public Pipeline Pipeline { get; set; }
[JsonProperty("state")]
public string State { get; set; }
[JsonProperty("createdDate")]
public DateTime CreatedDate { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("resources")]
public Resources Resources { get; set; }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
}
用法:
PipelineHttpClient client = new PipelineHttpClient(...);
var project = Guid.Parse("TODO");
var pipelineId = 1234;
// pipeline parameters:
var parameters = new {meaningOfLife = 42};
var result = await client.RunPipelineAsync(project, pipelineId, parameters, "refs/heads/feature/my-branch");
if (result.State == "inProgress")
{
// TODO the pipeline is running!
}
YAML 管道如下所示
parameters:
- name: parameter1
type: string
steps:
task: PowerShell@2
inputs:
targetType: 'inline'
script: |
# Write your PowerShell commands here.
Write-Host ${{ parameters.parameter1 }}
排队构建的 C# 代码类似于
var build = new Build()
{
Definition = definition,
Project = project
};
var dict = new Dictionary<string, string> { { "parameter1", "parametervalue" } };
build.Parameters = JsonSerializer.Serialize(dict);
buildClient.QueueBuildAsync(build).Wait();
我遇到异常 无法对构建进行排队,因为存在验证错误或警告。必须提供 'parameter1' 参数的值。 解决此问题的任何想法都会有所帮助。
目前看来,通过 C# SDK 传递 运行 时间参数,运行 管道是不可能的。您找到了使用 REST API.
的解决方法这不是 SDK 的问题。它们按照自己的节奏发展。因此,在 REST API 中可用的功能在 SDK 中并不总是在同一时刻可用。它可能在将来可用,但目前如果您想以编程方式 运行 它,您需要使用 REST API.
我设法对一些可能对其他人有帮助的客户端代码进行了逆向工程。它可能尚未完全投入生产,但请随时对其进行改进:
public class PipelineHttpClient : VssHttpClientBase
{
public PipelineHttpClient(Uri baseUrl, VssCredentials credentials)
: base(baseUrl, credentials)
{
}
public PipelineHttpClient(Uri baseUrl, VssCredentials credentials, VssHttpRequestSettings settings)
: base(baseUrl, credentials, settings)
{
}
public PipelineHttpClient(Uri baseUrl, VssCredentials credentials, params DelegatingHandler[] handlers)
: base(baseUrl, credentials, handlers)
{
}
public PipelineHttpClient(Uri baseUrl, VssCredentials credentials, VssHttpRequestSettings settings, params DelegatingHandler[] handlers)
: base(baseUrl, credentials, settings, handlers)
{
}
public PipelineHttpClient(Uri baseUrl, HttpMessageHandler pipeline, bool disposeHandler)
: base(baseUrl, pipeline, disposeHandler)
{
}
public async Task<PipelineRun> RunPipelineAsync(Guid project, int pipelineId, object parameters, string refName = "refs/heads/master")
{
var method = HttpMethod.Post;
var locationId = Guid.Parse("7859261e-d2e9-4a68-b820-a5d84cc5bb3d");
object routeValues = new
{
project,
pipelineId,
//pipelineVersion = ""
};
var version = new ApiResourceVersion("6.0");
// ensure that the refName is prefixed correctly.
refName = refName.StartsWith("refs/heads/", StringComparison.InvariantCultureIgnoreCase)
? refName
: $"refs/heads/{refName}";
var content = (HttpContent) new ObjectContent<object>(new
{
StagesToSkip = new object[0],
TemplateParameters = parameters,
Variables = new object(),
Resources = new
{
Repositories = new
{
Self = new
{
RefName = refName
}
}
}
},
new VssJsonMediaTypeFormatter(true));
var queryParameters = new Dictionary<string, string>();
return await SendAsync<PipelineRun>(method, locationId, routeValues, version, content, queryParameters, cancellationToken: CancellationToken.None);
}
}
public class Pipeline
{
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("revision")]
public int Revision { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("folder")]
public string Folder { get; set; }
}
public class Repository
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
}
public class Self
{
[JsonProperty("repository")]
public Repository Repository { get; set; }
[JsonProperty("refName")]
public string RefName { get; set; }
[JsonProperty("version")]
public string Version { get; set; }
}
public class Repositories
{
[JsonProperty("self")]
public Self Self { get; set; }
}
public class Resources
{
[JsonProperty("repositories")]
public Repositories Repositories { get; set; }
}
public class PipelineRun
{
[JsonProperty("pipeline")]
public Pipeline Pipeline { get; set; }
[JsonProperty("state")]
public string State { get; set; }
[JsonProperty("createdDate")]
public DateTime CreatedDate { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("resources")]
public Resources Resources { get; set; }
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
}
用法:
PipelineHttpClient client = new PipelineHttpClient(...);
var project = Guid.Parse("TODO");
var pipelineId = 1234;
// pipeline parameters:
var parameters = new {meaningOfLife = 42};
var result = await client.RunPipelineAsync(project, pipelineId, parameters, "refs/heads/feature/my-branch");
if (result.State == "inProgress")
{
// TODO the pipeline is running!
}