Using the Azure Devops Server client library, how do you create the master branch in a new repository? - azure-devops

Using the client API I can create a new repository, but it hasn't been initialized and so doesn't contain a master branch.
public void CreateRepository(string name)
{
TeamProjectReference tpr = new TeamProjectReference();
tpr.Name = "AppDev";
tpr.Id = new Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
GitRepositoryCreateOptions grco = new GitRepositoryCreateOptions();
grco.ProjectReference = tpr;
grco.Name = name;
newRepo = gitClient.CreateRepositoryAsync(grco).Result;
}
I can't figure out how to create a master branch. The methods to create branches all require a parent branch to create from. How do I create master using the client libraries?

How do I create master using the client libraries?
Apart from creating the empty repo, you also need to initialize it with initial commit. Hint from this rest api Initial commit, and also from this official document. You can follow my working sample below:
static void Main(string[] args)
{
//Connect to Azure Devops Service and create an empty git repo.
ConnectToAzureDevopsService(OrgUrl, PAT);
TeamProjectReference teamProjectReference = new TeamProjectReference();
teamProjectReference.Name = "MyProjectName";
teamProjectReference.Id = new Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
GitRepositoryCreateOptions gitRepositoryCreateOptions = new GitRepositoryCreateOptions();
gitRepositoryCreateOptions.ProjectReference = teamProjectReference;
gitRepositoryCreateOptions.Name = "MyTestRepo";
GitRepository gitRepo = GitClient.CreateRepositoryAsync(gitRepositoryCreateOptions).Result;
//You need extra steps below to initialize your newly created repo.
//Craft the branch and commit that we'll push.
GitRefUpdate newBranch = new GitRefUpdate()
{
RepositoryId = gitRepo.Id,
Name = $"refs/heads/master",
OldObjectId = "0000000000000000000000000000000000000000",
};
string newFileName = $"README.md";
GitCommitRef newCommit = new GitCommitRef()
{
Comment = "Initial the repo with custom README.md",
Changes = new GitChange[]
{
new GitChange()
{
ChangeType = VersionControlChangeType.Add,
Item = new GitItem() { Path = $"/{newFileName}" },
NewContent = new ItemContent()
{
Content = "# Thank you for using VSTS!",
ContentType = ItemContentType.RawText,
},
}
},
};
//Start initializing the repo via creating the push.
GitPush InitialPush = GitClient.CreatePushAsync(new GitPush()
{
RefUpdates = new GitRefUpdate[] { newBranch },
Commits = new GitCommitRef[] { newCommit },
}, gitRepo.Id).Result;
//Let me know if it succeeds.
Console.WriteLine("Done");
}
The result:
Let me know if it helps.

Related

Add new Files and Folders to Azure Git Repository with Azure DevOps REST API

How to Add new Files and Folders to Azure Git Repository with Azure DevOps REST API?
I want to add some static files to my repository using Azure DevOps REST APIs.
https://learn.microsoft.com/en-us/rest/api/azure/devops/git/repositories?view=azure-devops-rest-5.1
Is there any option available via REST API?.
or anyother automated way available, either CICD or through c#?
I found the answer, we can use the Git Push REST API uri
https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pushes/create?view=azure-devops-rest-5.1
Follow below steps in your C# code
call GetRef REST https://dev.azure.com/{0}/{1}/_apis/git/repositories/{2}/refs{3}
this should return the object of your repository branch which you can use to push your changes
Next, call Push REST API to create folder or file into your repository
https://dev.azure.com/{0}/{1}/_apis/git/repositories/{2}/pushes{3}
var changes = new List<ChangeToAdd>();
//Add Files
//pnp_structure.yml
var jsonContent = File.ReadAllText(#"./static-files/somejsonfile.json");
ChangeToAdd changeJson = new ChangeToAdd()
{
changeType = "add",
item = new ItemBase() { path = string.Concat(path, "/[your-folder-name]/somejsonfile.json") },
newContent = new Newcontent()
{
contentType = "rawtext",
content = jsonContent
}
};
changes.Add(changeJson);
CommitToAdd commit = new CommitToAdd();
commit.comment = "commit from code";
commit.changes = changes.ToArray();
var content = new List<CommitToAdd>() { commit };
var request = new
{
refUpdates = refs,
commits = content
};
var personalaccesstoken = _configuration["azure-devOps-configuration-token"];
var authorization = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", personalaccesstoken)));
_logger.LogInformation($"[HTTP REQUEST] make a http call with uri: {uri} ");
//here I making http client call
// https://dev.azure.com/{orgnizationName}/{projectName}/_apis/git/repositories/{repositoryId}/pushes{?api-version}
var result = _httpClient.SendHttpWebRequest(uri, method, data, authorization);

How to create a GitHub tag using the octokit.net API

I am creating Release using the github's octokit API. Create release method creates release and also create corresponding tag.
I also want to create additional tag. So using the example here i am trying to create a tag. I am assuming when GitHubClient creates release it has to commit changes as well. However i am not sure how do get SHA of the release commit so that i can use that SHA to create additional tag?
Here is my current code:
var client = new GitHubClient(new ProductHeaderValue(Constants.ProductHeader));
var tokenAuth = new Credentials(options.AccessToken);
client.Credentials = tokenAuth;
var newRelease = new NewRelease(options.Version)
{
Name = options.Version,
Body = "This is test release",
Draft = false,
Prerelease = false
};
var result = await client.Repository.Release.Create(Constants.Owner, repositoryName, newRelease);
??? How do i get `sha` here for the release
var tag = "AdditionalTag"
var newTag = new NewTag()
{
Message = tag,
Tag = tag,
Type = TaggedType.Tag,
Object = ???
};
await client.Git.Tag.Create(Constants.Owner, repositoryName, newTag);
This throws the exception "Validation Failed", because I am not setting the SHA.
Questions
How do I calculate the SHA of the git object?
The octokit also has TagsClient class. What is the difference between TagsClient and GitHubClient?

Pushing an update to VSTS via REST API

I am struggling with pushing an update to an existing file in a VSTS Git repository.
The documentation https://learn.microsoft.com/en-us/rest/api/vsts/git/pushes/create#update_a_file shows what to do.
When I use GET instead of POST, I get all existing pushes. So basically the request is working. This is my URL https://mine.visualstudio.com/_apis/git/repositories/ad3d7615-6e4a-4988-bd3f-ca80d7ec9791/pushes?api-version=4.1-preview.
I am testing the request from a console application. The body is created from a dynamic that is serialized later. The filecontent is a string var x=1;.
dynamic body = new
{
refUpdates = new[] { new { name = "refs/heads/master", oldObjectId = branchObjectId } },
commits = new[] {
new {
comment = "Updated Configuration" ,
changes = new[] {
new {
changeType = "edit",
item = new { path = "/files/filename.js"},
newContent = new { content = filecontent, contentType = "rawtext" }
}
}
}
}
};
The request looks like this:
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
byte[] login = Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "", personalaccesstoken));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(login));
var content = new StringContent(body, Encoding.UTF8, "application/json");
using (HttpResponseMessage response = client.PostAsync(url, content).Result)
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
responseBodyAction.Invoke(responseBody);
}
}
It is not successful, as the following Exception is thrown:
System.Net.Http.HttpRequestException: 'Response status code does not
indicate success: 404 (Not Found).
The body is a valid JSON.
Some API calls need the url .vsrm.visualstudio.com instead of .visualstudio.com. But not in this case.
I am out of ideas. Did anybody successfully push an update to VSTS and can show me how to do it?
As mentioned in a comment I was able to add instead of edit.
The solution is to first check in a file and then send an update/edit.
If there is no existing file, an edit will fail with the Exception.

SharpSvn - Is File or Folder is under svn repository

i intend to use SharpSvn methods such as 'add' and 'lock' for file or folder under SVN repository.
if the file is not mapped i receive an error indication - 'the node ... is not found'.
prior to SvnClient.Info() or SvnClient.Status(), how can i know the status of the file - is it or is it not added to SVN repository?
You can use the 'GetStatus' method:
static bool IsInRepository(string filename)
{
bool isVersioned = false;
using (SvnClient client = new SvnClient())
{
SvnStatusArgs sa = new SvnStatusArgs();
sa.Depth = SvnDepth.Empty;
sa.RetrieveAllEntries = true;
Collection<SvnStatusEventArgs> statuses;
client.GetStatus(filename, sa, out statuses);
isVersioned = !statuses[0].LocalContentStatus.Equals(SvnStatus.NotVersioned);
}
return isVersioned;
}

github api: How to efficiently find the number of commits for a repository?

I want to find the number of commits done to specific github projects, and within them to specific files. I checked the github api docs but only found an API for actually returning all commits. This would be very inefficient since I have to do multiple api calls for paging thru all commits.
Anyone has a better idea?
Update May 2013: see "File CRUD and repository statistics now available in the API"
You now can Get the last year of commit activity data
GET /repos/:owner/:repo/stats/commit_activity
Returns the last year of commit activity grouped by week. The days array is a group of commits per day, starting on Sunday.
Not completely what you are looking for, but closer.
Original answer (April 2010)
No, the current API doesn't support a 'log --all' for listing all commmits from all branches.
The only alternative is presented in "Github API: Retrieve all commits for all branches for a repo", and list through all pages of all commits, branch after branch.
This seems so cumbersome than another alternative would actually to clone the Github repo and apply git commands on that local clone!
(mainly git shortlog)
Note: you can also checkout that python script created by Arcsector.
With GraphQL API v4, you can get total commit count per branch with totalCount for each branch:
{
repository(owner: "google", name: "gson") {
name
refs(first: 100, refPrefix: "refs/heads/") {
edges {
node {
name
target {
... on Commit {
id
history(first: 0) {
totalCount
}
}
}
}
}
}
}
}
Test it in the explorer
0penBrain found a clever way to obtain this information and detailed it in the following Gist : https://gist.github.com/0penBrain/7be59a48aba778c955d992aa69e524c5
Here's the relevant snippet with curl :
curl -I -k "https://api.github.com/repos/:owner/:repo/commits?per_page=1" | sed -n '/^[Ll]ink:/ s/.*"next".*page=\([0-9]*\).*"last".*/\1/p'
The trick is to enable a 1 commit per page pagination, as can be seen in the query-string.
Then the focus must shift from the response JSON body to the HTTP headers where the following entry can be found :
link: <https://api.github.com/repositories/27193779/commits?per_page=1&page=2>; rel="next", <https://api.github.com/repositories/27193779/commits?per_page=1&page=37949>; rel="last"
The sed expression is then in charge of extracting the 37949 number (in this example)
Pure JS Implementation
const base_url = 'https://api.github.com';
function httpGet(theUrl, return_headers) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", theUrl, false); // false for synchronous request
xmlHttp.send(null);
if (return_headers) {
return xmlHttp
}
return xmlHttp.responseText;
}
function get_all_commits_count(owner, repo, sha) {
let first_commit = get_first_commit(owner, repo);
let compare_url = base_url + '/repos/' + owner + '/' + repo + '/compare/' + first_commit + '...' + sha;
let commit_req = httpGet(compare_url);
let commit_count = JSON.parse(commit_req)['total_commits'] + 1;
console.log('Commit Count: ', commit_count);
return commit_count
}
function get_first_commit(owner, repo) {
let url = base_url + '/repos/' + owner + '/' + repo + '/commits';
let req = httpGet(url, true);
let first_commit_hash = '';
if (req.getResponseHeader('Link')) {
let page_url = req.getResponseHeader('Link').split(',')[1].split(';')[0].split('<')[1].split('>')[0];
let req_last_commit = httpGet(page_url);
let first_commit = JSON.parse(req_last_commit);
first_commit_hash = first_commit[first_commit.length - 1]['sha']
} else {
let first_commit = JSON.parse(req.responseText);
first_commit_hash = first_commit[first_commit.length - 1]['sha'];
}
return first_commit_hash;
}
let owner = 'getredash';
let repo = 'redash';
let sha = 'master';
get_all_commits_count(owner, repo, sha);
Credits - https://gist.github.com/yershalom/a7c08f9441d1aadb13777bce4c7cdc3b