diff --git a/build/publish/FinishBuild.targets b/build/publish/FinishBuild.targets index 49efcf115..e67faa14c 100644 --- a/build/publish/FinishBuild.targets +++ b/build/publish/FinishBuild.targets @@ -38,7 +38,8 @@ just publish the latest version and list a "core-sdk" package with version --> diff --git a/build_projects/dotnet-cli-build/GitHubWriteVersionUpdater.cs b/build_projects/dotnet-cli-build/GitHubWriteVersionUpdater.cs new file mode 100644 index 000000000..f07c951d7 --- /dev/null +++ b/build_projects/dotnet-cli-build/GitHubWriteVersionUpdater.cs @@ -0,0 +1,137 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#if !SOURCE_BUILD +using Microsoft.DotNet.VersionTools.Automation; +using Microsoft.DotNet.VersionTools.Automation.GitHubApi; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; + +namespace Microsoft.DotNet.Cli.Build +{ + // This code is a slightly modified port of GitHubVersionsRepoUpdater from + // https://raw.githubusercontent.com/dotnet/buildtools/master/src/Microsoft.DotNet.VersionTools/Automation/GitHubVersionsRepoUpdater.cs + internal class GitHubWriteVersionUpdater: VersionsRepoUpdater + { + private const int MaxTries = 10; + private const int RetryMillisecondsDelay = 5000; + + private GitHubAuth _gitHubAuth; + private GitHubProject _project; + + public GitHubWriteVersionUpdater( + GitHubAuth gitHubAuth, + string versionsRepoOwner = null, + string versionsRepo = null) + : this( + gitHubAuth, + new GitHubProject(versionsRepo ?? "versions", versionsRepoOwner)) + { + } + + public GitHubWriteVersionUpdater(GitHubAuth gitHubAuth, GitHubProject project) + { + if (gitHubAuth == null) + { + throw new ArgumentNullException(nameof(gitHubAuth)); + } + _gitHubAuth = gitHubAuth; + + if (project == null) + { + throw new ArgumentNullException(nameof(project)); + } + _project = project; + } + /// If true, updates Latest.txt with a prerelease moniker. If there isn't one, makes the file empty. + /// If true, updates Latest_Packages.txt. + public async Task UpdateBuildInfoAsync( + string versionIdentifier, + string version, + string versionsRepoPath, + bool updateLatestPackageList = true, + bool updateLatestVersion = true) + { + if (versionIdentifier == null) + { + throw new ArgumentNullException(nameof(versionIdentifier)); + } + if (version == null) + { + throw new ArgumentNullException(nameof(version)); + } + if (versionsRepoPath == null) + { + throw new ArgumentNullException(nameof(versionsRepoPath)); + } + + using (GitHubClient client = new GitHubClient(_gitHubAuth)) + { + for (int i = 0; i < MaxTries; i++) + { + try + { + // Master commit to use as new commit's parent. + string masterRef = "heads/master"; + GitReference currentMaster = await client.GetReferenceAsync(_project, masterRef); + string masterSha = currentMaster.Object.Sha; + + List objects = new List(); + + if (updateLatestVersion) + { + objects.Add(new GitObject + { + Path = $"{versionsRepoPath}/Latest.txt", + Type = GitObject.TypeBlob, + Mode = GitObject.ModeFile, + Content = version + }); + } + if (updateLatestPackageList) + { + objects.Add(new GitObject + { + Path = $"{versionsRepoPath}/Latest_Packages.txt", + Type = GitObject.TypeBlob, + Mode = GitObject.ModeFile, + Content = $"{versionIdentifier} {version}{Environment.NewLine}" + }); + } + string message = $"Updating {versionsRepoPath}"; + + GitTree tree = await client.PostTreeAsync(_project, masterSha, objects.ToArray()); + GitCommit commit = await client.PostCommitAsync(_project, message, tree.Sha, new[] { masterSha }); + + // Only fast-forward. Don't overwrite other changes: throw exception instead. + await client.PatchReferenceAsync(_project, masterRef, commit.Sha, force: false); + + Trace.TraceInformation($"Committed build-info update on attempt {i + 1}."); + break; + } + catch (HttpRequestException ex) + { + int nextTry = i + 1; + if (nextTry < MaxTries) + { + Trace.TraceInformation($"Encountered exception committing build-info update: {ex.Message}"); + Trace.TraceInformation($"Trying again in {RetryMillisecondsDelay}ms. {MaxTries - nextTry} tries left."); + await Task.Delay(RetryMillisecondsDelay); + } + else + { + Trace.TraceInformation("Encountered exception committing build-info update."); + throw; + } + } + } + } + } + } +} +#endif diff --git a/build_projects/dotnet-cli-build/WriteVersionToVersionsRepo.cs b/build_projects/dotnet-cli-build/WriteVersionToVersionsRepo.cs index 6f2c99d9f..e9a57e984 100644 --- a/build_projects/dotnet-cli-build/WriteVersionToVersionsRepo.cs +++ b/build_projects/dotnet-cli-build/WriteVersionToVersionsRepo.cs @@ -3,20 +3,14 @@ #if !SOURCE_BUILD using Microsoft.Build.Framework; -using MSBuildUtilities = Microsoft.Build.Utilities; +using Microsoft.Build.Utilities; using Microsoft.DotNet.VersionTools.Automation; using Microsoft.DotNet.VersionTools.Automation.GitHubApi; -using System; -using System.Collections.Generic; -using System.Diagnostics; using System.IO; -using System.Linq; -using System.Net.Http; -using ThreadingTasks= System.Threading.Tasks; namespace Microsoft.DotNet.Cli.Build { - public class WriteVersionToVersionsRepo : MSBuildUtilities.Task + public class WriteVersionToVersionsRepo : Task { [Required] public string BranchName { get; set; } @@ -30,142 +24,21 @@ namespace Microsoft.DotNet.Cli.Build [Required] public string GitHubPassword { get; set; } + [Required] public string VersionsRepoPath { get; set; } public override bool Execute() { - string versionsRepoPath = VersionsRepoPath ?? $"build-info/dotnet/core-sdk/{BranchName}"; - GitHubAuth auth = new GitHubAuth(GitHubPassword); GitHubWriteVersionUpdater repoUpdater = new GitHubWriteVersionUpdater(auth); repoUpdater.UpdateBuildInfoAsync( Name, Version, - versionsRepoPath).Wait(); + VersionsRepoPath).Wait(); return true; } } - - // This code is a slightly modified port of GitHubVersionsRepoUpdater from - // https://raw.githubusercontent.com/dotnet/buildtools/master/src/Microsoft.DotNet.VersionTools/Automation/GitHubVersionsRepoUpdater.cs - internal class GitHubWriteVersionUpdater: VersionsRepoUpdater - { - private const int MaxTries = 10; - private const int RetryMillisecondsDelay = 5000; - - private GitHubAuth _gitHubAuth; - private GitHubProject _project; - - public GitHubWriteVersionUpdater( - GitHubAuth gitHubAuth, - string versionsRepoOwner = null, - string versionsRepo = null) - : this( - gitHubAuth, - new GitHubProject(versionsRepo ?? "versions", versionsRepoOwner)) - { - } - - public GitHubWriteVersionUpdater(GitHubAuth gitHubAuth, GitHubProject project) - { - if (gitHubAuth == null) - { - throw new ArgumentNullException(nameof(gitHubAuth)); - } - _gitHubAuth = gitHubAuth; - - if (project == null) - { - throw new ArgumentNullException(nameof(project)); - } - _project = project; - } - /// If true, updates Latest.txt with a prerelease moniker. If there isn't one, makes the file empty. - /// If true, updates Latest_Packages.txt. - public async ThreadingTasks.Task UpdateBuildInfoAsync( - string versionIdentifier, - string version, - string versionsRepoPath, - bool updateLatestPackageList = true, - bool updateLatestVersion = true) - { - if (versionIdentifier == null) - { - throw new ArgumentNullException(nameof(versionIdentifier)); - } - if (version == null) - { - throw new ArgumentNullException(nameof(version)); - } - if (versionsRepoPath == null) - { - throw new ArgumentNullException(nameof(versionsRepoPath)); - } - - using (GitHubClient client = new GitHubClient(_gitHubAuth)) - { - for (int i = 0; i < MaxTries; i++) - { - try - { - // Master commit to use as new commit's parent. - string masterRef = "heads/master"; - GitReference currentMaster = await client.GetReferenceAsync(_project, masterRef); - string masterSha = currentMaster.Object.Sha; - - List objects = new List(); - - if (updateLatestVersion) - { - objects.Add(new GitObject - { - Path = $"{versionsRepoPath}/Latest.txt", - Type = GitObject.TypeBlob, - Mode = GitObject.ModeFile, - Content = version - }); - } - if (updateLatestPackageList) - { - objects.Add(new GitObject - { - Path = $"{versionsRepoPath}/Latest_Packages.txt", - Type = GitObject.TypeBlob, - Mode = GitObject.ModeFile, - Content = $"{versionIdentifier} {version}{Environment.NewLine}" - }); - } - string message = $"Updating {versionsRepoPath}"; - - GitTree tree = await client.PostTreeAsync(_project, masterSha, objects.ToArray()); - GitCommit commit = await client.PostCommitAsync(_project, message, tree.Sha, new[] { masterSha }); - - // Only fast-forward. Don't overwrite other changes: throw exception instead. - await client.PatchReferenceAsync(_project, masterRef, commit.Sha, force: false); - - Trace.TraceInformation($"Committed build-info update on attempt {i + 1}."); - break; - } - catch (HttpRequestException ex) - { - int nextTry = i + 1; - if (nextTry < MaxTries) - { - Trace.TraceInformation($"Encountered exception committing build-info update: {ex.Message}"); - Trace.TraceInformation($"Trying again in {RetryMillisecondsDelay}ms. {MaxTries - nextTry} tries left."); - await ThreadingTasks.Task.Delay(RetryMillisecondsDelay); - } - else - { - Trace.TraceInformation("Encountered exception committing build-info update."); - throw; - } - } - } - } - } - } } #endif