Skip to content

Commit 871f0e7

Browse files
authored
Fixes and updates to enable courtesy push for locakpackage config (#20608)
Fixes and updates to enable courtesy push for locakpackage config LocalPackage - write and consume build modified package-lock.json to _generated_buildConfigs so we avoid filtertasks over-selection to LocalPackage updates LocalPackage - Temporarily pull in mock fix BuildConfigGen Fix: writes to non-copied files were not validated LocalPackage - Fix for automatically bumping globalversion.txt when needed Increase build timeouts (to support build all = true parameter) Fix for 'build all' parameter not working when courtesy push enabled (filterTasks fix) Parameterized test options for courtesy push (skip tests, use test feed
1 parent 8db3cc5 commit 871f0e7

File tree

8 files changed

+179
-54
lines changed

8 files changed

+179
-54
lines changed

BuildConfigGen/EnsureUpdateModeVerifier.cs

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,25 @@ public IEnumerable<string> GetVerifyErrors(bool skipContentCheck)
3333

3434
if (!skipContentCheck)
3535
{
36+
foreach(var r in RedirectedToTempl)
37+
{
38+
string? sourceFile;
39+
string procesed = "";
40+
41+
string? tempToKeep = null;
42+
sourceFile = r.Value;
43+
procesed = $"(processed temp={sourceFile}) ";
44+
tempToKeep = sourceFile;
45+
46+
string? contentError = null;
47+
contentError = CompareFile(r, sourceFile, procesed, tempToKeep, contentError);
48+
49+
if (contentError is not null)
50+
{
51+
yield return contentError;
52+
}
53+
}
54+
3655
foreach (var r in CopiedFilesToCheck)
3756
{
3857
string? sourceFile;
@@ -49,30 +68,44 @@ public IEnumerable<string> GetVerifyErrors(bool skipContentCheck)
4968
sourceFile = r.Value;
5069
}
5170

52-
FileInfo fi = new FileInfo(r.Key);
71+
string? contentError = null;
72+
contentError = CompareFile(r, sourceFile, procesed, tempToKeep, contentError);
5373

54-
if (fi.Name.Equals("resources.resjson", StringComparison.OrdinalIgnoreCase))
74+
if (contentError is not null)
5575
{
56-
// resources.resjson is generated by make.js and does not need to be verified
57-
// it can differ between configs if configs have different inputs (causes verifier to fail);
76+
yield return contentError;
5877
}
59-
else
78+
}
79+
}
80+
}
81+
82+
private string? CompareFile(KeyValuePair<string, string> r, string sourceFile, string procesed, string? tempToKeep, string? contentError)
83+
{
84+
FileInfo fi = new FileInfo(r.Key);
85+
86+
if (fi.Name.Equals("resources.resjson", StringComparison.OrdinalIgnoreCase))
87+
{
88+
// resources.resjson is generated by make.js and does not need to be verified
89+
// it can differ between configs if configs have different inputs (causes verifier to fail);
90+
}
91+
else
92+
{
93+
if (Helpers.FilesEqual(sourceFile, r.Key))
94+
{
95+
// if overwrite and content match, everything is good! Verification passed.
96+
}
97+
else
98+
{
99+
if (tempToKeep != null)
60100
{
61-
if (Helpers.FilesEqual(sourceFile, r.Key))
62-
{
63-
// if overwrite and content match, everything is good! Verification passed.
64-
}
65-
else
66-
{
67-
if (tempToKeep != null)
68-
{
69-
this.tempsToKeep.Add(tempToKeep!);
70-
}
71-
yield return $"Content doesn't match {r.Value} {procesed}to {r.Key} (overwrite=true). Dest file doesn't match source.";
72-
}
101+
this.tempsToKeep.Add(tempToKeep!);
73102
}
103+
104+
contentError = $"Content doesn't match {r.Value} {procesed}to {r.Key} (overwrite=true). Dest file doesn't match source.";
74105
}
75106
}
107+
108+
return contentError;
76109
}
77110

78111
public void CleanupTempFiles()

BuildConfigGen/Program.cs

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ private static void MainInner(string? task, string? configs, int? currentSprintN
192192
}
193193

194194
UpdateMaxPatchForSprint(taskVersionInfo[t.Value.Name], currentSprint, ref maxPatchForCurrentSprint);
195-
CheckForDuplicates(t.Value.Name, taskVersionInfo[t.Value.Name].configTaskVersionMapping);
195+
CheckForDuplicates(t.Value.Name, taskVersionInfo[t.Value.Name].configTaskVersionMapping, checkGlobalVersion: false);
196196
}
197197

198198
if (tasksNeedingUpdates.Count > 0)
@@ -201,11 +201,14 @@ private static void MainInner(string? task, string? configs, int? currentSprintN
201201
}
202202

203203
// bump patch number for global if any tasks invalidated or if there is no existing global version
204-
if (taskVersionInfo.Values.Any(x => x.versionsUpdated.Any()) || globalVersion is null)
204+
bool anyTaskVersionUpdated = taskVersionInfo.Values.Any(x => x.versionsUpdated.Any());
205+
bool noCurrentGlobalVersion = globalVersion is null;
206+
bool maxPatchForCurrentSprintGreaterOrEqualToGlobalPatch = globalVersion is not null && maxPatchForCurrentSprint >= globalVersion.Patch;
207+
if (anyTaskVersionUpdated || noCurrentGlobalVersion || maxPatchForCurrentSprintGreaterOrEqualToGlobalPatch)
205208
{
206209
maxPatchForCurrentSprint = maxPatchForCurrentSprint + 1;
207210

208-
Console.WriteLine($"Global version: maxPatchForCurrentSprint = maxPatchForCurrentSprint + 1");
211+
Console.WriteLine($"Global version: maxPatchForCurrentSprint = maxPatchForCurrentSprint + 1 anyTaskVersionUpdated={anyTaskVersionUpdated} noCurrentGlobalVersion={noCurrentGlobalVersion} maxPatchForCurrentSprintGreaterOrEqualToGlobalPatch={maxPatchForCurrentSprintGreaterOrEqualToGlobalPatch}");
209212
}
210213

211214
Console.WriteLine($"Global version update: globalVersion = {globalVersion} maxPatchForCurrentSprint={maxPatchForCurrentSprint}");
@@ -218,7 +221,7 @@ private static void MainInner(string? task, string? configs, int? currentSprintN
218221
IEnumerable<string> configsList = FilterConfigsForTask(configs, t);
219222
HashSet<Config.ConfigRecord> targetConfigs = GetConfigRecords(configsList, writeUpdates);
220223
UpdateVersionsForTask(t.Value.Name, taskVersionInfo[t.Value.Name], targetConfigs, currentSprint, globalVersionPath, globalVersion, generatedFolder);
221-
CheckForDuplicates(t.Value.Name, taskVersionInfo[t.Value.Name].configTaskVersionMapping);
224+
CheckForDuplicates(t.Value.Name, taskVersionInfo[t.Value.Name].configTaskVersionMapping, checkGlobalVersion: true);
222225
}
223226
}
224227

@@ -264,7 +267,7 @@ private static void MainInner(string? task, string? configs, int? currentSprintN
264267
HashSet<Config.ConfigRecord> targetConfigs = GetConfigRecords(configsList, writeUpdates);
265268

266269
UpdateVersionsGlobal(t.Value.Name, taskVersionInfo[t.Value.Name], targetConfigs, globalVersion);
267-
CheckForDuplicates(t.Value.Name, taskVersionInfo[t.Value.Name].configTaskVersionMapping);
270+
CheckForDuplicates(t.Value.Name, taskVersionInfo[t.Value.Name].configTaskVersionMapping, checkGlobalVersion: true);
268271
}
269272
}
270273

@@ -335,15 +338,25 @@ private static IEnumerable<string> FilterConfigsForTask(string? configs, KeyValu
335338
return configsList;
336339
}
337340

338-
private static void CheckForDuplicates(string task, Dictionary<Config.ConfigRecord, TaskVersion> configTaskVersionMapping)
341+
private static void CheckForDuplicates(string task, Dictionary<Config.ConfigRecord, TaskVersion> configTaskVersionMapping, bool checkGlobalVersion)
339342
{
340-
var duplicateVersions = configTaskVersionMapping.GroupBy(x => x.Value).Select(x => new { version = x.Key, configName = String.Join(",", x.Select(x => x.Key.name)), count = x.Count() }).Where(x => x.count > 1);
343+
var duplicateVersions = configTaskVersionMapping
344+
.Where(x => checkGlobalVersion || !x.Key.useGlobalVersion)
345+
.GroupBy(x => x.Value)
346+
.Select(x => new { version = x.Key, hasGlobal = x.Where(x => x.Key.useGlobalVersion).Any(), configName = String.Join(",", x.Select(x => x.Key.name)), count = x.Count() }).Where(x => x.count > 1);
341347
if (duplicateVersions.Any())
342348
{
343349
StringBuilder dupConfigsStr = new StringBuilder();
344350
foreach (var x in duplicateVersions)
345351
{
346-
dupConfigsStr.AppendLine($"task={task} version={x.version} specified in multiple configName={x.configName} config count={x.count}");
352+
if (x.hasGlobal)
353+
{
354+
dupConfigsStr.AppendLine($"task={task} version={x.version} specified in multiple configName={x.configName} config count={x.count}. To fix, check-in globalversion.txt change generated by running 'node make.js build --task {task} --includeLocalPackagesBuildConfig'");
355+
}
356+
else
357+
{
358+
dupConfigsStr.AppendLine($"task={task} version={x.version} specified in multiple configName={x.configName} config count={x.count}");
359+
}
347360
}
348361

349362
throw new Exception(dupConfigsStr.ToString());
@@ -549,7 +562,7 @@ private static void MainUpdateTask(
549562

550563
if (config.enableBuildConfigOverrides)
551564
{
552-
EnsureBuildConfigFileOverrides(config, taskTargetPath);
565+
EnsureBuildConfigFileOverrides(config, taskTargetPath, generatedFolder, task);
553566
}
554567

555568
try
@@ -600,7 +613,7 @@ private static void MainUpdateTask(
600613

601614
if (config.enableBuildConfigOverrides)
602615
{
603-
CopyConfigOverrides(gitRootPath, taskTargetPath, taskOutput, config);
616+
CopyConfigOverrides(gitRootPath, taskTargetPath, taskOutput, config, generatedFolder, task);
604617
}
605618

606619
// if some files aren't present in destination, stop as following code assumes they're present and we'll just get a FileNotFoundException
@@ -620,7 +633,7 @@ private static void MainUpdateTask(
620633

621634
if (config.isNode)
622635
{
623-
GetBuildConfigFileOverridePaths(config, taskTargetPath, out string configTaskPath, out string readmePath);
636+
GetBuildConfigFileOverridePaths(config, taskTargetPath, out string configTaskPath, out string readmePath, generatedFolder, task);
624637

625638
string buildConfigPackageJsonPath = Path.Combine(taskTargetPath, buildConfigs, configTaskPath, "package.json");
626639

@@ -781,15 +794,15 @@ private static bool HasTaskInputContainsPreprocessorInstructions(string gitRootP
781794
return hasPreprocessorDirectives;
782795
}
783796

784-
private static void EnsureBuildConfigFileOverrides(Config.ConfigRecord config, string taskTargetPath)
797+
private static void EnsureBuildConfigFileOverrides(Config.ConfigRecord config, string taskTargetPath, string generatedFolder, string taskName)
785798
{
786799
if (!config.enableBuildConfigOverrides)
787800
{
788801
throw new Exception("BUG: should not get here: !config.enableBuildConfigOverrides");
789802
}
790803

791804
string path, readmeFile;
792-
GetBuildConfigFileOverridePaths(config, taskTargetPath, out path, out readmeFile);
805+
GetBuildConfigFileOverridePaths(config, taskTargetPath, out path, out readmeFile, generatedFolder, taskName);
793806

794807
if (!Directory.Exists(path))
795808
{
@@ -799,7 +812,7 @@ private static void EnsureBuildConfigFileOverrides(Config.ConfigRecord config, s
799812
ensureUpdateModeVerifier!.WriteAllText(readmeFile, "Place files overridden for this config in this directory", suppressValidationErrorIfTargetPathDoesntExist: !Knob.Default.SourceDirectoriesMustContainPlaceHolders);
800813
}
801814

802-
private static void GetBuildConfigFileOverridePaths(Config.ConfigRecord config, string taskTargetPath, out string path, out string readmeFile)
815+
private static void GetBuildConfigFileOverridePaths(Config.ConfigRecord config, string taskTargetPath, out string path, out string readmeFile, string generatedFolder, string taskName)
803816
{
804817
string directoryName = config.name;
805818

@@ -813,19 +826,28 @@ private static void GetBuildConfigFileOverridePaths(Config.ConfigRecord config,
813826
directoryName = config.overriddenDirectoryName;
814827
}
815828

816-
path = Path.Combine(taskTargetPath, buildConfigs, directoryName);
817-
readmeFile = Path.Combine(taskTargetPath, buildConfigs, directoryName, filesOverriddenForConfigGoHereReadmeTxt);
829+
if (config.useGlobalVersion)
830+
{
831+
// for global version, place artifacts in _generated (such as package-lock)
832+
path = Path.Combine(generatedFolder, buildConfigs, taskName, directoryName);
833+
readmeFile = Path.Combine(generatedFolder, buildConfigs, taskName, directoryName, filesOverriddenForConfigGoHereReadmeTxt);
834+
}
835+
else
836+
{
837+
path = Path.Combine(taskTargetPath, buildConfigs, directoryName);
838+
readmeFile = Path.Combine(taskTargetPath, buildConfigs, directoryName, filesOverriddenForConfigGoHereReadmeTxt);
839+
}
818840
}
819841

820-
private static void CopyConfigOverrides(string gitRootPath, string taskTargetPath, string taskOutput, Config.ConfigRecord config)
842+
private static void CopyConfigOverrides(string gitRootPath, string taskTargetPath, string taskOutput, Config.ConfigRecord config, string generatedFolder, string taskName)
821843
{
822844
if (!config.enableBuildConfigOverrides)
823845
{
824846
throw new Exception("BUG: should not get here: !config.enableBuildConfigOverrides");
825847
}
826848

827849
string overridePathForBuildConfig;
828-
GetBuildConfigFileOverridePaths(config, taskTargetPath, out overridePathForBuildConfig, out _);
850+
GetBuildConfigFileOverridePaths(config, taskTargetPath, out overridePathForBuildConfig, out _, generatedFolder, taskName);
829851

830852
bool doCopy;
831853
if (Knob.Default.SourceDirectoriesMustContainPlaceHolders)

azure-pipelines.yml

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ parameters:
3333
displayName: Flag to update LocalPackages buildconfig (for testing, this will be made default later)
3434
type: boolean
3535
default: false # note: keep in sync with ci\ci-test-tasks\canary-tests-v2.yml
36+
- name: skip_tests
37+
displayName: skipTests (Not for production use)
38+
type: boolean
39+
default: false
40+
- name: publishToDistributedTaskTest
41+
displayName: Publish to test feed (DistributedTasks-test), for infrastucture testing
42+
type: boolean
43+
default: false
3644

3745
variables:
3846
- name: currentDate
@@ -55,6 +63,16 @@ variables:
5563
value: '1'
5664
${{ else }}:
5765
value: ''
66+
- name: tasksSkipTests
67+
${{ if eq(parameters.skip_tests, true) }}:
68+
value: 'true'
69+
${{ else }}:
70+
value: 'false'
71+
- name: DEPLOY_ALL_TASKSVAR
72+
${{ if eq(parameters.deploy_all_tasks, true) }}:
73+
value: 'true'
74+
${{ else }}:
75+
value: 'false'
5876

5977
extends:
6078
template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates
@@ -86,7 +104,7 @@ extends:
86104
- job: build_all_windows
87105
displayName: Build all tasks (Windows)
88106
condition: eq(variables.os, 'Windows_NT')
89-
timeoutInMinutes: 360
107+
timeoutInMinutes: 1440 # AntiMalware takes 3 hours to scan tasks.zip
90108
pool:
91109
name: 1ES-ABTT-Shared-Pool
92110
image: abtt-windows-2022
@@ -111,6 +129,7 @@ extends:
111129
# Publish
112130
- job: publish
113131
displayName: Publish
132+
timeoutInMinutes: 360
114133
dependsOn:
115134
- build_all_windows
116135
condition: and(succeeded(), ne(variables['build.reason'], 'PullRequest'))
@@ -154,7 +173,10 @@ extends:
154173
- output: nuget
155174
packagesToPush: '$(Build.SourcesDirectory)/IndividualNugetPackagesDownloaded/IndividualNugetPackages/*/*.nupkg'
156175
packageParentPath: '$(Build.SourcesDirectory)'
157-
publishVstsFeed: 'c86767d8-af79-4303-a7e6-21da0ba435e2/e10d0795-57cd-4d7f-904e-5f39703cb096'
176+
${{ if eq(parameters.publishToDistributedTaskTest, true) }}:
177+
publishVstsFeed: 'c86767d8-af79-4303-a7e6-21da0ba435e2/9d34d871-8032-4e10-a34a-c7a01e125865'
178+
${{ else }}:
179+
publishVstsFeed: 'c86767d8-af79-4303-a7e6-21da0ba435e2/e10d0795-57cd-4d7f-904e-5f39703cb096'
158180
nuGetFeedType: internal
159181
displayName: Push Nuget package
160182
allowPackageConflicts: $(COURTESY_PUSH)

ci/build-all-steps.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,10 @@ steps:
161161
# Test
162162
- script: node make.js test
163163
displayName: Run tests
164-
condition: and(succeeded(), ne(variables['numTasks'], 0))
164+
condition: and(succeeded(), ne(variables['numTasks'], 0), ne(variables['tasksSkipTests'], 'true'))
165165
- script: node make.js testLegacy --task "$(getTaskPattern.task_pattern)"
166166
displayName: Legacy tests with node 6
167-
condition: and(succeeded(), ne(variables['numTasks'], 0))
167+
condition: and(succeeded(), ne(variables['numTasks'], 0), ne(variables['tasksSkipTests'], 'true'))
168168

169169
# Publish code coverage result
170170
- task: PublishCodeCoverageResults@1

ci/build-single-jobs.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ parameters:
99
displayName: Enable CodeQL for run
1010
type: boolean
1111
default: false
12+
- name: publishToDistributedTaskTest
13+
displayName: Publish to test feed (DistributedTasks-test), for infrastucture testing
14+
type: boolean
15+
default: false
1216

1317
jobs:
1418
# Build Single Task and stage hotfix
@@ -32,7 +36,10 @@ jobs:
3236
- output: nuget
3337
packagesToPush: '$(Build.SourcesDirectory)/nuget-packages/*/*.nupkg'
3438
packageParentPath: '$(Build.SourcesDirectory)'
35-
publishVstsFeed: 'c86767d8-af79-4303-a7e6-21da0ba435e2/e10d0795-57cd-4d7f-904e-5f39703cb096'
39+
${{ if eq(parameters.publishToDistributedTaskTest, true) }}:
40+
publishVstsFeed: 'c86767d8-af79-4303-a7e6-21da0ba435e2/9d34d871-8032-4e10-a34a-c7a01e125865'
41+
${{ else }}:
42+
publishVstsFeed: 'c86767d8-af79-4303-a7e6-21da0ba435e2/e10d0795-57cd-4d7f-904e-5f39703cb096'
3643
nuGetFeedType: internal
3744
displayName: Push Nuget package
3845
allowPackageConflicts: $(COURTESY_PUSH)

ci/filter-tasks.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ var setTaskVariables = function(tasks, tasksForDowngradingCheck) {
222222
var buildReason = process.env['BUILD_REASON'].toLowerCase();
223223
var forceCourtesyPush = process.env['FORCE_COURTESY_PUSH'] && process.env['FORCE_COURTESY_PUSH'].toLowerCase() === 'true';
224224
var taskNameIsSet = process.env['TASKNAMEISSET'] && process.env['TASKNAMEISSET'].toLowerCase() === 'true';
225+
var deployAllTasks = process.env['DEPLOY_ALL_TASKSVAR'] && process.env['DEPLOY_ALL_TASKSVAR'].toLowerCase() === 'true';
225226

226227
if (taskNameIsSet) {
227228
var taskName = process.env['TASKNAME'];
@@ -240,7 +241,9 @@ const ciBuildReasonList = [AzpBuildReason.Individualci, AzpBuildReason.Batchedci
240241

241242
async function filterTasks () {
242243
try {
243-
if (ciBuildReasonList.includes(buildReason) || (forceCourtesyPush && !taskNameIsSet)) {
244+
if (deployAllTasks) {
245+
setTaskVariables(makeOptions.tasks, makeOptions.tasks);
246+
} else if (ciBuildReasonList.includes(buildReason) || (forceCourtesyPush && !taskNameIsSet)) {
244247
// If CI, we will compare any tasks that have updated versions.
245248
const tasks = await getTasksToBuildForCI();
246249
setTaskVariables(tasks, tasks);

0 commit comments

Comments
 (0)