azure-devops-dotnet-samples icon indicating copy to clipboard operation
azure-devops-dotnet-samples copied to clipboard

Sample to import a private repository

Open filip7sr opened this issue 6 years ago • 3 comments

Hi!

I'm currently trying to migrate some of our GitHub repositories to Azure Devops. While importing public repositories isn't an issue, I can't manage to create an ImportRequest that uses a token.

My current code looks like this

GitRepository createdRepo = azureGitClient.CreateRepositoryAsync(new GitRepository
		{
			Name = repo.Name,
			ProjectReference = new TeamProjectReference
			{
				Id = archiveProject.Id
			}
		}).Result;

		azureGitClient.CreateImportRequestAsync(new GitImportRequest()
		{
			Repository = createdRepo,
			Parameters = new GitImportRequestParameters()
			{
				GitSource = new GitImportGitSource() { Url = repo.GitUrl }
			}
		}, archiveProject.Id, createdRepo.Id);

I can't imagine I'm the only one that wants to import several repositories, so I'm sure an example would come in handy! :)

filip7sr avatar Jul 31 '19 09:07 filip7sr

Agreed. I'm doing some POC's and I'm unable to figure how to pass the credentials for the source repo. Importing public repos works fine.

ahoffmanvenado avatar Sep 03 '19 21:09 ahoffmanvenado

I think, the solution is to create a ServiceEndPoint in the Azure DevOps project settings. Then, you need to find out the ID of this ServiceEndPoint by going to https://dev.azure.com/[yourOrganization]/[projectName]/_apis/distributedtask/serviceendpoints and get the ID.

I used the following code successfully to import the Git repository from a different Azure DevOps project:

var importRequest = new GitImportRequest
            {
                Repository = new GitRepository()
                {
                    Id = newRepoId, // the repository id of the existing, empty repository with size=0 to import into ...
                    Name = newRepoName, // the name of the existing, empty repository with size=0 to import into ...
                },
                Parameters = new GitImportRequestParameters()
                {
                    GitSource = new GitImportGitSource()
                    {
                        Url =  "https://[sourceOrg].visualstudio.com/[sourceProj]/_git/[sourceRepo]"
                    },
                    ServiceEndpointId = new Guid("[the guid of your service endpoint to sourceOrg]"),
                    DeleteServiceEndpointAfterImportIsDone = false,
                    TfvcSource = null
                }
            };

            var importedRepo = client.CreateImportRequestAsync(importRequest, projectName, newRepoName).Result;

Attention! PAT did not work for me, even when trying to import from a repository that is from a project of the SAME Azure DevOps organization! I was not able to get it working, when I was creating a service endpoint with PAT token, only with basic authentication! (Also, I only tested it, when I used basic authentication credentials generated by my own DevOps account so far)

Attention! I was not able to share the service endpoint / service connection with other projects! (the policy: 'Allow all pipelines to use this service connection' seems not to allow other projects to import via this service endpoint Guid)

Attention! There is also a property 'Overwrite' available for creating a new GitImportGitSource. In none of my tests, I got it working when using this property.

achimismaili avatar Oct 28 '19 18:10 achimismaili

I was able to get this to work:

  1. Make sure you create a repository in the destination project.
  2. Create a service endpoint in the destination project using your alternate credentials for Azure DevOps.
  3. Get the GUID from the URL provided by @achimismaili
  4. Ensure you use the destination repository id in CreateImportRequestAsync(...)

Here is a snippet of my code:

var srcProjectName = "the name of the source project";
var destProjectName= "the name of the destination project";
var prefix = "the prefix for the repository names in the destination project, if any";

// Get a GitHttpClient to talk to the Git endpoints
var gitClient = connection.GetClient<GitHttpClient>();

var sourceRepos = await gitClient.GetRepositoriesAsync(project: srcProjectName);
var destRepos = await gitClient.GetRepositoriesAsync(project: destProjectName);
foreach (var r in sourceRepos)
{
    var destRepoName = $"{prefix}{r.Name}";

    Console.WriteLine($"Creating empty repo at '{destProjectName}/{destRepoName}'");
    var repo = destRepos.SingleOrDefault(rr => rr.Name == destRepoName);
    if (repo == null)
    {
        repo = new GitRepository { Name = destRepoName, };
        repo = await gitClient.CreateRepositoryAsync(repo, destProjectName);
    }

    Console.WriteLine($"Importing '{srcProjectName}/{r.Name}' to '{destProjectName}/{destRepoName}'");
    var imr = new GitImportRequest
    {
        Repository = repo,
        Parameters = new GitImportRequestParameters
        {
            GitSource = new GitImportGitSource { Url = r.RemoteUrl, },
            ServiceEndpointId = new Guid("[the GUId of the service endpoint in the destination project]"),
            DeleteServiceEndpointAfterImportIsDone = false,
            TfvcSource = null
        }
    };
    var result = await gitClient.CreateImportRequestAsync(imr, destProjectName, repo.Id);
}

Note: Alternate Credentials are being (or already) deprecated, but some may still work.

mburumaxwell avatar Jun 15 '20 16:06 mburumaxwell