如何通过 Powershell 命令 Invoke-RESTMethod 从 CircleCI 下载工件
How to download artifacts from CircleCI via Powershell command Invoke-RESTMethod
我正在尝试从 Powershell 中的 CircleCI 获取工件并取回不熟悉的数据格式?
Powershell 喜欢将您的 API 的 JSON 响应自动转换为 PSCustomObject。这通常是我想要的。
这是我尝试获取干净数据的示例。
Add the necessary .NET assembly
Add-Type -AssemblyName System.Net.Http
Create the HttpClient object
$client = New-Object -TypeName System.Net.Http.Httpclient
Get the web content.
$task = $client.GetByteArrayAsync(“https://circleci.com/api/v1.1/project/$vcs_type/$username/$project/$build_number/artifacts?circle-token=$CIRCLE_TOKEN”)
Wait for the async call to finish
$task.wait();
结果:
(({
:path “src./file1.txt”,
:pretty-path “src/file1.txt”,
:node-index 0,
:url “https://15-198716507-gh.circle-artifacts.com/0/src/file1.txt”
} {
:path “src/file2.txt”,
:pretty-path “src/file2.txt”,
:node-index 0,
:url “https://15-198716507-gh.circle-artifacts.com/0/src/file2.txt”
}…continued
如您所见,这不是 JSON 或 YAML。让我们试试内置的 PowerShell 工具,如 Invoke-RestMethod。
Invoke-RESTMethod -uri https://circleci.com/api/v1.1/project/$vcs_type/$username/$project/$build_number/artifacts?circle-token=$CIRCLE_TOKEN -Method GET
**Output:**
({
:path “src/file1.txt”,
:pretty-path “src/file1.txt”,
:node-index 0,
:url “https://15-198716507-gh.circle-artifacts.com/0/src/file1.txt”
} {
:path “src/file2.txt”,
:pretty-path “src/file2.txt”,
:node-index 0,
:url “https://15-198716507-gh.circle-artifacts.com/0/src/file2.txt”
}…continued
当当相同的输出。我从 Invoke-RestMethod 文档中知道 PS 看到 JSON 并自动将其转换为 PS 对象。也许它正在转换我不熟悉的数据类型?我发现奇怪的是,当 PowerShell 之外的所有其他尝试都是 JSON 时,PowerShell 正在获取 EDN 类型。
也许他们应该更新 API 以默认使用 JSON 回复 PS 请求。
PowerShell 没有获取 JSON 数据有什么问题?
这是 EDN,直到 CircleCI 回答了一个关于这个主题的问题才知道。因此,如果您使用 PowerShell 从 CircleCI 检索工件,您肯定想知道这一点。
您需要传递一个 header 指定返回的数据类型。
(Accept: application/json)
一位 CircleCI 支持成员告诉我,在 PowerShell 中你必须指定一个 Accept header 来接收 JSON 中的数据。难怪我得到奇怪的输出!
所以再次尝试使用新的 accept JSON header 我们在下面有这个命令。
用于在 JSON 中获取数据并将其 auto-convert 发送到 PSObject.
的工作命令
Invoke-RestMethod -Uri https://circleci.com/api/v1.1/project/$vcs_type/$username/$project/$build_number/artifacts?circle-token=$CIRCLE_TOKEN -Method GET -ContentType 'application/json' -UseBasicParsing -Header @{"Accept" = "application/json"}
输出
$response|select path,url
-
小路
-
----
-
src.orig/file1.txt
-
src.orig/file2.txt
-
url
-
---
-
https://15-824975-gh.circle-artifacts.com/0/src.orig/file1.txt
-
https://15-824975-gh.circle-artifacts.com/0/src.orig/file2.txt
如果您不执行以下操作,则使用 PS 命令 Invoke-WebRequest/Invoke-RestMethod 两者都将接收 EDN 格式的数据。是的,现在我可以使用我认为合适的数据来下载我的工件。
CircleCI 的回复让我找到了解决方案。
@burninmedia So what's being sent back is actually a data format called EDN. If you want to return JSON you'll need to pass a header specifying so (Accept: application/json). Thanks!
这是我编写的用于下载所有工件的简单脚本。请确保您正在设置环境变量。
if ($USERNAME -eq $null) { write-host " please add required variable USERNAME" ;exit }
if ($VCS_TYPE -eq $null) { write-host " please add required variable VCS_TYPE" ;exit}
if ($CIRCLE_TOKEN -eq $null) { write-host " please add required variable CIRCLE_TOKEN" ;exit}
if ($BUILD_NUMBER -eq $null) { write-host " please add required variable BUILD_NUMBER" ;exit}
if ($PROJECT -eq $null) { write-host " please add required variable PROJECT" ;exit}
if ($BASEPATH -eq $null) { write-host " please add required variable BASEPATH" ;exit}
$response = Invoke-RestMethod -Uri https://circleci.com/api/v1.1/project/$VCS_TYPE/$USERNAME/$PROJECT/$BUILD_NUMBER/artifacts?circle-token=$CIRCLE_TOKEN -Method GET -ContentType 'application/json' -UseBasicParsing -Header @{"Accept" = "application/json"}
ForEach ($i in $response){
$PATH = $(Split-Path -Path "$($BASEPATH)$($i.path)")
if (-Not ( Test-Path $PATH) ) {
write-host "Creating folder: $($PATH)"
New-Item -ItemType Directory -Force -Path "$($PATH)"
}
Write-Host "Saving artifact $($i.pretty_path) to file: $($BASEPATH)$($i.path)"
Invoke-RestMethod "$($i.url)?circle-token=$($CIRCLE_TOKEN)" -UseBasicParsing -OutFile "$($BASEPATH)$($i.path)"
}
Bash版本
export CIRCLE_TOKEN=':your_token'
echo $(https://circleci.com/api/v1.1/project/$vcs-type/$username/$project/$build_number/artifacts?circle-token=$CIRCLE_TOKEN) > ./artifact_json
for ((i = 0 ; i <= $(jq -c '.[].url ' ./artifact_json|wc -l) ; i++));
do
path=$(jq -c ".[$i].path" ./artifact_json|tr -d '"');
url=$(jq -c ".[$i].url" ./artifact_json|tr -d '"');
pathdir=$(dirname "$path")
echo "URL: $url"
echo "path: $path"
echo "Pathdir: $pathdir"
[ -d $pathdir ] && mkdir -p "$pathdir" #check if folder exists if not mkdir
wget -o $path $url
done
rm ./artifact_json```
我正在尝试从 Powershell 中的 CircleCI 获取工件并取回不熟悉的数据格式?
Powershell 喜欢将您的 API 的 JSON 响应自动转换为 PSCustomObject。这通常是我想要的。
这是我尝试获取干净数据的示例。
Add the necessary .NET assembly
Add-Type -AssemblyName System.Net.Http
Create the HttpClient object
$client = New-Object -TypeName System.Net.Http.Httpclient
Get the web content.
$task = $client.GetByteArrayAsync(“https://circleci.com/api/v1.1/project/$vcs_type/$username/$project/$build_number/artifacts?circle-token=$CIRCLE_TOKEN”)
Wait for the async call to finish
$task.wait();
结果:
(({
:path “src./file1.txt”,
:pretty-path “src/file1.txt”,
:node-index 0,
:url “https://15-198716507-gh.circle-artifacts.com/0/src/file1.txt”
} {
:path “src/file2.txt”,
:pretty-path “src/file2.txt”,
:node-index 0,
:url “https://15-198716507-gh.circle-artifacts.com/0/src/file2.txt”
}…continued
如您所见,这不是 JSON 或 YAML。让我们试试内置的 PowerShell 工具,如 Invoke-RestMethod。
Invoke-RESTMethod -uri https://circleci.com/api/v1.1/project/$vcs_type/$username/$project/$build_number/artifacts?circle-token=$CIRCLE_TOKEN -Method GET
**Output:**
({
:path “src/file1.txt”,
:pretty-path “src/file1.txt”,
:node-index 0,
:url “https://15-198716507-gh.circle-artifacts.com/0/src/file1.txt”
} {
:path “src/file2.txt”,
:pretty-path “src/file2.txt”,
:node-index 0,
:url “https://15-198716507-gh.circle-artifacts.com/0/src/file2.txt”
}…continued
当当相同的输出。我从 Invoke-RestMethod 文档中知道 PS 看到 JSON 并自动将其转换为 PS 对象。也许它正在转换我不熟悉的数据类型?我发现奇怪的是,当 PowerShell 之外的所有其他尝试都是 JSON 时,PowerShell 正在获取 EDN 类型。
也许他们应该更新 API 以默认使用 JSON 回复 PS 请求。
PowerShell 没有获取 JSON 数据有什么问题?
这是 EDN,直到 CircleCI 回答了一个关于这个主题的问题才知道。因此,如果您使用 PowerShell 从 CircleCI 检索工件,您肯定想知道这一点。
您需要传递一个 header 指定返回的数据类型。
(Accept: application/json)
一位 CircleCI 支持成员告诉我,在 PowerShell 中你必须指定一个 Accept header 来接收 JSON 中的数据。难怪我得到奇怪的输出! 所以再次尝试使用新的 accept JSON header 我们在下面有这个命令。
用于在 JSON 中获取数据并将其 auto-convert 发送到 PSObject.
的工作命令Invoke-RestMethod -Uri https://circleci.com/api/v1.1/project/$vcs_type/$username/$project/$build_number/artifacts?circle-token=$CIRCLE_TOKEN -Method GET -ContentType 'application/json' -UseBasicParsing -Header @{"Accept" = "application/json"}
输出
$response|select path,url
- 小路
- ----
- src.orig/file1.txt
- src.orig/file2.txt
- url
- ---
- https://15-824975-gh.circle-artifacts.com/0/src.orig/file1.txt
- https://15-824975-gh.circle-artifacts.com/0/src.orig/file2.txt
如果您不执行以下操作,则使用 PS 命令 Invoke-WebRequest/Invoke-RestMethod 两者都将接收 EDN 格式的数据。是的,现在我可以使用我认为合适的数据来下载我的工件。
CircleCI 的回复让我找到了解决方案。
@burninmedia So what's being sent back is actually a data format called EDN. If you want to return JSON you'll need to pass a header specifying so (Accept: application/json). Thanks!
这是我编写的用于下载所有工件的简单脚本。请确保您正在设置环境变量。
if ($USERNAME -eq $null) { write-host " please add required variable USERNAME" ;exit }
if ($VCS_TYPE -eq $null) { write-host " please add required variable VCS_TYPE" ;exit}
if ($CIRCLE_TOKEN -eq $null) { write-host " please add required variable CIRCLE_TOKEN" ;exit}
if ($BUILD_NUMBER -eq $null) { write-host " please add required variable BUILD_NUMBER" ;exit}
if ($PROJECT -eq $null) { write-host " please add required variable PROJECT" ;exit}
if ($BASEPATH -eq $null) { write-host " please add required variable BASEPATH" ;exit}
$response = Invoke-RestMethod -Uri https://circleci.com/api/v1.1/project/$VCS_TYPE/$USERNAME/$PROJECT/$BUILD_NUMBER/artifacts?circle-token=$CIRCLE_TOKEN -Method GET -ContentType 'application/json' -UseBasicParsing -Header @{"Accept" = "application/json"}
ForEach ($i in $response){
$PATH = $(Split-Path -Path "$($BASEPATH)$($i.path)")
if (-Not ( Test-Path $PATH) ) {
write-host "Creating folder: $($PATH)"
New-Item -ItemType Directory -Force -Path "$($PATH)"
}
Write-Host "Saving artifact $($i.pretty_path) to file: $($BASEPATH)$($i.path)"
Invoke-RestMethod "$($i.url)?circle-token=$($CIRCLE_TOKEN)" -UseBasicParsing -OutFile "$($BASEPATH)$($i.path)"
}
Bash版本
export CIRCLE_TOKEN=':your_token'
echo $(https://circleci.com/api/v1.1/project/$vcs-type/$username/$project/$build_number/artifacts?circle-token=$CIRCLE_TOKEN) > ./artifact_json
for ((i = 0 ; i <= $(jq -c '.[].url ' ./artifact_json|wc -l) ; i++));
do
path=$(jq -c ".[$i].path" ./artifact_json|tr -d '"');
url=$(jq -c ".[$i].url" ./artifact_json|tr -d '"');
pathdir=$(dirname "$path")
echo "URL: $url"
echo "path: $path"
echo "Pathdir: $pathdir"
[ -d $pathdir ] && mkdir -p "$pathdir" #check if folder exists if not mkdir
wget -o $path $url
done
rm ./artifact_json```