Skip to content

Commit 9307f34

Browse files
sanjuyadav24kboomSanju Yadav
authored
Canary Task Rollouts (#21160)
* Initial changes * Generator * working version * TEST update to task * Remove unecessary changes * Example task changes - commit to be removed prior to merging * Task release pipeline add semvar changes * Revert "Example task changes - commit to be removed prior to merging" This reverts commit 6a41025. * Merge conflict fixes * Updated Powershellv2 version * Code review fixes * Code review fixes - semantic fixes Co-authored-by: Grzegorz Gurgul <[email protected]> Co-authored-by: Sanju Yadav <[email protected]>
1 parent 03a706b commit 9307f34

File tree

11 files changed

+331
-120
lines changed

11 files changed

+331
-120
lines changed

.azure-pipelines/.vsts.release.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ parameters:
4444
displayName: Dry Run (no push, no PR, no feed publish)
4545
type: boolean
4646
default: false
47+
- name: useSemverBuildConfig
48+
displayName: Use Semver Build Config to support canary rollout
49+
type: boolean
50+
default: false
4751

4852
variables:
4953
- name: currentDate
@@ -134,6 +138,7 @@ extends:
134138
- template: /ci/build-all-steps.yml@self
135139
parameters:
136140
os: Windows_NT
141+
useSemverBuildConfig: ${{ parameters.useSemverBuildConfig }}
137142

138143
# Publish
139144
- job: publish
@@ -217,4 +222,5 @@ extends:
217222
- template: /ci/build-all-tasks.yml@self
218223
parameters:
219224
deploy_all_tasks: ${{ eq(parameters.task_deployment, 'Deploy all Tasks') }}
225+
useSemverBuildConfig: ${{ parameters.useSemverBuildConfig }}
220226

BuildConfigGen/Debugging/VsCodeLaunchConfigGenerator.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ public void AddForTask(string taskConfigPath)
4242
int major = versionNode["Major"]!.GetValue<int>();
4343
int minor = versionNode["Minor"]!.GetValue<int>();
4444
int patch = versionNode["Patch"]!.GetValue<int>();
45+
string? build = versionNode["Build"]?.GetValue<string>() ?? null;
4546

46-
var version = new TaskVersion(major, minor, patch);
47+
var version = new TaskVersion(major, minor, patch, build);
4748

4849
LaunchConfig.AddConfigForTask(
4950
taskId: taskConfig["id"]!.GetValue<string>(),

BuildConfigGen/Program.cs

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ internal static class Config
4646
{
4747
public static readonly string[] ExtensionsToPreprocess = new[] { ".ts", ".json" };
4848

49-
public record ConfigRecord(string name, string constMappingKey, bool isDefault, bool isNode, string nodePackageVersion, bool isWif, string nodeHandler, string preprocessorVariableName, bool enableBuildConfigOverrides, bool deprecated, bool shouldUpdateTypescript, bool writeNpmrc, string? overriddenDirectoryName = null, bool shouldUpdateLocalPkgs = false, bool useGlobalVersion = false, bool useAltGeneratedPath = false, bool mergeToBase = false);
49+
public record ConfigRecord(string name, string constMappingKey, bool isDefault, bool isNode, string nodePackageVersion, bool isWif, string nodeHandler, string preprocessorVariableName, bool enableBuildConfigOverrides, bool deprecated, bool shouldUpdateTypescript, bool writeNpmrc, string? overriddenDirectoryName = null, bool shouldUpdateLocalPkgs = false, bool useGlobalVersion = false, bool useAltGeneratedPath = false, bool mergeToBase = false, bool abTaskReleases = true);
5050

5151
public static readonly ConfigRecord Default = new ConfigRecord(name: nameof(Default), constMappingKey: "Default", isDefault: true, isNode: false, nodePackageVersion: "", isWif: false, nodeHandler: "", preprocessorVariableName: "DEFAULT", enableBuildConfigOverrides: false, deprecated: false, shouldUpdateTypescript: false, writeNpmrc: false);
5252
public static readonly ConfigRecord Node16 = new ConfigRecord(name: nameof(Node16), constMappingKey: "Node16-219", isDefault: false, isNode: true, nodePackageVersion: "^16.11.39", isWif: false, nodeHandler: "Node16", preprocessorVariableName: "NODE16", enableBuildConfigOverrides: true, deprecated: true, shouldUpdateTypescript: false, writeNpmrc: false);
@@ -86,12 +86,22 @@ public record ConfigRecord(string name, string constMappingKey, bool isDefault,
8686
/// <param name="getTaskVersionTable"></param>
8787
/// <param name="debugAgentDir">When set to the local pipeline agent directory, this tool will produce tasks in debug mode with the corresponding visual studio launch configurations that can be used to attach to built tasks running on this agent</param>
8888
/// <param name="includeLocalPackagesBuildConfig">Include LocalPackagesBuildConfig</param>
89-
static void Main(string? task = null, string? configs = null, int? currentSprint = null, bool writeUpdates = false, bool allTasks = false, bool getTaskVersionTable = false, string? debugAgentDir = null, bool includeLocalPackagesBuildConfig = false)
89+
/// <param name="useSemverBuildConfig">If true, the semver "build" (suffix) will be generated for each task configuration produced, but all tasks configurations will have the same version (for example '1.2.3-node20' and 1.2.3-wif). The default configuration gets no build suffix (e.g. 1.2.3).</param>
90+
static void Main(
91+
string? task = null,
92+
string? configs = null,
93+
int? currentSprint = null,
94+
bool writeUpdates = false,
95+
bool allTasks = false,
96+
bool getTaskVersionTable = false,
97+
string? debugAgentDir = null,
98+
bool includeLocalPackagesBuildConfig = false,
99+
bool useSemverBuildConfig = false)
90100
{
91101
try
92102
{
93103
ensureUpdateModeVerifier = new EnsureUpdateModeVerifier(!writeUpdates);
94-
MainInner(task, configs, currentSprint, writeUpdates, allTasks, getTaskVersionTable, debugAgentDir, includeLocalPackagesBuildConfig);
104+
MainInner(task, configs, currentSprint, writeUpdates, allTasks, getTaskVersionTable, debugAgentDir, includeLocalPackagesBuildConfig, useSemverBuildConfig);
95105
}
96106
catch (Exception e2)
97107
{
@@ -113,7 +123,16 @@ static void Main(string? task = null, string? configs = null, int? currentSprint
113123
}
114124
}
115125

116-
private static void MainInner(string? task, string? configs, int? currentSprintNullable, bool writeUpdates, bool allTasks, bool getTaskVersionTable, string? debugAgentDir, bool includeLocalPackagesBuildConfig)
126+
private static void MainInner(
127+
string? task,
128+
string? configs,
129+
int? currentSprintNullable,
130+
bool writeUpdates,
131+
bool allTasks,
132+
bool getTaskVersionTable,
133+
string? debugAgentDir,
134+
bool includeLocalPackagesBuildConfig,
135+
bool useSemverBuildConfig)
117136
{
118137
if (allTasks)
119138
{
@@ -313,7 +332,18 @@ private static void MainInner(string? task, string? configs, int? currentSprintN
313332
{
314333
IEnumerable<string> configsList = FilterConfigsForTask(configs, t);
315334

316-
MainUpdateTask(taskVersionInfo[t.Value.Name], t.Value.Name, configsList, writeUpdates, currentSprint, debugConfGen, includeLocalPackagesBuildConfig, hasGlobalVersion: globalVersion is not null, generatedFolder: generatedFolder, altGeneratedFolder: altGeneratedFolder);
335+
MainUpdateTask(
336+
taskVersionInfo[t.Value.Name],
337+
t.Value.Name,
338+
configsList,
339+
writeUpdates,
340+
currentSprint,
341+
debugConfGen,
342+
includeLocalPackagesBuildConfig,
343+
hasGlobalVersion: globalVersion is not null,
344+
generatedFolder: generatedFolder,
345+
altGeneratedFolder: altGeneratedFolder,
346+
useSemverBuildConfig: useSemverBuildConfig);
317347
}
318348

319349
debugConfGen.WriteLaunchConfigurations();
@@ -464,6 +494,7 @@ private static void GetVersions(string task, string configsString, out List<(str
464494
string gitRootPath = GetTasksRootPath(currentDir);
465495

466496
string taskTargetPath = Path.Combine(gitRootPath, "Tasks", task);
497+
467498
if (!Directory.Exists(taskTargetPath))
468499
{
469500
throw new Exception($"expected {taskTargetPath} to exist!");
@@ -572,7 +603,8 @@ private static void MainUpdateTask(
572603
bool includeLocalPackagesBuildConfig,
573604
bool hasGlobalVersion,
574605
string generatedFolder,
575-
string altGeneratedFolder)
606+
string altGeneratedFolder,
607+
bool useSemverBuildConfig)
576608
{
577609
if (string.IsNullOrEmpty(task))
578610
{
@@ -717,7 +749,18 @@ private static void MainUpdateTask(
717749
WriteWIFInputTaskJson(taskOutput, config, "task.json", isLoc: false);
718750
WriteWIFInputTaskJson(taskOutput, config, "task.loc.json", isLoc: true);
719751

720-
if (!config.mergeToBase)
752+
if (useSemverBuildConfig && !config.mergeToBase)
753+
{
754+
var defaultConfig = targetConfigs.FirstOrDefault(x => x.isDefault);
755+
if (defaultConfig == null)
756+
{
757+
throw new Exception($"There is no default config for task {task}");
758+
}
759+
760+
WriteTaskJson(taskOutput, taskVersionState, config, "task.json", existingLocalPackageVersion, useSemverBuildConfig: true, defaultConfig: defaultConfig);
761+
WriteTaskJson(taskOutput, taskVersionState, config, "task.loc.json", existingLocalPackageVersion, useSemverBuildConfig: true, defaultConfig: defaultConfig);
762+
}
763+
else if (!config.mergeToBase)
721764
{
722765
WriteTaskJson(taskOutput, taskVersionState, config, "task.json", existingLocalPackageVersion);
723766
WriteTaskJson(taskOutput, taskVersionState, config, "task.loc.json", existingLocalPackageVersion);
@@ -1048,7 +1091,12 @@ private static void PreprocessIfExtensionEnabledInConfig(string file, Config.Con
10481091
return outputTaskNodeObject["_buildConfigMapping"]?.AsObject()?[Config.LocalPackages.constMappingKey]?.GetValue<string>();
10491092
}
10501093

1051-
private static void WriteTaskJson(string taskPath, TaskStateStruct taskState, Config.ConfigRecord config, string fileName, string? existingLocalPackageVersion)
1094+
/// <summary>
1095+
/// Writes task.json with version information and build config mapping.
1096+
/// When useSemverBuildConfig is true, uses the same major.minor.patch for all build configuration tasks,
1097+
/// but the "build" suffix of semver is different and directly corresponds to the config name.
1098+
/// </summary>
1099+
private static void WriteTaskJson(string taskPath, TaskStateStruct taskState, Config.ConfigRecord config, string fileName, string? existingLocalPackageVersion, bool useSemverBuildConfig = false, Config.ConfigRecord? defaultConfig = null)
10521100
{
10531101
string outputTaskPath = Path.Combine(taskPath, fileName);
10541102
JsonNode outputTaskNode = JsonNode.Parse(ensureUpdateModeVerifier!.FileReadAllText(outputTaskPath))!;
@@ -1057,6 +1105,12 @@ private static void WriteTaskJson(string taskPath, TaskStateStruct taskState, Co
10571105
outputTaskNode["version"]!["Minor"] = taskState.configTaskVersionMapping[config].Minor;
10581106
outputTaskNode["version"]!["Patch"] = taskState.configTaskVersionMapping[config].Patch;
10591107

1108+
// Add semver build suffix if using semver config and not the default config
1109+
if (useSemverBuildConfig && defaultConfig != null && defaultConfig != config)
1110+
{
1111+
outputTaskNode["version"]!["Build"] = config.constMappingKey;
1112+
}
1113+
10601114
var outputTaskNodeObject = outputTaskNode.AsObject();
10611115
outputTaskNodeObject.Remove("_buildConfigMapping");
10621116

@@ -1305,7 +1359,6 @@ private static void UpdateVersionsForTask(string task, TaskStateStruct taskState
13051359
string currentDir = Environment.CurrentDirectory;
13061360
string gitRootPath = GetTasksRootPath(currentDir);
13071361
string taskTargetPath = Path.Combine(gitRootPath, "Tasks", task);
1308-
13091362
if (!Directory.Exists(taskTargetPath))
13101363
{
13111364
throw new Exception($"expected {taskTargetPath} to exist!");
@@ -1481,6 +1534,13 @@ private static void UpdateVersionsForTask(string task, TaskStateStruct taskState
14811534
}
14821535
while (taskState.configTaskVersionMapping.Values.Contains(targetVersion));
14831536

1537+
if (config.abTaskReleases)
1538+
{
1539+
// In the first stage of refactoring, we keep different version numbers to retain the ability to rollback.
1540+
// In the second stage of refactoring, we are going to use the same version, which is going to significantly reduce complexity of all this.
1541+
targetVersion = targetVersion.CloneWithBuild(config.constMappingKey);
1542+
}
1543+
14841544
taskState.configTaskVersionMapping.Add(config, targetVersion);
14851545

14861546
if (!taskState.versionsUpdated.Contains(config))
@@ -1555,11 +1615,20 @@ private static void UpdateVersionsGlobal(string task, TaskStateStruct taskState,
15551615
{
15561616
if (config.useGlobalVersion)
15571617
{
1618+
TaskVersion versionToUse = globalVersion;
1619+
1620+
if (config.abTaskReleases)
1621+
{
1622+
// In the first stage of refactoring, we keep different version numbers to retain the ability to rollback.
1623+
// In the second stage of refactoring, we are going to use the same version, which is going to significantly reduce complexity of all this.
1624+
versionToUse = globalVersion.CloneWithBuild(config.constMappingKey);
1625+
}
1626+
15581627
if (taskState.configTaskVersionMapping.ContainsKey(config))
15591628
{
1560-
if (taskState.configTaskVersionMapping[config] != globalVersion)
1629+
if (taskState.configTaskVersionMapping[config] != versionToUse)
15611630
{
1562-
taskState.configTaskVersionMapping[config] = globalVersion;
1631+
taskState.configTaskVersionMapping[config] = versionToUse;
15631632

15641633
if (!taskState.versionsUpdated.Contains(config))
15651634
{
@@ -1569,7 +1638,7 @@ private static void UpdateVersionsGlobal(string task, TaskStateStruct taskState,
15691638
}
15701639
else
15711640
{
1572-
taskState.configTaskVersionMapping.Add(config, globalVersion);
1641+
taskState.configTaskVersionMapping.Add(config, versionToUse);
15731642

15741643
if (!taskState.versionsUpdated.Contains(config))
15751644
{

BuildConfigGen/Properties/launchSettings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
"BuildConfigGen": {
44
"commandName": "Project",
55
"commandLineArgs": "--all-tasks --write-updates"
6+
},
7+
"BuildConfigGenNew": {
8+
"commandName": "Project",
9+
"commandLineArgs": "--use-semver-build-config --all-tasks --write-updates"
610
}
711
}
812
}

0 commit comments

Comments
 (0)