Creating a File in VSTS with APIs

ViewAPIArticles16Following along the same line as some of the previous API examples I’ve posted I thought I’d post an example on how to make use of the VSTS APIs to create a new file in a VSTS-based Git repo. This can be handy if you need to get a file into VSTS but don’t want to mess around with calling out to the Git command line or making use of various Git libraries.

If you’re new to calling the VSTS REST APIs or you are new to this series of articles then I would recommend you check out the other articles in this series before getting started.

For our example (of creating a new file) there are two VSTS APIs that must be utilized: the refs API and the pushes API.

The *refs* API is needed because we need to find the objectId for the branch where the file is going to be created. The objectId will be utilized as an input parameter for the *pushes* API.

Obtaining the Branch Object ID

The format of the API call to obtain the Object ID for the branch where the file will be created looks something like this:

https://{instance}.visualstudio.com/DefaultCollection/{project}/_apis/git/repositories/{repo}/refs/heads/{branch}?api-version=1.0

A real-world example of the call might look like this:

https://MyAccount.visualstudio.com/DefaultCollection/MyProject/_apis/git/repositories/MyRepo/refs/heads/master?api-version=1.0

In the above example, I am simply attempting to retrieve some information for the master branch. The following C# example shows how you might call the API in code:

var url = $"https://MyAccount.visualstudio.com/DefaultCollection/MyProject/_apis/git/repositories/MyRepo/refs/heads/master?api-version=1.0";
var token = "<INSERT YOUR PERSONAL ACCESS TOKEN HERE>";
var authorizationHeader = Convert.ToBase64String(

UTF8Encoding.UTF8.GetBytes($":{token}"));

var request = (HttpWebRequest)WebRequest.Create(url);

request.Headers.Set(HttpRequestHeader.Authorization,

$"BASIC {authorizationHeader}");
request.ContentType = "application/json";
request.Method = "GET";

using (var response = (HttpWebResponse)request.GetResponse())
{
    using (var streamToRead = response.GetResponseStream())
    {
        using (var streamReader = new StreamReader(streamToRead,

Encoding.UTF8))
        {
            var resultsJson = streamReader.ReadToEnd();
        }
    }
}

When the API returns, the JSON will include information regarding the branch you specified. The JSON will look something like this:

{
    "value": [{
    "name": "refs/heads/master",
     "objectId": "6cec7a08d43c744bd54a0eafaf7657a665cdbc9b",
        "url": https://myaccount.visualstudio.com/DefaultCollection/_apis/git/repositories/6ee66670-32d8-42b2-b9da-54b15bd45aae/refs?filter=heads%2Fmaster
     }],
     "count": 1
}

It is the objectId shown in the above JSON that we are interested in. Once you’ve obtained that value, you can move on to the next API.

Creating the File

The API call we will use is based on the *pushes* API and looks something like:

https://{instance}.visualstudio.com/DefaultCollection/{project}/_apis/git/repositories/{repo}/pushes?api-version=2.0-preview

So, using the same account, project and repo as above, the URL would look something like this:

https://MyAccount.visualstudio.com/DefaultCollection/MyProject/_apis/git/repositories/MyRepo/pushes?api-version=2.0-preview

The particular API we are calling utilizes an HTTP POST call and, therefor, also requires a message body to be passed in. The message body has the following format:

{
   "refUpdates": [
    {
      "name": "refs/heads/master",
        "oldObjectId": "<GET FROM PREVIOUS API RESULTS>"
    }
    ],
    "commits": [
    {
        "comment": "Initial commit.",
        "changes": [
        {
            "changeType": "add",
            "item": {
              "path": "/test.md"
            },
            "newContent": {
             "content": "My first file pushed via API!",
               "contentType": "rawtext"
            }
          }
        ]
      }
   ]
}

Take notice of the oldObjectId value in the above JSON. Set this value to the Object ID obtained in the previous (refs) call. This identifies the branch where the file is to reside.

Next, ensure the changeType value is set to add. If the file happens to already exist, you can set this value to edit to update the file.

If you want to get a head start on making these calls with C# code (rather than using Fiddler) check out the post Calling VSTS APIs with C#. This post will show you how to make use of an excellent Fiddler extension, Request to Code, that will provide some starter C# code for you from a selected web request. Very cool!

I’ll be posting some larger examples to GitHub in the near future. Once I do that, I’ll come back and update this post with the appropriate links. Enjoy!

ContactUs.com