如何通过Powershell命令Invoke-RESTMethod从CircleCI下载工件

时间:2019-08-30 16:09:14

标签: windows powershell circleci artifacts

我正在尝试从Powershell中的CircleCI获取工件,并找回不熟悉的数据格式?

Powershell喜欢将您的API的JSON响应自动转换为PSCustomObject。这通常是我想要的。

这是我尝试获取干净数据的一个示例。

<?php
function is_blog() {
    return ( is_archive() || is_author() || is_category() || is_home() || is_single() || is_tag() ) && 'post' == get_post_type();
}
?>

<?php do_action( 'generate_before_footer' ); ?>
<div <?php generate_footer_class(); ?>>
    <?php
    do_action( 'generate_before_footer_content' );

    // Get how many widgets to show.
    $widgets = generate_get_footer_widgets();

    if ( ! empty( $widgets ) && 0 !== $widgets ) :

        // Set up the widget width.
        $widget_width = '';
        if ( $widgets == 1 ) {
            $widget_width = '100';
        }
        if ( $widgets == 2 ) {
            $widget_width = '50';
        }
        if ( $widgets == 3 ) {
            $widget_width = '33';
        }
        if ( $widgets == 4 ) {
            $widget_width = '25';
        }
        if ( $widgets == 5 ) {
            $widget_width = '20';
        }
        ?>

结果:

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();

如您所见,这不是JSON或YAML。让我们尝试内置的PowerShell工具,例如Invoke-RestMethod。

    (({
    :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数据怎么了?

1 个答案:

答案 0 :(得分:0)

这是EDN,直到CircleCI回答了有关该主题的问题才知道。因此,如果您使用PowerShell从CircleCI检索工件,您肯定想知道这一点。

您需要传递一个标头,指定返回的数据类型。

(Accept: application/json)

CircleCI支持成员告诉我,在PowerShell中,您必须指定Accept标头才能接收JSON中的数据。难怪我得到奇怪的输出! 因此,使用新的accept JSON标头再试一次,我们在下面有此命令。

正在运行的命令,用于获取JSON中的数据并将其自动转换为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
  •     网址
  • ---
  • 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```