diff --git a/build/Microsoft.DotNet.Cli.tasks b/build/Microsoft.DotNet.Cli.tasks
index 58227dce8..67085b6fc 100644
--- a/build/Microsoft.DotNet.Cli.tasks
+++ b/build/Microsoft.DotNet.Cli.tasks
@@ -31,7 +31,7 @@
-
+
diff --git a/build/publish/FinishBuild.targets b/build/publish/FinishBuild.targets
index fd439bab0..49efcf115 100644
--- a/build/publish/FinishBuild.targets
+++ b/build/publish/FinishBuild.targets
@@ -32,10 +32,14 @@
Channel="$(Channel)"
CommitHash="$(CommitHash)"
Coherent="$(Coherent)" />
-
-
+
+
+
diff --git a/build_projects/dotnet-cli-build/UpdateVersionsRepo.cs b/build_projects/dotnet-cli-build/UpdateVersionsRepo.cs
deleted file mode 100644
index 7baae1795..000000000
--- a/build_projects/dotnet-cli-build/UpdateVersionsRepo.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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.Build.Framework;
-using Microsoft.Build.Utilities;
-using Microsoft.DotNet.VersionTools.Automation;
-using System.IO;
-
-
-namespace Microsoft.DotNet.Cli.Build
-{
- public class UpdateVersionsRepo : Task
- {
- [Required]
- public string BranchName { get; set; }
-
- [Required]
- public string PackagesDirectory { get; set; }
-
- [Required]
- public string GitHubPassword { get; set; }
-
- public override bool Execute()
- {
- string versionsRepoPath = $"build-info/dotnet/core-sdk/{BranchName}";
-
- GitHubAuth auth = new GitHubAuth(GitHubPassword);
- GitHubVersionsRepoUpdater repoUpdater = new GitHubVersionsRepoUpdater(auth);
- repoUpdater.UpdateBuildInfoAsync(
- Directory.GetFiles(PackagesDirectory, "*.nupkg"),
- versionsRepoPath).Wait();
-
- return true;
- }
- }
-}
-#endif
diff --git a/build_projects/dotnet-cli-build/WriteVersionToVersionsRepo.cs b/build_projects/dotnet-cli-build/WriteVersionToVersionsRepo.cs
new file mode 100644
index 000000000..6f2c99d9f
--- /dev/null
+++ b/build_projects/dotnet-cli-build/WriteVersionToVersionsRepo.cs
@@ -0,0 +1,171 @@
+// 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.Build.Framework;
+using MSBuildUtilities = 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
+ {
+ [Required]
+ public string BranchName { get; set; }
+
+ [Required]
+ public string Name { get; set; }
+
+ [Required]
+ public string Version { get; set; }
+
+ [Required]
+ public string GitHubPassword { get; set; }
+
+ 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();
+
+ 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