Параметр управления задачами - пользовательское условие - запускать задачу, если предыдущий сбой или время истекло - PullRequest
1 голос
/ 23 марта 2020

Есть ли возможность установить пользовательское условие, которое будет проверять, не выполнено ли предыдущее задание ИЛИ истекло ли время ожидания?

В настоящее время я использую Only when a previous task has failed, который работает, когда задача не выполняется. Если время выполнения задачи истекло, оно не считается ошибкой и пропускается.

Тогда мне нужно пользовательское условие, что-то вроде or(failed(), timedout()). Возможно ли это?

Контекст

У нас есть эта периодически возникающая проблема с задачей npm install, для которой мы не можем найти причину, но она решается с помощью следующей работы запустить, поэтому мы искали функциональность повтора. Частичное решение состояло в том, чтобы дублировать npm install и использовать опцию управления, но она не работала для всех случаев «сбоя». Решение, предоставленное @Levi Lu-MSFT, похоже, работает для всех наших потребностей (оно повторяет попытку), но, к сожалению, оно не решает проблему, повторное задание 2-й строки также не удается.

Примеры ошибок:

20741 error   stack: 'Error: EPERM: operation not permitted, unlink \'C:\\agent2\\_work\\4\\s\\node_modules\\.staging\\typescript-4440ace9\\lib\\tsc.js\'',
20741 error   errno: -4048,
20741 error   code: 'EPERM',
20741 error   syscall: 'unlink',
20741 error   path: 'C:\\agent2\\_work\\4\\s\\node_modules\\.staging\\typescript-4440ace9\\lib\\tsc.js',
20741 error   parent: 's' }
20742 error The operation was rejected by your operating system.
20742 error It's possible that the file was already in use (by a text editor or antivirus),
20742 error or that you lack permissions to access it.

или

21518 verbose stack SyntaxError: Unexpected end of JSON input while parsing near '...ter/doc/TypeScript%20'
21518 verbose stack     at JSON.parse (<anonymous>)
21518 verbose stack     at parseJson (C:\agent2\_work\_tool\node\8.17.0\x64\node_modules\npm\node_modules\json-parse-better-errors\index.js:7:17)
21518 verbose stack     at consumeBody.call.then.buffer (C:\agent2\_work\_tool\node\8.17.0\x64\node_modules\npm\node_modules\node-fetch-npm\src\body.js:96:50)
21518 verbose stack     at <anonymous>
21518 verbose stack     at process._tickCallback (internal/process/next_tick.js:189:7)
21519 verbose cwd C:\agent2\_work\7\s
21520 verbose Windows_NT 10.0.14393
21521 verbose argv "C:\\agent2\\_work\\_tool\\node\\8.17.0\\x64\\node.exe" "C:\\agent2\\_work\\_tool\\node\\8.17.0\\x64\\node_modules\\npm\\bin\\npm-cli.js" "install"
21522 verbose node v8.17.0
21523 verbose npm  v6.13.4
21524 error Unexpected end of JSON input while parsing near '...ter/doc/TypeScript%20'
21525 verbose exit [ 1, true ]

Иногда также время вышло

Ответы [ 2 ]

2 голосов
/ 24 марта 2020

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

enter image description here

Однако существует проблема с выше пользовательского условия, он не работает в сценарии с несколькими задачами.

Например, есть три задачи A, B, C. Ожидаемое поведение: задача C выполняется только в случае сбоя задачи B. Но фактическое поведение - Задача C также будет выполняться при сбое Задачи A, даже если Задача B выполнена успешно. Проверьте скриншот ниже.

enter image description here

Обходной путь для вышеуказанной проблемы - добавить задачу скрипта для вызова azure devops restful api чтобы получить статус задачи B и установить ее в переменную, используя это выражение echo "##vso[task.setvariable variable=taskStatus]taskStatus".

. Например, ниже: добавьте задачу powershell (вам нужно установить условие для этой задачи на Even if a previous task has failed, even if the build was canceled, чтобы всегда запускаться это задача PowerShell), прежде чем запускать задачу C ниже встроенных сценариев:

$url = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/timeline?api-version=5.1"

$result = Invoke-RestMethod -Uri $url -Headers @{authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"} -ContentType "application/json" -Method get

#Get the task B's task result  
$taskResult = $result.records | where {$_.name -eq "B"} | select result  

#set the Task B's taskResult to variable taskStatus
echo "##vso[task.setvariable variable=taskStatus]$($taskResult.result)" 

Чтобы вышеприведенные сценарии могли получить доступ к токену доступа, необходимо также щелкнуть задание агента и проверить параметр Allow scripts to access the OAuth token. См. Скриншот ниже.

enter image description here

Наконец, вы можете использовать пользовательское условие and(not(canceled()), ne(variables.taskStatus, 'succeeded')) для Задачи C. Задача C должна выполняться только тогда, когда задача B. не выполнена.

enter image description here

1 голос
/ 23 марта 2020

Хотя мне не удалось найти встроенную функцию, чтобы определить, истек ли срок выполнения шага сборки, вы можете попытаться эмулировать это с помощью переменных.

Рассмотрим следующий фрагмент объявления конвейера YAML:

steps:
- script: |
    echo Hello from the first task!
    sleep 90
    echo "##vso[task.setvariable variable=timedOut]false"
  timeoutInMinutes: 1
  displayName: 'A'
  continueOnError: true

- script: echo Previous task has failed or timed out!
  displayName: 'B'
  condition: or(failed(), ne(variables.timedOut, 'false'))

Для первой задачи (A) задано время ожидания через 1 минуту, но скрипт внутри эмулирует долгосрочную задачу (sleep 90) в течение 1,5 минут. В результате время выполнения задачи истекает, а переменная timedOut имеет значение NOT , установленное на false. Следовательно, условие задачи B оценивается как true и оно выполняется. То же самое происходит, если вы замените sleep 90 на exit 1 для эмуляции сбоя задачи A.

С другой стороны, если задание A выполнено успешно, ни одна из условных частей задачи B не оценивается как true, а вся задача B. пропущена.

Это очень упрощенный пример, но он демонстрирует идею, которую можно настроить в дальнейшем для удовлетворения потребностей вашего конвейера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...