Azure Devops REST API — публикуйте артефакты сборки из локального хранилища

Я пытаюсь опубликовать некоторые файлы как артефакты сборки в конвейере сборки Azure DevOps с помощью PowerShell, используя эту документацию:

https://learn.microsoft.com/en-us/rest/api/azure/devops/build/artifacts/create?view=azure-devops-rest-7.2#artifactresource

Моя powershell выглядит так:

$url = "https://dev.azure.com/<org>/<project>/_apis/build/builds/<buildId>/artifacts?api-version=7.2-preview.5"

$body = @{
  name = 'testpublish'
  resource = @{
    data = "./testfolder/*"
    type = "filepath"
  }
}

$headers = @{
  'Authorization' = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":<pat>"))
  'Content-Type' = 'application/json'
}

$response = Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $body

однако я получаю сообщение об ошибке:

Invoke-RestMethod:
{
  "$id": "1",
  "innerException": null,
  "message": "TF400898: An Internal Error Occurred.",
  "typeName": "Newtonsoft.Json.JsonReaderException, Newtonsoft.Json",
  "typeKey": "JsonReaderException",
  "errorCode": 0,
  "eventId": 0
}

Может ли кто-нибудь указать мне на правильный синтаксис и сообщить, если я что-то упускаю?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Похоже, вы пытаетесь загрузить папку в агент сборки как артефакт конвейера. Сообщение об ошибке, которое вы получаете, скорее всего, связано с неправильными входными данными type и data. Однако, если вы остановитесь и подумаете об этом как о REST API, в котором локальный компьютер взаимодействует с удаленным сервером, внутренний сервер не будет иметь ни малейшего представления о том, что означает ".\testfolder\*", так что это может быть не то, что вы ищете.

Эта конечная точка REST API подойдет, если вы хотите связать артефакт предыдущей сборки с новой сборкой или если у вас где-то размещен zip-файл, и вы хотите добавить ссылку из вашей сборки на этот загружаемый артефакт. В этом примере использования подразумеваются некоторые подсказки .

Вот несколько лучших альтернатив:

  • Синтаксис ведения журнала: ваш сценарий PowerShell может генерировать специальный оператор журнала, который агент сборки может обрабатывать как команду загрузки файла: ##vso[artifact.upload ...]<file>

  • Задача публикации артефакта: вместо использования задачи PowerShell для загрузки файлов используйте задачу PublishArtifactTask@1

    - task: PublishArtifactTask@1
      inputs:
         targetPath: $(Pipeline.Workspace)/testfolder
         artifact: testpublish
    

Если вы настроены на программное использование API, вам придется немного покопаться. И команды ведения журнала, и PublishArtifactTask используют внутренние плагины в exe-файле агента сборки. Репозитории для этого находятся не в GitHub, но вы можете настроить агент сборки локально, а затем декомпилировать Agents.Plugins.dll, чтобы увидеть, как они загружаются в хранилище Azure, и использовать REST API, чтобы связать артефакт с вашей сборкой.

Ответ принят как подходящий

Я могу воспроизвести ту же ошибку с вашим скриптом. Вам необходимо преобразовать формат $body в json.

      $body = @{
        name = 'testpublish'
        resource = @{
          data = "./testfolder/*"
          type = "filepath"
        }
      } | ConvertTo-Json

Однако остальные API, на которые ссылается associate an artifact with a build, используются для сценария, приведенного выше, созданный артефакт not на самом деле будет иметь любой контент, поскольку ваши данные не имеют общего пути.

Если вы создаете артефакт сборки из build pipeline, рекомендуется использовать существующую задачу PublishPipelineArtifact@1 или PublishBuildArtifacts@1 или команду регистрации:

##vso[artifact.associate type=filepath;artifactname=MyFileShareDrop]\\MyShare\MyDropLocation

Если они не соответствуют требованию, вместо этого вы можете использовать Azure CLI, содержимое будет содержаться в артефакте, и команда также может выполняться local machine.

- powershell: |
    az pipelines runs artifact upload --artifact-name newtestpublish --path "testfolder" --run-id 5995 --org https://dev.azure.com/{orgname} --project {projectname}
  env:
    AZURE_DEVOPS_EXT_PAT: $(pat)

С локальной машины:

Другие вопросы по теме

Параметры форматирования для C# HttpClient.PostAsJsonAsync
Невозможно получить доступ к конечным точкам отдыха даже после успешного входа в систему Spring Security через форму реагирования
Проблема при создании рабочего элемента Azure DevOps с полями Microsoft.VSTS.Common.Priority и Microsoft.VSTS.Common.StackRank
Как мне убедиться, что я загружаю только рейсы при поиске, а не загрузку начальной страницы?
Как отозвать токен в Laravel Sanctum?
Какой тип данных использовать в объекте JPA для хранения и получения даты с помощью Java 8
Почему конечная точка PUT django-ninja не использует значение из тела запроса, а вместо этого возвращает значение по умолчанию для обновляемого поля (ModelSchema)?
Загрузите PDF-файл в GCS с помощью REST API — Coldfusion
Скрипт PowerShell для получения терминов глоссария Azure Purview через REST API
Как создать скрипт для автоматизации приема данных GET с моего сайта Wordpress и POST на другой сервер