public async Task <IRemote> GetRemoteAsync(string repoUrl, ILogger logger) { using (_operations.BeginOperation($"Getting remote for repo {repoUrl}.")) { // Normalize the url with the AzDO client prior to attempting to // get a token. When we do coherency updates we build a repo graph and // may end up traversing links to classic azdo uris. string normalizedUrl = AzureDevOpsClient.NormalizeUrl(repoUrl); Uri normalizedRepoUri = new Uri(normalizedUrl); // Look up the setting for where the repo root should be held. Default to empty, // which will use the temp directory. string temporaryRepositoryRoot = _configuration.GetValue <string>("DarcTemporaryRepoRoot", null); if (string.IsNullOrEmpty(temporaryRepositoryRoot)) { temporaryRepositoryRoot = _tempFiles.GetFilePath("repos"); } IGitRepo gitClient; long installationId = await _context.GetInstallationId(normalizedUrl); var gitExe = await ExponentialRetry.RetryAsync( async() => await _localGit.GetPathToLocalGitAsync(), ex => logger.LogError(ex, $"Failed to install git to local temporary directory."), ex => true); switch (normalizedRepoUri.Host) { case "github.com": if (installationId == default) { throw new GithubApplicationInstallationException($"No installation is avaliable for repository '{normalizedUrl}'"); } gitClient = new GitHubClient(gitExe, await _gitHubTokenProvider.GetTokenForInstallationAsync(installationId), logger, temporaryRepositoryRoot, _cache.Cache); break; case "dev.azure.com": gitClient = new AzureDevOpsClient(gitExe, await _azureDevOpsTokenProvider.GetTokenForRepository(normalizedUrl), logger, temporaryRepositoryRoot); break; default: throw new NotImplementedException($"Unknown repo url type {normalizedUrl}"); } ; return(new Remote(gitClient, new MaestroBarClient(_context), logger)); } }
/// <summary> /// Github authentication. /// </summary> /// <param name="issueRepo">Repository where gitHub issue is created.</param> /// <returns>Authenticated GithubClient</returns> private async Task <GitHubClient> AuthenticateGitHubClient(string issueRepo) { IGitHubTokenProvider gitHubTokenProvider = _context.GetService <IGitHubTokenProvider>(); long installationId = await _context.GetInstallationId(issueRepo); string gitHubToken = await gitHubTokenProvider.GetTokenForInstallationAsync(installationId); _logger.LogInformation($"GitHub token acquired for '{issueRepo}'"); string version = Assembly.GetExecutingAssembly() .GetCustomAttribute <AssemblyInformationalVersionAttribute>() .InformationalVersion; ProductHeaderValue product = new ProductHeaderValue("Maestro", version); return(new GitHubClient(product) { Credentials = new Credentials(gitHubToken), }); }
private async Task CreateGitHubIssueAsync(int buildId, int releaseId, string releaseName) { Logger.LogInformation($"Something failed in release definition {releaseId} triggered by build {buildId}"); Build build = Context.Builds.Where(b => b.Id == buildId).First(); string whereToCreateIssue = "https://github.com/dotnet/arcade"; string fyiHandles = "@JohnTortugo, @riarenas"; string gitHubToken = null, azureDevOpsToken = null; string repo = build.GitHubRepository ?? build.AzureDevOpsRepository; using (Logger.BeginScope($"Opening GitHub issue for release definition {releaseId} " + $"triggered by build {buildId} from repo '{repo}'.")) { try { // We get the token of the repo which triggered the release so we can get the author. if (!string.IsNullOrEmpty(build.GitHubRepository)) { IGitHubTokenProvider gitHubTokenProvider = Context.GetService <IGitHubTokenProvider>(); long installationId = await Context.GetInstallationId(build.GitHubRepository); gitHubToken = await gitHubTokenProvider.GetTokenForInstallationAsync(installationId); Logger.LogInformation($"GitHub token acquired for '{build.GitHubRepository}'!"); } if (!string.IsNullOrEmpty(build.AzureDevOpsRepository)) { IAzureDevOpsTokenProvider azdoTokenProvider = Context.GetService <IAzureDevOpsTokenProvider>(); azureDevOpsToken = await azdoTokenProvider.GetTokenForAccount(build.AzureDevOpsAccount); Logger.LogInformation($"AzureDevOPs token acquired for '{build.AzureDevOpsRepository}'!"); } IssueManager issueManager = new IssueManager(gitHubToken, azureDevOpsToken); string title = $"Release '{releaseName}' with id {releaseId} failed"; string description = $"Something failed while running an async release pipeline for build " + $"[{build.AzureDevOpsBuildNumber}](https://dnceng.visualstudio.com/internal/_build/results?buildId={build.AzureDevOpsBuildId})." + $"{Environment.NewLine} {Environment.NewLine}" + $"Please click [here](https://dnceng.visualstudio.com/internal/_releaseProgress?_a=release-pipeline-progress&releaseId={releaseId}) to check the error logs." + $" {Environment.NewLine} {Environment.NewLine}" + $"/FYI: {fyiHandles}"; if (build.GitHubRepository != whereToCreateIssue) { // We get the token of the Arcade installation since there's where the actual issue will be // created. We cannot reuse the previously acquired token since its generated for a // different repo. IGitHubTokenProvider gitHubTokenProvider = Context.GetService <IGitHubTokenProvider>(); long installationId = await Context.GetInstallationId(whereToCreateIssue); gitHubToken = await gitHubTokenProvider.GetTokenForInstallationAsync(installationId); Logger.LogInformation($"GitHub token acquired for '{whereToCreateIssue}'!"); issueManager = new IssueManager(gitHubToken, azureDevOpsToken); } int issueId = await issueManager.CreateNewIssueAsync(whereToCreateIssue, title, description); Logger.LogInformation($"Issue {issueId} was created in '{whereToCreateIssue}'"); } catch (Exception exc) { Logger.LogError(exc, $"Something failed while attempting to create an issue based on repo '{repo}' " + $"and commit {build.Commit}."); } } }