Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Situation:

I'm currently working on automating CI/CD configurations through bitbucket -> vsts -> azure.

My ideal result is to be able to copy paste (or manually enter) my configuration values into their respective console programs and have the applications configure the whole CI/CD ordeal without having to click through all the web interfaces. It's now possible in Bitbucket and Azure, but creating the VSTS CI/CD configurations through REST API is proving to be difficult.

Azure resources and Bitbucket configurations are currently created through a simple .NET console application that talks to the REST APIs. Basically copy paste (or manually enter) all the values (azure input values / bitbucket input values)into the console application and it will configure everything within 5 minutes.


Problem:

Now I face the harder part of trying to automate build configurations and release configurations in VSTS. Microsoft Docs isn't great on the documentation of VSTS client libraries.

I'm honestly at a loss for how I can create a build definition through the API or Client Library.

  • The BuildHttpClient has three methods I can work with:

    public virtual Task<BuildDefinition> CreateDefinitionAsync(BuildDefinition definition, Guid project, int? definitionToCloneId = null, int? definitionToCloneRevision = null, object userState = null, CancellationToken cancellationToken = default(CancellationToken));   
    public virtual Task<BuildDefinition> CreateDefinitionAsync(BuildDefinition definition, int? definitionToCloneId = null, int? definitionToCloneRevision = null, object userState = null, CancellationToken cancellationToken = default(CancellationToken));    
    public virtual Task<BuildDefinition> CreateDefinitionAsync(BuildDefinition definition, string project, int? definitionToCloneId = null, int? definitionToCloneRevision = null, object userState = null, CancellationToken cancellationToken = default(CancellationToken));
    
  • The BuildDefinition has the following properties.

    namespace Microsoft.TeamFoundation.Build.WebApi    
    { 
    [DataContract]    
    public class BuildDefinition : BuildDefinitionReference
        {
            public BuildDefinition();
    
            public List<string> Tags { get; }
            public PropertiesCollection Properties { get; }
            public List<RetentionPolicy> RetentionRules { get; }
            public List<Demand> Demands { get; }
            public IDictionary<string, BuildDefinitionVariable> Variables { get; }
            public List<BuildTrigger> Triggers { get; }
            public ProcessParameters ProcessParameters { get; set; }
            public BuildRepository Repository { get; set; }
            public List<BuildOption> Options { get; }
            public List<BuildDefinitionStep> Steps { get; }
            public bool BadgeEnabled { get; set; }
            public int JobTimeoutInMinutes { get; set; }
            public BuildAuthorizationScope JobAuthorizationScope { get; set; }
            public string DropLocation { get; set; }
            public string Description { get; set; }
            public string Comment { get; set; }
            public string BuildNumberFormat { get; set; }
            public Build LatestBuild { get; }
            public Build LatestCompletedBuild { get; }
        }
     }
    

As you can see, the most important properties of a build definition are read-only.

How do I go about creating a build definition through the REST API? Are there better alternatives to VSTS that will allow me to do this?


See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
147 views
Welcome To Ask or Share your Answers For Others

1 Answer

The format for the REST API to create a build definition as below:

POST https://{account}.visualstudio.com/{project}/_apis/build/definitions?api-version=5.0-preview.6

application/json example:

{
    "process": {
        "phases": [
            {
                "steps": [

                ],
                "name": "Phase 1",
                "refName": "Phase_1",
                "condition": "succeeded()",
                "target": {
                    "executionOptions": {
                        "type": 0
                    },
                    "allowScriptsAuthAccessOption": false,
                    "type": 1
                },
                "jobAuthorizationScope": "projectCollection",
                "jobCancelTimeoutInMinutes": 1
            }
        ],
        "type": 1
    },
    "repository": {
        "properties": {
            "cleanOptions": "0",
            "labelSources": "0",
            "labelSourcesFormat": "$(build.buildNumber)",
            "reportBuildStatus": "true",
            "gitLfsSupport": "false",
            "skipSyncSource": "false",
            "checkoutNestedSubmodules": "false",
            "fetchDepth": "0"
        },
        "id": "4ba24767-e5a6-4987-80cc-ebaeca01fdbc",
        "type": "TfsGit",
        "name": "product1",
        "url": "https://marinaliu.visualstudio.com/Git2/_git/product1",
        "defaultBranch": "refs/heads/master",
        "clean": "false",
        "checkoutSubmodules": false
    },
    "processParameters": {},
    "drafts": [],
    "queue": {
        "id": 324,
        "name": "ownPC",
        "pool": {
            "id": 23,
            "name": "ownPC"
        }
    },
    "name": "definitionCreatedByRESTAPI",
    "type": "build",
    "queueStatus": "enabled"
}

To use the REST API in C#, you can convert as below:

var personalaccesstoken = "PAT";
var base64Token = Convert.ToBase64String(Encoding.ASCII.GetBytes($":{personalaccesstoken}"));
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64Token);

var requestMessage = new HttpRequestMessage(HttpMethod.Post, "https://account.visualstudio.com/project/_apis/build/definitions?api-version=5.0-preview.6");
requestMessage.Content = new StringContent("{"process": {  "phases": [{"steps": [], "name": "Phase 1","refName": "Phase_1","condition": "succeeded()","target": { "executionOptions": { "type": 0 },"allowScriptsAuthAccessOption": false,  "type": 1  },  "jobAuthorizationScope": "projectCollection", "jobCancelTimeoutInMinutes": 1 }],"type": 1  }, "repository": { "properties": { "cleanOptions": "0","labelSources": "0","labelSourcesFormat": "$(build.buildNumber)", "reportBuildStatus": "true","gitLfsSupport": "false", "skipSyncSource": "false","checkoutNestedSubmodules": "false", "fetchDepth": "0"},"id": "4ba24767-e5a6-4987-80cc-ebaeca01fdbc","type": "TfsGit","name": "product1", "url": "https://marinaliu.visualstudio.com/Git2/_git/product1", "defaultBranch": "refs/heads/master",  "clean": "false","checkoutSubmodules": false },"processParameters": {}, "drafts": [],"queue": { "id": 324,  "name": "ownPC","pool": {"id": 23, "name": "ownPC"}}, "name": "definitionCreatedByRESTAPI", "type": "build","queueStatus": "enabled"}", Encoding.UTF8, "application/json");

HttpResponseMessage response = client.SendAsync(requestMessage).Result;
response.EnsureSuccessStatusCode();

By referring the blog Accessing TFS/VSTS 2017 programmatically for the C# program.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...