Skip to content

Commit

Permalink
Fixes for version collisions when generating global version (#20544)
Browse files Browse the repository at this point in the history
* Fixes for version collisions when generating global version
1. When adding global version, task versions initalized to major version 0 instead of major version
2. To avoid collisions, when determining global version, we need to look at versions across all tasks, not just the one being built

* cleanup
  • Loading branch information
merlynomsft authored Oct 15, 2024
1 parent e0b1a32 commit d10c07d
Showing 1 changed file with 78 additions and 35 deletions.
113 changes: 78 additions & 35 deletions BuildConfigGen/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,57 +155,97 @@ private static void MainInner(string? task, string? configs, int? currentSprintN
Dictionary<string, TaskStateStruct> taskVersionInfo = [];

{
var tasks = MakeOptionsReader.ReadMakeOptions(gitRootPath).AsEnumerable()
IEnumerable<KeyValuePair<string, MakeOptionsReader.AgentTask>> allTasksList = MakeOptionsReader.ReadMakeOptions(gitRootPath).AsEnumerable()
.Where(c => c.Value.Configs.Any()); // only tasks with configs

if (!allTasks)
{
var taskList = task!.Split(',', '|');
IEnumerable<KeyValuePair<string, MakeOptionsReader.AgentTask>> tasks;

tasks = tasks.Where(s => taskList.Where(tl => string.Equals(tl, s.Key, StringComparison.OrdinalIgnoreCase)).Any());
if (allTasks)
{
tasks = allTasksList;
}

foreach (var t in tasks)
else
{
taskVersionInfo.Add(t.Value.Name, new TaskStateStruct([], []));
var taskList = task!.Split(',', '|');
tasks = allTasksList.Where(s => taskList.Where(tl => string.Equals(tl, s.Key, StringComparison.OrdinalIgnoreCase)).Any());
}

foreach (var t in tasks)
if (includeLocalPackagesBuildConfig)
{
IEnumerable<string> configsList = FilterConfigsForTask(configs, t);
HashSet<Config.ConfigRecord> targetConfigs = GetConfigRecords(configsList, writeUpdates);
UpdateVersionsForTask(t.Value.Name, taskVersionInfo[t.Value.Name], targetConfigs, currentSprint, globalVersionPath, ref maxPatchForCurrentSprint, globalVersion, generatedFolder);
CheckForDuplicates(t.Value.Name, taskVersionInfo[t.Value.Name].configTaskVersionMapping);
}
Console.WriteLine("Updating global version...");
var tasksNeedingUpdates = new List<string>();

// when generating global version, we must enumerate all tasks to generate correct maxPatchForCurrentSprint across all tasks to avoid collisions
foreach (var t in allTasksList)
{
taskVersionInfo.Add(t.Value.Name, new TaskStateStruct([], []));
IEnumerable<string> configsList = FilterConfigsForTask(configs, t);
HashSet<Config.ConfigRecord> targetConfigs = GetConfigRecords(configsList, writeUpdates);
UpdateVersionsForTask(t.Value.Name, taskVersionInfo[t.Value.Name], targetConfigs, currentSprint, globalVersionPath, globalVersion, generatedFolder);

// bump patch number for global if any tasks invalidated.
if (taskVersionInfo.Values.Any(x => x.versionsUpdated.Any()))
bool taskTargettedForUpdating = allTasks || tasks.Where(x => x.Key == t.Value.Name).Any();
bool taskVersionsNeedUpdating = taskVersionInfo[t.Value.Name].versionsUpdated.Any();

if (taskVersionsNeedUpdating && !taskTargettedForUpdating)
{
tasksNeedingUpdates.Add(t.Value.Name);
}

UpdateMaxPatchForSprint(taskVersionInfo[t.Value.Name], currentSprint, ref maxPatchForCurrentSprint);
CheckForDuplicates(t.Value.Name, taskVersionInfo[t.Value.Name].configTaskVersionMapping);
}

if (tasksNeedingUpdates.Count > 0)
{
throw new Exception($"The following tasks have versions that need updating (needed for updating global version): {string.Join(", ", tasksNeedingUpdates)}. Please run 'node make.js build --task [taskname]' to update");
}

// bump patch number for global if any tasks invalidated or if there is no existing global version
if (taskVersionInfo.Values.Any(x => x.versionsUpdated.Any()) || globalVersion is null)
{
maxPatchForCurrentSprint = maxPatchForCurrentSprint + 1;

Console.WriteLine($"Global version: maxPatchForCurrentSprint = maxPatchForCurrentSprint + 1");
}

Console.WriteLine($"Global version update: globalVersion = {globalVersion} maxPatchForCurrentSprint={maxPatchForCurrentSprint}" );
}
else
{
maxPatchForCurrentSprint = maxPatchForCurrentSprint + 1;
foreach (var t in tasks)
{
taskVersionInfo.Add(t.Value.Name, new TaskStateStruct([], []));
IEnumerable<string> configsList = FilterConfigsForTask(configs, t);
HashSet<Config.ConfigRecord> targetConfigs = GetConfigRecords(configsList, writeUpdates);
UpdateVersionsForTask(t.Value.Name, taskVersionInfo[t.Value.Name], targetConfigs, currentSprint, globalVersionPath, globalVersion, generatedFolder);
CheckForDuplicates(t.Value.Name, taskVersionInfo[t.Value.Name].configTaskVersionMapping);
}
}

foreach (var t in tasks)
{
IEnumerable<string> configsList = FilterConfigsForTask(configs, t);

int taskMajorVersion = taskVersionInfo[t.Value.Name].configTaskVersionMapping[Config.Default].Major;

if (includeLocalPackagesBuildConfig)
{
if (globalVersion is null)
{
globalVersion = new TaskVersion(0, currentSprint, maxPatchForCurrentSprint);
globalVersion = new TaskVersion(taskMajorVersion, currentSprint, maxPatchForCurrentSprint);
}
else
{
if (globalVersion.Minor == currentSprint)
{
globalVersion = globalVersion.CloneWithMinorAndPatch(currentSprint, Math.Max(maxPatchForCurrentSprint, globalVersion.Patch));
globalVersion = globalVersion.CloneWithMajor(taskVersionInfo[t.Value.Name].configTaskVersionMapping[Config.Default].Major);
globalVersion = globalVersion.CloneWithMajor(taskMajorVersion);
}
else
{
// this could fail if there is a task with a future-sprint version, which should not be the case. If that happens, CheckForDuplicates will throw
globalVersion = globalVersion.CloneWithMinorAndPatch(currentSprint, 0);
globalVersion = globalVersion.CloneWithMajor(taskVersionInfo[t.Value.Name].configTaskVersionMapping[Config.Default].Major);
globalVersion = globalVersion.CloneWithMajor(taskMajorVersion);
}
}
}
Expand All @@ -226,7 +266,7 @@ private static void MainInner(string? task, string? configs, int? currentSprintN
}

ThrowWithUserFriendlyErrorToRerunWithWriteUpdatesIfVeriferError("(global)", skipContentCheck: false);

foreach (var t in tasks)
{
IEnumerable<string> configsList = FilterConfigsForTask(configs, t);
Expand Down Expand Up @@ -1035,7 +1075,7 @@ private static void CopyConfig(string gitRootPath, string taskTargetPathOrUnders
}
}

private static void UpdateVersionsForTask(string task, TaskStateStruct taskState, HashSet<Config.ConfigRecord> targetConfigs, int currentSprint, string globalVersionPath, ref int maxPatchForCurrentSprint, TaskVersion? globalVersion, string generatedFolder)
private static void UpdateVersionsForTask(string task, TaskStateStruct taskState, HashSet<Config.ConfigRecord> targetConfigs, int currentSprint, string globalVersionPath, TaskVersion? globalVersion, string generatedFolder)
{
string currentDir = Environment.CurrentDirectory;
string gitRootPath = GitUtil.GetGitRootPath(currentDir);
Expand Down Expand Up @@ -1102,23 +1142,23 @@ private static void UpdateVersionsForTask(string task, TaskStateStruct taskState
}
}

TaskVersion baseVersion = maxVersion;
if (!allConfigsMappedAndValid)
{
TaskVersion baseVersion = maxVersion;

bool baseVersionIsCurrentSprint = baseVersion.Minor == currentSprint;
bool baseVersionIsCurrentSprint = baseVersion.Minor == currentSprint;

int offset = 0;
int offset = 0;

if (baseVersionIsCurrentSprint)
{
offset = 1;
}
else
{
baseVersion = inputVersion.CloneWithMinorAndPatch(currentSprint, 0);
}
if (baseVersionIsCurrentSprint)
{
offset = 1;
}
else
{
baseVersion = inputVersion.CloneWithMinorAndPatch(currentSprint, 0);
}

if (!allConfigsMappedAndValid)
{
var old = new Dictionary<Config.ConfigRecord, TaskVersion>();
foreach (var x in taskState.configTaskVersionMapping)
{
Expand Down Expand Up @@ -1181,7 +1221,10 @@ private static void UpdateVersionsForTask(string task, TaskStateStruct taskState
}
}
}
}

private static void UpdateMaxPatchForSprint(TaskStateStruct taskState, int currentSprint, ref int maxPatchForCurrentSprint)
{
foreach (var x in taskState.configTaskVersionMapping)
{
// accumulate the max patch, excluding existing globalversion (used for providing a new global version)
Expand Down

0 comments on commit d10c07d

Please sign in to comment.