不会触发 Azure DevOps REST API 创建的管道
Azure DevOps REST API-created pipeline will not trigger
我使用 REST API.
在 Azure DevOps 中为我的每个存储库创建了 2 个 YAML 管道
管道工作正常,只是它不会在回购更改时触发。不知何故,管道没有被 Azure DevOps 完全识别。
这意味着即使 REST 创建的管道使用默认的 azure-pipelines.yml 文件,回购页面上仍会显示“设置构建”按钮。
此外,当我去 Pipelines 手动设置额外的管道时,我无法做到这一点。它想为 azure-pipelines.yml 文件创建一个新的管道(即使它已经被 REST 创建的管道使用)并且不允许我选择不同的 .yml 文件。
这是我使用 REST 创建管道的代码 API:
string pipelinesURL = $"https://dev.azure.com/{ViewModel.Organization}/{ViewModel.ProjectName}/_apis/pipelines?api-version=6.0-preview.1";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", pat))));
string folderToUse = "null";
if (!string.IsNullOrEmpty(folder))
{
folderToUse = "\"" + folder + "\""; //folder + "/"; // @"/" + folder;
}
string pipelineDef =
"{" +
$" \"folder\": {folderToUse}," +
$" \"name\": \"{name}\"," +
" \"configuration\": {" +
" \"type\": \"yaml\"," +
$" \"path\": \"{yamlPath}\"," +
" \"repository\": {" +
$" \"id\": \"{repoId}\"," +
$" \"name\": \"{repoName}\"," +
" \"type\": \"azureReposGit\"" +
" }" +
" }" +
"}";
StringContent stringContent = new StringContent(pipelineDef, Encoding.UTF8, "application/json");
string url = pipelinesURL;
using (HttpResponseMessage response = await client.PostAsync(
url, stringContent))
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
return true;
}
}
我该如何解决这个问题?
代码不足以创建工作管道。
此外,使用管道端点也不起作用。它必须是构建定义端点:
https://dev.azure.com/{Organization}/{ProjectName}/_apis/build/definitions?api-version=6.0;
Microsoft 在不同论坛上建议从手动创建的管道中获取定义、修改它并使用它来创建新管道:
您实际上可以使用管道端点来创建管道。在那之后,管道令人困惑地变成了“构建定义”。
只有一个巨大而丑陋的更新端点。因此,在创建管道后,获取响应中返回的 ID (definitionId)。
发出获取请求:
var getDefinitionRequest = new HttpRequestMessage(HttpMethod.Get, $"{request.CollectionUri}build/definitions/{definitionId}");
getDefinitionRequest.Headers.Authorization =
new BasicAuthenticationHeaderValue(request.DevopsToken, request.DevopsToken);
var definitionResponse = await _httpClient.SendAsync(getDefinitionRequest, cancellationToken);
definitionResponse.EnsureSuccessStatusCode();
然后解析json payload (Json.Net)
var responseObject = JObject.Parse(await definitionResponse.Content.ReadAsStringAsync(cancellationToken));
您现在可以修改它了。要禁用似乎是默认设置的 PR 触发器覆盖,请执行以下操作:
//enable PRs
var triggers = responseObject.SelectToken("triggers")!.Value<JArray>()!;
triggers.Add(JObject.Parse(@"{
""settingsSourceType"": 2,
""branchFilters"": [
""+refs/heads/master""
],
""forks"": {
""enabled"": false,
""allowSecrets"": false,
""allowFullAccessToken"": false
},
""pathFilters"": [],
""requireCommentsForNonTeamMembersOnly"": false,
""requireCommentsForNonTeamMemberAndNonContributors"": false,
""isCommentRequiredForPullRequest"": false,
""triggerType"": ""pullRequest""
}"));
您现在可以将其推回。
var updateDefinitionRequest = new HttpRequestMessage(HttpMethod.Put, $"{request.CollectionUri}build/definitions/{definitionId}?api-version=6.0");
updateDefinitionRequest.Headers.Authorization =
new BasicAuthenticationHeaderValue(request.DevopsToken, request.DevopsToken);
updateDefinitionRequest.Content = new StringContent(responseObject.ToString(Formatting.None));
updateDefinitionRequest.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var updateResponse = await _httpClient.SendAsync(updateDefinitionRequest, cancellationToken);
updateResponse.EnsureSuccessStatusCode();
您也可以使用相同的方法向管道添加变量:
var variables = responseObject.SelectToken("variables");
JObject items;
if (variables == null)
{
responseObject.Add(new JProperty("variables", items = new JObject()));
}
else
{
items = variables.Value<JObject>()!;
}
items["ContainerName"] = new JObject(new JProperty("value", new JValue(request.ContainerName)));
items["Repository"] = new JObject(new JProperty("value", new JValue(request.RepositoryName)));
items["OctopusProjectName"] = new JObject(new JProperty("value", new JValue(request.OctopusProjectName)));
用起来很累API。
我使用 REST API.
在 Azure DevOps 中为我的每个存储库创建了 2 个 YAML 管道管道工作正常,只是它不会在回购更改时触发。不知何故,管道没有被 Azure DevOps 完全识别。 这意味着即使 REST 创建的管道使用默认的 azure-pipelines.yml 文件,回购页面上仍会显示“设置构建”按钮。
此外,当我去 Pipelines 手动设置额外的管道时,我无法做到这一点。它想为 azure-pipelines.yml 文件创建一个新的管道(即使它已经被 REST 创建的管道使用)并且不允许我选择不同的 .yml 文件。
这是我使用 REST 创建管道的代码 API:
string pipelinesURL = $"https://dev.azure.com/{ViewModel.Organization}/{ViewModel.ProjectName}/_apis/pipelines?api-version=6.0-preview.1";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", pat))));
string folderToUse = "null";
if (!string.IsNullOrEmpty(folder))
{
folderToUse = "\"" + folder + "\""; //folder + "/"; // @"/" + folder;
}
string pipelineDef =
"{" +
$" \"folder\": {folderToUse}," +
$" \"name\": \"{name}\"," +
" \"configuration\": {" +
" \"type\": \"yaml\"," +
$" \"path\": \"{yamlPath}\"," +
" \"repository\": {" +
$" \"id\": \"{repoId}\"," +
$" \"name\": \"{repoName}\"," +
" \"type\": \"azureReposGit\"" +
" }" +
" }" +
"}";
StringContent stringContent = new StringContent(pipelineDef, Encoding.UTF8, "application/json");
string url = pipelinesURL;
using (HttpResponseMessage response = await client.PostAsync(
url, stringContent))
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
return true;
}
}
我该如何解决这个问题?
代码不足以创建工作管道。
此外,使用管道端点也不起作用。它必须是构建定义端点:
https://dev.azure.com/{Organization}/{ProjectName}/_apis/build/definitions?api-version=6.0;
Microsoft 在不同论坛上建议从手动创建的管道中获取定义、修改它并使用它来创建新管道:
您实际上可以使用管道端点来创建管道。在那之后,管道令人困惑地变成了“构建定义”。
只有一个巨大而丑陋的更新端点。因此,在创建管道后,获取响应中返回的 ID (definitionId)。
发出获取请求:
var getDefinitionRequest = new HttpRequestMessage(HttpMethod.Get, $"{request.CollectionUri}build/definitions/{definitionId}");
getDefinitionRequest.Headers.Authorization =
new BasicAuthenticationHeaderValue(request.DevopsToken, request.DevopsToken);
var definitionResponse = await _httpClient.SendAsync(getDefinitionRequest, cancellationToken);
definitionResponse.EnsureSuccessStatusCode();
然后解析json payload (Json.Net)
var responseObject = JObject.Parse(await definitionResponse.Content.ReadAsStringAsync(cancellationToken));
您现在可以修改它了。要禁用似乎是默认设置的 PR 触发器覆盖,请执行以下操作:
//enable PRs
var triggers = responseObject.SelectToken("triggers")!.Value<JArray>()!;
triggers.Add(JObject.Parse(@"{
""settingsSourceType"": 2,
""branchFilters"": [
""+refs/heads/master""
],
""forks"": {
""enabled"": false,
""allowSecrets"": false,
""allowFullAccessToken"": false
},
""pathFilters"": [],
""requireCommentsForNonTeamMembersOnly"": false,
""requireCommentsForNonTeamMemberAndNonContributors"": false,
""isCommentRequiredForPullRequest"": false,
""triggerType"": ""pullRequest""
}"));
您现在可以将其推回。
var updateDefinitionRequest = new HttpRequestMessage(HttpMethod.Put, $"{request.CollectionUri}build/definitions/{definitionId}?api-version=6.0");
updateDefinitionRequest.Headers.Authorization =
new BasicAuthenticationHeaderValue(request.DevopsToken, request.DevopsToken);
updateDefinitionRequest.Content = new StringContent(responseObject.ToString(Formatting.None));
updateDefinitionRequest.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var updateResponse = await _httpClient.SendAsync(updateDefinitionRequest, cancellationToken);
updateResponse.EnsureSuccessStatusCode();
您也可以使用相同的方法向管道添加变量:
var variables = responseObject.SelectToken("variables");
JObject items;
if (variables == null)
{
responseObject.Add(new JProperty("variables", items = new JObject()));
}
else
{
items = variables.Value<JObject>()!;
}
items["ContainerName"] = new JObject(new JProperty("value", new JValue(request.ContainerName)));
items["Repository"] = new JObject(new JProperty("value", new JValue(request.RepositoryName)));
items["OctopusProjectName"] = new JObject(new JProperty("value", new JValue(request.OctopusProjectName)));
用起来很累API。