0

Can I use this api and convert classic pipeline to yml pipeline -

PUT https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}?api-version=6.0

I tried to override json body by putting this yml content in postman body and calling above API with PUT request -

{
    "_links": {
        "self": {
            "href": "https://dev.azure.com/{org}/xxxx/_apis/pipelines/7?revision=2"
        },
       "web": {
           "href": "https://dev.azure.com/{org}/xxxx/_build/definition?definitionId=7"
        }
    },
    "configuration": {
        "path": "azure-pipelines.yml",
        "repository": {
            "id": "xxxxx",
            "type": "azureReposGit"
        },
        "type": "yaml"
    },
    "url": "https://dev.azure.com/{org}/xxxx/_apis/pipelines/7?revision=2",
    "id": 7,
    "revision": 2,
    "name": "testput",
    "folder": "\\"
    }

This is giving me error in postman - "203 Non-Authoritative Information"

Is there any way to to achieve this ?

Also how can I download yml file using azure DevOps api ?

In UI I can download from here. I want to download this using API and then convert classic pipeline to yml pipeline ?

enter image description here

megha
  • 621
  • 2
  • 11
  • 36
  • How about this issue? Could you get the YAML file via REST API now? If not, would you please let me know the latest information about this issue? – Leo Liu Jan 13 '21 at 02:32
  • @LeoLiu-MSFT I can get the yml json body response now. Thank you so much. – megha Jan 13 '21 at 03:03

2 Answers2

4

In UI I can download from here. I want to download this using API and then convert classic pipeline to yml pipeline ?

There is no such document REST API to export the classic pipeline to yml pipeline. But we could use F12 to grab the URL:

https://dev.azure.com/<YourOrganizationName>/<YourProjectName>/_apis/build/definitions/<DefinitionsId>?dummyValue=

The return result is:

{
    "yaml": "jobs:\r\n- job: Job_1\r\n  displayName: Agent job\r\n  pool:\r\n    vmImage: vs2017-win2016\r\n  steps:\r\n  - checkout: self\r\n  - task: NuGetToolInstaller@1\r\n    displayName: 'Use NuGet '\r\n...\r\n"
}

Obviously, this is not a standard YAML file, including headers and line breaks, etc. We could not use it to create a new pipeline. So, we have to convert it to the standard YAML. Please check my powershell scripts:

$outfile = "D:\YAMLTempFolder\test.yaml"

$connectionToken="Your PAT Here"

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

$YAMLURL = "https://dev.azure.com/<YourOrganizationName>/<YourProjectName>/_apis/build/definitions/165?dummyValue=" 

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

$yaml = $YAMLInfo.yaml

echo $yaml.Replace("...","") > $outfile

The test result of my YAML file is:

enter image description here

Now, we get the YAML file. We could submit this YAML to the repo, then use REST API to create a new YAML pipeline with that YAML.

The reason why need submit the YAML to the repo:

How to create new build pipeline using Azure DevOps REST API?

How to create a new YAML pipeline with existing YAML:

Azure DevOps create build definition via REST API given existing YAML

Update:

If my ORG is Central US, the REST API should be:

Yaml - Get:

GET https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}/yaml?api-version=6.1-preview.1

https://dev.azure.com/<YourOrganizationName>/<YourProjectName>/_apis/build/definitions/1/yaml

To get the REST API, please open your definition and press F12, then click the export to YAML option:

enter image description here

Leo Liu
  • 71,098
  • 10
  • 114
  • 135
  • 1
    This shows I have to create new yml pipeline and can not convert existing pipeline to yml? – megha Jan 08 '21 at 14:06
  • This is not possible. You can create a new one and delete an old. But of course you will loose all history etc. – Krzysztof Madej Jan 08 '21 at 15:20
  • @megha, Yes, we could not convert existing pipeline to yml, even without REST API, we currently cannot do it. Have to create a new one and delete the old. – Leo Liu Jan 08 '21 at 16:33
  • @megha, During the weekend, I researched more documents and tried other methods. At present, we could not directly convert classic pipeline to yml pipeline without creating new pipeline. You could add your request for this feature on our UserVoice site (https://developercommunity.visualstudio.com/content/idea/post.html?space=21 ), which is our main forum for product suggestions. Thank you for helping us build a better Azure DevOps. – Leo Liu Jan 11 '21 at 02:47
  • @LeoLiu-MSFT I tried dummy value api from above in postman and its giving me all the pipeline details but not the yml response as you got ? – megha Jan 11 '21 at 04:33
  • @megha, Also test it with postman, it works fine on my side, would you please share your URL, hide the org name.https://1drv.ms/u/s!Ai1sp_yvodHf6zV3ScjEYlbKi0ie?e=i4hCZb – Leo Liu Jan 11 '21 at 05:37
  • 1
    @LeoLiu-MSFT Here is link - https://1drv.ms/u/s!AlwEuCGgVvi8bU0K5MkPl-IvqME – megha Jan 11 '21 at 14:17
  • @megha, Oh! I think I found the reason for the different result with the same REST API. It is related to the **Region** where our org is located. If my ORG is Central US, then I will get the same result as yours, but if my ORG is East Asia, then I will be able to return the result value correctly. For Central US, its REST API is slightly different. – Leo Liu Jan 12 '21 at 09:24
  • @megha, Please check my updated answer for some more details. – Leo Liu Jan 12 '21 at 09:36
  • @megha, The reason for this difference should be REST API GET `https://dev.azure.com/{organization}/{project}/_apis/build/definitions/{definitionId}/yaml?api-version=6.1-preview.1` It is a newly developed REST API, which has not been deployed to all regions. In regions that have not been deployed, we can use dummyValue=. For regions that have been deployed, we can use REST API Yaml-Get – Leo Liu Jan 12 '21 at 09:53
2

To download yaml for your pipeline you need to call this endpoint

https://dev.azure.com/<YOUR-ORGANIZATION>/<YOUR-PROJECT-ID>/_apis/build/definitions/45?dummyValue=

Yeah, that's correct, there is ?dummyValue= at the end.

Then you will get such response:

{
    "yaml": "variables:\r\n- name: BuildParameters.RestoreBuildProjects\r\n  value: dotnet-core-on-windows/**/*.csproj\r\n- name: BuildParameters.TestProjects\r\n  value: dotnet-core-on-windows/*[Tt]ests/*.csproj\r\nname: $(date:yyyyMMdd)$(rev:.r)\r\nresources:\r\n  repositories:\r\n  - repository: self\r\n    type: git\r\n    ref: master\r\njobs:\r\n- job: Job_1\r\n  displayName: Agent job 1\r\n  pool:\r\n    vmImage: ubuntu-16.04\r\n  steps:\r\n  - checkout: self\r\n  - task: UseDotNet@2\r\n    displayName: Use .Net Core sdk 3.1.x\r\n    inputs:\r\n      version: 3.1.x\r\n  - task: Bash@3\r\n    displayName: Bash Script\r\n    inputs:\r\n      targetType: inline\r\n      script: >-\r\n        ls $(Build.SourcesDirectory) *\r\n\r\n        echo 'siema'\r\n  - task: DotNetCoreCLI@2\r\n    displayName: Restore\r\n    inputs:\r\n      command: restore\r\n      projects: $(BuildParameters.RestoreBuildProjects)\r\n  - task: DotNetCoreCLI@2\r\n    displayName: Build\r\n    inputs:\r\n      projects: $(BuildParameters.RestoreBuildProjects)\r\n      arguments: --configuration $(BuildConfiguration)\r\n  - task: DotNetCoreCLI@2\r\n    displayName: Test\r\n    inputs:\r\n      command: test\r\n      projects: $(BuildParameters.TestProjects)\r\n      arguments: --configuration $(BuildConfiguration) --collect:\"XPlat Code Coverage\"\r\n  - task: DotNetCoreCLI@2\r\n    displayName: dotnet install report-generator\r\n    inputs:\r\n      command: custom\r\n      custom: tool\r\n      arguments: install --tool-path . dotnet-reportgenerator-globaltool\r\n  - task: PowerShell@2\r\n    displayName: PowerShell Script\r\n    enabled: False\r\n    inputs:\r\n      targetType: inline\r\n      script: dotnet tool install --global dotnet-reportgenerator-globaltool --version 4.5.8\r\n  - task: PowerShell@2\r\n    displayName: PowerShell Script\r\n    inputs:\r\n      targetType: inline\r\n      script: >-\r\n        dotnet tool list\r\n\r\n\r\n        ./reportgenerator -reports:$(Agent.TempDirectory)/**/coverage.cobertura.xml -targetdir:$(Build.SourcesDirectory)/coverlet/reports -reporttypes:\"Cobertura\"\r\n\r\n\r\n        ls $(Build.SourcesDirectory)/coverlet/reports\r\n      pwsh: true\r\n  - task: PowerShell@2\r\n    displayName: PowerShell Script\r\n    inputs:\r\n      targetType: inline\r\n      script: ls $(Build.SourcesDirectory)/coverlet/reports\r\n  - task: PublishCodeCoverageResults@1\r\n    displayName: Publish code coverage from $(Build.SourcesDirectory)/coverlet/reports/Cobertura.xml\r\n    inputs:\r\n      codeCoverageTool: Cobertura\r\n      summaryFileLocation: $(Build.SourcesDirectory)/coverlet/reports/Cobertura.xml\r\n  - task: DotNetCoreCLI@2\r\n    displayName: Publish\r\n    enabled: False\r\n    inputs:\r\n      command: publish\r\n      publishWebProjects: True\r\n      projects: $(BuildParameters.RestoreBuildProjects)\r\n      arguments: --configuration $(BuildConfiguration) --output $(build.artifactstagingdirectory)\r\n      zipAfterPublish: True\r\n  - task: PublishBuildArtifacts@1\r\n    displayName: Publish Artifact\r\n    condition: succeededOrFailed()\r\n    enabled: False\r\n    inputs:\r\n      PathtoPublish: $(build.artifactstagingdirectory)\r\n      TargetPath: '\\\\my\\share\\$(Build.DefinitionName)\\$(Build.BuildNumber)'\r\n...\r\n"
}

And then you should use Pipelines - Create

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

The example you can find here - don't worry about the issue as it is fixed now. I copied above example here

curl -X POST \
  'https://dev.azure.com/<myorg>/<myproj>/_apis/pipelines?api-version=6.0-preview.1' \
  -H 'Authorization: Basic <b64string>' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '{
    "configuration":{
    
        "repository": {
            "id": "<repo-guid>",
            "name": "<repo-name>",
            "type": "azureReposGit"
        },
        "path": "pipeline.yaml",
        "type": "yaml"
    },
    "folder": "\\custompath\\",
    "name": "<pipelinename>"
}
Krzysztof Madej
  • 32,704
  • 10
  • 78
  • 107
  • I can create pipeline with this json body but how do I specify specific branch in json body to use for yml pipeline ? – megha Jan 13 '21 at 04:02