我正在尝试编写一个PowerShell脚本,以根据现有版本定义创建和启动新版本。我在构建POST请求正文所需的ReleaseStartMetadata对象时遇到了问题。文档here,here和here没有说明哪些字段是必需的,哪些字段是可选的,在某些情况下(BuildVersion)根本没有说明什么是字段意味着在哪里找到填充它们的值。
我使用的版本定义取决于两组工件。一个是构建工件,一个是源工件。发布定义被配置为默认为两者的最新工件版本,但我无法通过其余api找到任何方式来指定仅使用默认(最新)工件。所以我假设我需要明确指定要使用的工件版本。我在网上找到的所有示例都显示了如何使用构建工件创建发布,但我找不到使用源工件的示例。我正在猜测" sourceVersion" BuildVersion合约上的字段应该是变更集ID,但我不知道在哪里找到要为" sourceBranch"," sourceRepositoryId"和" sourceRepositoryType"指定的值。
这是我到目前为止的剧本:
$authinfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("my@email.com:blahblahtokenvalueblahblahblah"))
$headers = @{}
$headers.Add('Authorization', ("Basic {0}" -f $authinfo))
$headers.Add('Content-Type', 'application/json')
$uri = 'https://my-account.visualstudio.com/DefaultCollection/MyProject/_apis/build/builds?api-version=2.0&definitions=16'
$buildsResponse = Invoke-RestMethod -Method 'Get' -Uri $uri -Headers $headers
$build = $buildsResponse | Select -Expand value | Sort -Property id | Select -Last 1
$buildId = $build | Select -Expand id
$buildNumber = $build | Select -Expand buildNumber
Write-Host "Found latest build. BuildId: $buildId, BuildNumber: $buildNumber"
$uri = 'https://my-account.visualstudio.com/DefaultCollection/MyProject/_apis/tfvc/changesets?api-version=1.0&searchCriteria.itemPath=$/MyProject'
$changesetsResponse = Invoke-RestMethod -Method 'Get' -Uri $uri -Headers $headers
$changeset = $changesetsResponse | Select -Expand value | Sort -Property changesetId | Select -Last 1
$changesetId = $changeset | Select -Expand changesetId
Write-Host "Found latest changeset. ChangesetId: $changesetId"
$uri = 'https://my-account.vsrm.visualstudio.com/MyProject/_apis/release/releases?api-version=4.0-preview.4'
$body = @{
definitionId = 3
description = 'Testing release via Rest API'
isDraft = $FALSE
reason = 'none'
manualEnvironments = $NULL
artifacts = @(
@{
alias = 'My Build Artifact'
instanceReference = @{
id = "$buildId"
name = $buildNumber
}
},
@{
alias = 'My Source Artifact'
instanceReference = @{
sourceBranch = "Dev"
sourceRepositoryId = $NULL
sourceRepositoryType = $NULL
sourceVersion = "$changesetId"
}
}
)
properties = $NULL
}
$createResponse = Invoke-RestMethod -Method 'Post' -Uri $uri -Headers $headers -Body $body
$releaseId = $createResponse | Select id
Write-Host "Release Created: $releaseId"
当我运行它时,前两个请求工作正常,我得到了预期的值,但POST请求失败并出现此异常:
Invoke-RestMethod : {
"$id":"1",
"innerException":null,
"message":"VS402903: The specified value is not convertible to type ReleaseStartMetadata. Make sure it is convertible to type eleaseStartMetadata and try again.",
"typeName":"Microsoft.VisualStudio.Services.ReleaseManagement.Data.Exceptions.InvalidRequestException, Microsoft.VisualStudio.Services.ReleaseManagement2.Data",
"typeKey":"InvalidRequestException",
"errorCode":0,
"eventId":3000
}
At C:\dev\PShell\MyScript.ps1:49 char:19
+ ... eResponse = Invoke-RestMethod -Method 'Post' -Uri $uri -Headers $head ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
即使我为sourceRepositoryId和sourceRepository类型填写了一些虚假值,我也会得到同样的错误。所以现在我有两个问题:
答案 0 :(得分:1)
如果您使用Git源作为工件,那么instanceReference id是提交ID,但您使用的是TFVC REST API,因此它不正确。
样品:
{
"definitionId":1,
"isDraft":false,
"description":"",
"manualEnvironments":[],
"artifacts":
[
{
"alias":"Asp.netVnext",
"instanceReference":
{
"id":"6459",
"name":"null"
}
},
{
"alias":"WebAPI",
"instanceReference":{
"id":"26e0df34d57fc68ce1706f230eee03c4166d24d0",
"name":"null",
"sourceBranch":"dev"
}
}
]
}
如果您使用TFVC源作为工件,则instanceReference id是变更集ID,但不存在sourceBranch,sourcerepositoryId参数/键,只是id和name。
样品:
{
"definitionId":1
,"isDraft":false,
"description":"",
"manualEnvironments":[],
"artifacts":[
{
"alias":"ScrumStarain2",
"instanceReference":{
"id":"1705",
"name":"Changeset 1705"
}
}
]}
答案 1 :(得分:0)
像往常一样,在我发布问题后不久,我偶然发现了一篇文章,最终引导我找到了我需要的答案。
对于问题1,答案是BuildVersion合同中唯一的实际必填字段是“id”。
对于问题2,我缺少的那篇文章是通过将“| ConvertTo-Json 100”附加到$ body定义来将我的@ -notation对象转换为json。
作为一些额外的奖励信息,如果其他人对“将环境列表设置为手动作为条件”的内容感到困惑。表示(来自ReleaseStartMetadata合同的文档),如果您的发布定义是为新版本配置为在其任何环境中自动启动,则可以通过在manualEnvironments字段中列出这些环境来禁用创建发布时的自动启动。我必须这样做以防止我的新版本(用于我们的自动化测试环境)自动开始部署到开发环境。
所以我的最终工作$ body定义如下:
$body = @{
definitionId = 3
description = 'Testing release via Rest API'
isDraft = $FALSE
reason = 'none'
manualEnvironments = @('Development')
artifacts = @(
@{
alias = 'My Build Artifact'
instanceReference = @{
id = "$buildId"
}
},
@{
alias = 'My Source Artifact'
instanceReference = @{
id = "$changesetId"
}
}
)
properties = $NULL
} | ConvertTo-Json -Depth 100