Параметры группы задач с типом, отличным от string

#azure-devops #azure-pipelines-release-pipeline #azure-task-groups

#azure-devops #azure-pipelines-release-pipeline #azure-task-groups

Вопрос:

У меня есть вариант использования, когда я хочу добавить параметр a pickList -type в свою группу задач. Это кажется выполнимым; пользовательский интерфейс отображается нормально, и переменная также корректна при запуске конвейера с использованием группы задач. Я понимаю, что вы не можете напрямую настроить параметр как список выбора и что это должно быть сделано вручную с помощью JSON.

Что я тогда сделал:

  • Создал группу задач с моими задачами и необходимыми переменными. Все хорошо, и переменные появились в качестве параметров, $(someType) и $(someValue) .
  • Я хотел $(someType) , чтобы переменная была a pickList — я экспортировал указанную группу задач, удалил все связи с исходной группой задач (идентификаторы и что-то еще) из JSON, отредактировал свое поле ввода, чтобы оно имело тип pickList , и добавил необходимые параметры в options -array .
  • Импортировал указанную группу задач с отредактированными значениями. Работает нормально. Использовал его в конвейере выпуска. Работал нормально.
  • Возникла проблема с одним из моих сценариев в группе задач, пошел редактировать группу задач. Как только я нажму save, он преобразует все параметры в строки, и теперь он явно сломан.

Я включил минимальный рабочий JSON-пример группы задач, в который multiline pickList включен параметр типа и.

 {
   "tasks":[
      {
         "environment":{
            
         },
         "displayName":"PowerShell Script",
         "alwaysRun":false,
         "continueOnError":false,
         "condition":"succeeded()",
         "enabled":true,
         "timeoutInMinutes":0,
         "inputs":{
            "targetType":"inline",
            "filePath":"",
            "arguments":"",
            "script":"Write-Host "$(picklisttype)"nWrite-Host "$(mlvalue)"",
            "errorActionPreference":"stop",
            "failOnStderr":"false",
            "showWarnings":"false",
            "ignoreLASTEXITCODE":"false",
            "pwsh":"false",
            "workingDirectory":""
         },
         "task":{
            "id":"e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
            "versionSpec":"2.*",
            "definitionType":"task"
         }
      }
   ],
   "runsOn":[
      "Agent",
      "DeploymentGroup"
   ],
   "name":"my-task-group-with-picklist",
   "version":{
      "major":1,
      "minor":0,
      "patch":0,
      "isTest":false
   },
   "iconUrl":"https://my-own-custom-image.com/images/icon.png",
   "friendlyName":"My Task Group w/ PickList",
   "description":"This task group contains a picklist. Awesome.",
   "category":"Deploy",
   "definitionType":"metaTask",
   "author":"Myself",
   "demands":[
      
   ],
   "groups":[
      
   ],
   "inputs":[
      {
        "aliases": [],
        "options": {
            "option1": "First option",
            "option2": "Second option (default)",
            "option3": "Third option"
        },
        "properties": {},
        "name": "picklisttype",
        "label": "Pick a type",
        "defaultValue": "option2",
        "required": true,
        "type": "pickList",
        "helpMarkDown": "Just pick a type!",
        "groupName": ""
      },
      {
         "aliases":[],
         "options":{},
         "properties":{},
         "name":"mlvalue",
         "label":"Write several lines",
         "defaultValue":"This containsnseveral linesnof text.nHowever, you it isnquite small and itnis not possible to alternits appearance...",
         "required":true,
         "type":"multiLine",
         "helpMarkDown":"Write some awesome text.",
         "groupName":"",
         "visibleRule": "picklisttype != option3"
      }
   ],
   "satisfies":[
      
   ],
   "sourceDefinitions":[
      
   ],
   "dataSourceBindings":[
      
   ],
   "instanceNameFormat":"Default name with default value $(picklisttype)",
   "preJobExecution":{
      
   },
   "execution":{
      
   },
   "postJobExecution":{
      
   }
}
 

Если вы импортируете указанный JSON, добавляете группу задач в конвейер выпуска и запускаете его, вы увидите, что он выводит все, что вы правильно выбрали из списка выбора.

Если вы затем перейдете к редактированию группы задач, как только вы ее сохраните, она будет отображаться разбитой (преобразует многострочный список и список выбора в строковые типы).

У кого-нибудь есть какой-либо опыт в этом, если это возможно каким-либо образом (используя для ваших параметров типы, отличные от string)?

Ответ №1:

Пожалуйста, не обновляйте задачу группы задач в пользовательском интерфейсе, вы должны обновить ее через REST API.

Получение информации о группе задач через REST API

 GET https://dev.azure.com/{organization}/{project}/_apis/distributedtask/taskgroups/{taskGroupId}?api-version=6.0-preview.1
 

Затем обновите информацию о группе задач с помощью этого REST API

 PUT https://dev.azure.com/{organization}/{project}/_apis/distributedtask/taskgroups/{taskGroupId}?api-version=6.0-preview.1
 

Вы можете попробовать этот сценарий power shell, чтобы обновить информацию о печати power shell.

 $url = "https://dev.azure.com/{org name}/{project name}/_apis/distributedtask/taskgroups/{task group ID}?api-version=6.0-preview.1"

$connectionToken="{pat}"

$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))

$taskGroups = Invoke-RestMethod -Uri $url -Headers @{authorization = "Basic $base64AuthInfo"} -Method Get

#Write-Host $taskGroups.value.tasks.inputs.script

$taskGroups.value.tasks.inputs.script = 'Write-Host "$(picklisttype)"
Write-Host "$(mlvalue)" 
Write-Host "$(picklisttype)"'

$json = $taskGroups.value | ConvertTo-Json -Depth 10

$response = Invoke-RestMethod -Uri $url -ContentType "application/json" -Body $json -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method PUT

#Write-Host $taskGroups.value.tasks.inputs.script
 

Результат:

Страница группы задач:

введите описание изображения здесь

Отпустите информацию о печати:

введите описание изображения здесь

Комментарии:

1. Спасибо, это сработало. Я также добавил ответ сам, расширив ваш скрипт, чтобы упростить работу с ним, поскольку API обычно ориентированы на код, а не на людей. 😉

Ответ №2:

В качестве дополнения к ответу @Vito Liu-MSFT, вот простой командлет PS, который я в итоге использовал (я не эксперт в сценариях PS, так что это, вероятно, можно было бы улучшить):

 Function Get-TaskGroup {
    [CmdletBinding()]
        param (
        [Parameter(Mandatory=$true, HelpMessage="DevOps organization")][string]$org,
        [Parameter(Mandatory=$true, HelpMessage="Organization project")][string]$project,
        [Parameter(Mandatory=$true, HelpMessage="Task group ID")][string]$tgId,
        [Parameter(Mandatory=$true, HelpMessage="DevOps PAT")][string]$pat,
        [Parameter(Mandatory=$false, HelpMessage="DevOps PAT")][string]$path
    )
    
    $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$pat"))
    $url = "https://dev.azure.com/$org/$project/_apis/distributedtask/taskgroups/$tgId`?api-version=6.0-preview.1"
    $tg = Invoke-RestMethod -Uri $url -Headers @{authorization = "Basic $auth"} -Method GET -ErrorAction Stop
    if ($tg -and $tg.value) {
        echo $tg.value
            
        if ($path) {
            echo "$($tg.value | ConvertTo-Json -Depth 10)" > $path
        }
    }
    else {
        throw "Failed to fetch task group with id $tgId"
    }
}

Function Put-TaskGroup {
    [CmdletBinding()]
        param (
        [Parameter(Mandatory=$true, HelpMessage="DevOps organization")][string]$org,
        [Parameter(Mandatory=$true, HelpMessage="Organization project")][string]$project,
        [Parameter(Mandatory=$true, HelpMessage="Task group ID")][string]$tgId,
        [Parameter(Mandatory=$true, HelpMessage="DevOps PAT")][string]$pat,
        [Parameter(Mandatory=$false, HelpMessage="Valid task group object as JSON.")][string]$json,
        [Parameter(Mandatory=$false, HelpMessage="Path to file containing valid task group object as JSON.")][string]$path
    )
    BEGIN {
        if (!$json -and !$path) {
            throw "Must provide either a valid JSON string using the -json parameter or a path to a file with a valid JSON object using the -path parameter."
        }
        ElseIf ($json -and $path) {
            echo "Both -json and -path supplied, using string provided with -json"
        }
        ElseIf (!$json -and $path -and ![System.IO.File]::Exists($path)) {
            throw "$path does not exist"
        }
    }
    PROCESS {
        $body = ""
        if ($json) {
            $body = $json
        }
        else {
            $body = Get-Content $path
        }
        
        $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$pat"))
        $url = "https://dev.azure.com/$org/$project/_apis/distributedtask/taskgroups/$tgId`?api-version=6.0-preview.1"
        $tg = Invoke-RestMethod -Uri $url -ContentType "application/json" -Body $body -Headers @{authorization = "Basic $auth"} -Method PUT -ErrorAction Stop -TimeoutSec 10
        if ($tg) {
            echo $tg
        }
    }
}
 

Пример:

 $tg = Get-TaskGroup -org $org -project $project -tgId $tgId -pat $pat -path $path
$tg = Put-TaskGroup -org $org -project $proj -tgId $tgId -pat $pat -path $path