Azure DevOps通过Web Extension共享文件

时间:2019-08-23 08:23:19

标签: azure-devops

我在Buidlpipeline中有一个自定义PowerShell任务。该任务将有关Buildprocess的信息存储在本地json文件中。 (D:\AzureDevOpsData\Skripte\CoverageHistory.json

另一个网络扩展应在自定义网络中心中显示json文件的内容。

如何在这两个扩展之间共享信息?


我尝试过的事情:

//GET COVERAGE HISTORY JSON
console.log("Error 1:" + historyPath)
var request = new XMLHttpRequest();
console.log("Error 2");
request.open("GET", historyPath, false); //FALSE FOR SYNCHRONOUS REQUEST
console.log("Error 3");
request.send(null);
console.log("Error 4")

打开网络集线器后,我的输出是:

enter image description here

您可能会看到缺少的Error 3输出,因此失败的行必须为request.open("GET", historyPath, false);


我想了很多关于如何共享这些信息的想法,但是我不知道这样做的通用方法。

1 个答案:

答案 0 :(得分:0)

经过一段时间的研究,我发现有机会使用Data Storage中的扩展文档。

我在Buildpipeline中添加了一个PowerShell任务,该任务将json文件转换为Document对象。

param([string]$Uri, [string]$Collection = "DefaultCollection", [string]$Publisher, [string]$Extension, [string]$PAT, [string]$JsonPath)

#VARIABLES
$api = "api-version=3.1-preview.1"
$timeout = 30

#JSON TO EXTENSION SCRIPT
#-----------------------------------------------------------------------------------------------------#
##The script should upload a json file to a azure devops extension as a collection scoped document (data storage)[https://docs.microsoft.com/en-us/azure/devops/extend/develop/data-storage?view=azure-devops]
##Uri = is the uri of the azure devops server (`"{ip}:{port}"`)
##Collection = is the collection name where the extension is installed
##Publisher = is the publisher name of the extension
##Extension = is the the name of the istalled extension, which should get access to the document
##PAT = is a valid personal access token
##JsonPath = is the path of the json file
#-----------------------------------------------------------------------------------------------------#

Write-Host "Uri:`t`t`t$Uri`nCollection:`t$Collection`nPublisher:`t`t$Publisher`nExtension:`t`t$Extension`nPAT:`t`t`t$PAT`nJson Path:`t$JsonPath"

#CHECK ARGUMENTS
if ($Uri -eq "" -or $Collection -eq "" -or $PAT -eq "" -or $JsonPath -eq "") {
    Write-Host "##vso[task.logissue type=error;][ps1] missing uri ({ip}:{port}), collection name, publisher name, extension name, personal access token (PAT) or json file path" -ForegroundColor Red
    exit(-1)
}

#CHECK JSON FILE EXIST
if (-not [System.IO.File]::Exists($JsonPath)) { Write-Host "##vso[task.logissue type=error;][ps1] '$JsonPath' not found" -ForegroundColor Red; exit(-1) }

#READ JSON FILE
$jsonFile = Get-Content $JsonPath -Raw

#CHECK JSON VALID
try { ConvertFrom-Json $jsonFile -ErrorAction Stop; }
catch { Write-Host "##vso[task.logissue type=error;][ps1] '$JsonPath' is invalid:`n$jsonFile" -ForegroundColor Red; exit(-1) }

#AUTHORIZATION HEADERS
$headers = @{
    "Authorization" = ('Basic {0}' -f [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($PAT)")))
    "If-Match"      = ""
}

#GET ALL DOCUMENTS
$url = "$Uri/$Collection/_apis/ExtensionManagement/InstalledExtensions/$Publisher/$Extension/Data/Scopes/Default/Current/Collections/$Collection/Documents?"
$result = Invoke-RestMethod -Uri $url -Method GET -ContentType "application/json" -Headers $headers -TimeoutSec $timeout -Verbose
Write-Host "[ps1] get all documents: $result" -ForegroundColor Yellow

#REMOVE ALL DOCUMENTS
Write-Host "[ps1] documents to remove: $($result.count)" -ForegroundColor Yellow
for ($i = 0; $i -lt $result.count; $i++) {

    $id = $result.value[$i].id
    $url = "$Uri/$Collection/_apis/ExtensionManagement/InstalledExtensions/$Publisher/$Extension/Data/Scopes/Default/Current/Collections/$Collection/Documents/$($result.value[$i].id)?$api"
    try { Invoke-RestMethod -Uri $url -Method DELETE -ContentType "application/json" -Headers $headers -TimeoutSec $timeout -Verbose }
    catch { Write-Host "##vso[task.logissue type=error;][ps1] fail to remove document: $id" -ForegroundColor Red; exit(-1) }
    Write-Host "[ps1] delete document: $id" -ForegroundColor Yellow
}

#CREATE DOCUMENT
$body = $jsonFile
$url = "$Uri/$Collection/_apis/ExtensionManagement/InstalledExtensions/$Publisher/$Extension/Data/Scopes/Default/Current/Collections/$Collection/Documents?$api"
try { $result = Invoke-RestMethod -Uri $url -Method POST -ContentType "application/json" -Headers $headers -Body $body -TimeoutSec $timeout -Verbose }
catch { Write-Host "##vso[task.logissue type=error;][ps1] fail to create a document ('$url')" -ForegroundColor Red; exit(-1) }
Write-Host "[ps1] create document: $result" -ForegroundColor Green

#EXIT CODE
Write-Host "[ps1] exit code: 0" -ForegroundColor Green
exit(0)

Web扩展程序可以在JavaScript中使用以下行来读取文档:

//GET AZURE DEVOPS COLLECTION
var collection = VSS.getWebContext().collection.name

//GET ALL DOCUMENTS OF EXTENSION
VSS.getService(VSS.ServiceIds.ExtensionData).then(function (dataService) {

    //GET DOCUMENT BY ID
    dataService.getDocuments(collection).then(function (docs) {
        try {
            var value = docs[0]
            console.log("[js] loading chart data:");
            console.log(value);

            //REMOVE ID
            if (value.hasOwnProperty("id")) delete value.id;

            //REMOVE ETAG
            if (value.hasOwnProperty("__etag")) delete value.__etag;
        }
        catch (e) {
            //CATCH MISSING VARIABLE GROUP
            console.log("[js] error while loading chart data:");
            console.log(e);
        }
    });
});

在浏览器控制台中,您可以检出json对象:

Browser Console

id__etag会自动添加,这就是我从json对象中删除它的方式。

可能有更好的解决方案,但对我来说很好。如果您决定采用这种方式,请记住, Web扩展取决于PowerShell任务'JsonToExtension'