Skip to content

Commit 41d6df6

Browse files
committed
Merge branch 'master' into Localization
2 parents 83275b0 + 0d3d055 commit 41d6df6

File tree

7 files changed

+113
-16
lines changed

7 files changed

+113
-16
lines changed

.vsts.ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ parameters:
3333
- name: alpine_arm64
3434
type: boolean
3535
displayName: Alpine (ARM64)
36-
default: false
36+
default: true
3737
- name: macOS_x64
3838
type: boolean
3939
displayName: macOS (x64)

.vsts.release.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,6 @@ extends:
7575
- job: Set_variables
7676
displayName: Set release-specific variables
7777
steps:
78-
# There's no need to clone the repo since no sources are used.
79-
- checkout: none
80-
displayName: Skip repo clone
81-
8278
- pwsh: |
8379
$isBuildStageOnly = [System.Convert]::ToBoolean('${{ parameters.buildStageOnly }}')
8480
$buildReason = '$(Build.Reason)'

src/Agent.Sdk/Knob/AgentKnobs.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,12 @@ public class AgentKnobs
633633
new RuntimeKnobSource("AZP_AGENT_CHECK_FOR_TASK_DEPRECATION"),
634634
new BuiltInDefaultKnobSource("false"));
635635

636+
public static readonly Knob CheckIfTaskNodeRunnerIsDeprecated = new Knob(
637+
nameof(CheckIfTaskNodeRunnerIsDeprecated),
638+
"If true, the agent will check in the 'Initialize job' step each task used in the job if this task has node handlers, and all of them are deprecated.",
639+
new RuntimeKnobSource("AZP_AGENT_CHECK_IF_TASK_NODE_RUNNER_IS_DEPRECATED"),
640+
new BuiltInDefaultKnobSource("false"));
641+
636642
public static readonly Knob MountWorkspace = new Knob(
637643
nameof(MountWorkspace),
638644
"If true, the agent will mount the Pipeline.Workspace directory instead of the Working directory for steps which target a Docker container.",

src/Agent.Worker/TaskManager.cs

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ into taskGrouping
7676
return;
7777
}
7878

79+
HashSet<Guid> exceptionList = GetTaskExceptionSet();
80+
7981
foreach (var task in uniqueTasks.Select(x => x.Reference))
8082
{
8183
if (task.Id == Pipelines.PipelineConstants.CheckoutTask.Id && task.Version == Pipelines.PipelineConstants.CheckoutTask.Version)
@@ -90,6 +92,14 @@ into taskGrouping
9092
{
9193
CheckForTaskDeprecation(executionContext, task);
9294
}
95+
96+
if (AgentKnobs.CheckIfTaskNodeRunnerIsDeprecated.GetValue(executionContext).AsBoolean())
97+
{
98+
if (!exceptionList.Contains(task.Id))
99+
{
100+
CheckIfTaskNodeRunnerIsDeprecated(executionContext, task);
101+
}
102+
}
93103
}
94104
}
95105

@@ -319,9 +329,7 @@ private async Task DownloadAsync(IExecutionContext executionContext, Pipelines.T
319329

320330
private void CheckForTaskDeprecation(IExecutionContext executionContext, Pipelines.TaskStepDefinitionReference task)
321331
{
322-
string taskJsonPath = Path.Combine(GetDirectory(task), "task.json");
323-
string taskJsonText = File.ReadAllText(taskJsonPath);
324-
JObject taskJson = JObject.Parse(taskJsonText);
332+
JObject taskJson = GetTaskJson(task);
325333
var deprecated = taskJson["deprecated"];
326334

327335
if (deprecated != null && deprecated.Value<bool>())
@@ -363,6 +371,80 @@ private void CheckForTaskDeprecation(IExecutionContext executionContext, Pipelin
363371
}
364372
}
365373

374+
private void CheckIfTaskNodeRunnerIsDeprecated(IExecutionContext executionContext, Pipelines.TaskStepDefinitionReference task)
375+
{
376+
string[] deprecatedNodeRunners = { "Node", "Node10" };
377+
string[] approvedNodeRunners = { "Node16", "Node20_1" }; // Node runners which are not considered as deprecated
378+
379+
JObject taskJson = GetTaskJson(task);
380+
var taskRunners = (JObject)taskJson["execution"];
381+
382+
foreach (string runner in approvedNodeRunners)
383+
{
384+
if (taskRunners.ContainsKey(runner))
385+
{
386+
return; // Agent never uses deprecated Node runners if there are approved Node runners
387+
}
388+
}
389+
390+
List<string> taskNodeRunners = new(); // If we are here and task has Node runners, all of them are deprecated
391+
392+
foreach (string runner in deprecatedNodeRunners)
393+
{
394+
if (taskRunners.ContainsKey(runner))
395+
{
396+
switch (runner)
397+
{
398+
case "Node":
399+
taskNodeRunners.Add("6"); // Just "Node" is Node version 6
400+
break;
401+
default:
402+
taskNodeRunners.Add(runner[4..]); // Postfix after "Node"
403+
break;
404+
}
405+
}
406+
}
407+
408+
if (taskNodeRunners.Count > 0) // Tasks may have only PowerShell runners and don't have Node runners at all
409+
{
410+
string friendlyName = taskJson["friendlyName"].Value<string>();
411+
int majorVersion = new Version(task.Version).Major;
412+
executionContext.Warning(StringUtil.Loc("DeprecatedNodeRunner", friendlyName, majorVersion, task.Name, taskNodeRunners.Last()));
413+
}
414+
}
415+
416+
/// <summary>
417+
/// This method provides a set of in-the-box pipeline tasks for which we don't want to display Node deprecation warnings.
418+
/// </summary>
419+
/// <returns> Set of tasks ID </returns>
420+
private HashSet<Guid> GetTaskExceptionSet()
421+
{
422+
string exceptionListFile = HostContext.GetConfigFile(WellKnownConfigFile.TaskExceptionList);
423+
var exceptionList = new List<Guid>();
424+
425+
if (File.Exists(exceptionListFile))
426+
{
427+
try
428+
{
429+
exceptionList = IOUtil.LoadObject<List<Guid>>(exceptionListFile);
430+
}
431+
catch (Exception ex)
432+
{
433+
Trace.Info($"Unable to deserialize exception list {ex}");
434+
exceptionList = new List<Guid>();
435+
}
436+
}
437+
438+
return exceptionList.ToHashSet();
439+
}
440+
441+
private JObject GetTaskJson(Pipelines.TaskStepDefinitionReference task)
442+
{
443+
string taskJsonPath = Path.Combine(GetDirectory(task), "task.json");
444+
string taskJsonText = File.ReadAllText(taskJsonPath);
445+
return JObject.Parse(taskJsonText);
446+
}
447+
366448
private void ExtractZip(String zipFile, String destinationDirectory)
367449
{
368450
ZipFile.ExtractToDirectory(zipFile, destinationDirectory);

src/Misc/externals.sh

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,20 @@ else
3636
fi
3737

3838
function failed() {
39-
local error=${1:-Undefined error}
40-
echo "Failed: $error" >&2
41-
exit 1
39+
local error=${1:-Undefined error}
40+
local command_identifier=$2
41+
echo "Failed: $error" >&2
42+
if [[ $command_identifier == 'download_node_alpine_arm64' ]]; then
43+
echo "Node for Alpine ARM64 not found in blob storage. If the version of Node (for tasks execution) has been updated, it should be built for Alpine ARM64 and uploaded to blob storage. Read documentation about the agent release for more info."
44+
fi
45+
exit 1
4246
}
4347

4448
function checkRC() {
4549
local rc=$?
50+
local command_identifier=$2
4651
if [ $rc -ne 0 ]; then
47-
failed "${1} failed with return code $rc"
52+
failed "${1} failed with return code $rc" $command_identifier
4853
fi
4954
}
5055

@@ -56,6 +61,7 @@ function acquireExternalTool() {
5661
# of the nested TEE-CLC-14.0.4 directory are moved up one directory, and then the empty directory
5762
# TEE-CLC-14.0.4 is removed.
5863
local dont_uncompress=$4
64+
local tool_name=$5
5965

6066
# Extract the portion of the URL after the protocol. E.g. vstsagenttools.blob.core.windows.net/tools/pdbstr/1/pdbstr.zip
6167
local relative_url="${download_source#*://}"
@@ -84,7 +90,7 @@ function acquireExternalTool() {
8490
# -S Show error. With -s, make curl show errors when they occur
8591
# -L Follow redirects (H)
8692
# -o FILE Write to FILE instead of stdout
87-
curl --retry 10 -fkSL -o "$partial_target" "$download_source" 2>"${download_target}_download.log" || checkRC 'curl'
93+
curl --retry 10 -fkSL -o "$partial_target" "$download_source" 2>"${download_target}_download.log" || checkRC 'curl' "download_${tool_name}"
8894

8995
# Move the partial file to the download target.
9096
mv "$partial_target" "$download_target" || checkRC 'mv'
@@ -205,11 +211,11 @@ else
205211
ARCH="linux-arm64-musl"
206212

207213
if [[ "$INCLUDE_NODE10" == "true" ]]; then
208-
acquireExternalTool "${CONTAINER_URL}/nodejs/${ARCH}/node-v${NODE10_VERSION}-${ARCH}.tar.gz" node10/bin fix_nested_dir
214+
acquireExternalTool "${CONTAINER_URL}/nodejs/${ARCH}/node-v${NODE10_VERSION}-${ARCH}.tar.gz" node10/bin fix_nested_dir false node_alpine_arm64
209215
fi
210216

211-
acquireExternalTool "${CONTAINER_URL}/nodejs/${ARCH}/node-v${NODE16_VERSION}-${ARCH}.tar.gz" node16/bin fix_nested_dir
212-
acquireExternalTool "${CONTAINER_URL}/nodejs/${ARCH}/node-v${NODE20_VERSION}-${ARCH}.tar.gz" node20_1/bin fix_nested_dir
217+
acquireExternalTool "${CONTAINER_URL}/nodejs/${ARCH}/node-v${NODE16_VERSION}-${ARCH}.tar.gz" node16/bin fix_nested_dir false node_alpine_arm64
218+
acquireExternalTool "${CONTAINER_URL}/nodejs/${ARCH}/node-v${NODE20_VERSION}-${ARCH}.tar.gz" node20_1/bin fix_nested_dir false node_alpine_arm64
213219
else
214220
case $PACKAGERUNTIME in
215221
"linux-musl-x64") ARCH="linux-x64-musl";;

src/Misc/layoutbin/en-US/strings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@
262262
"DeploymentPoolName": "Deployment Pool name",
263263
"DeploymentPoolNotFound": "Deployment pool not found: '{0}'",
264264
"DeprecatedNode6": "This task uses Node 6 execution handler, which will be removed March 31st 2022. If you are the developer of the task - please consider the migration guideline to Node 10 handler - https://aka.ms/migrateTaskNode10 (check this page also if you would like to disable Node 6 deprecation warnings). If you are the user - feel free to reach out to the owners of this task to proceed on migration.",
265+
"DeprecatedNodeRunner": "Task '{0}' version {1} ({2}@{1}) is dependent on a Node version ({3}) that is end-of-life. Contact the extension owner for an updated version of the task. Task maintainers should review Node upgrade guidance: https://aka.ms/node-runner-guidance",
265266
"DeprecatedRunner": "Task '{0}' is dependent on a task runner that is end-of-life and will be removed in the future. Authors should review Node upgrade guidance: https://aka.ms/node-runner-guidance.",
266267
"DeprecationMessage": "Task '{0}' version {1} ({2}@{1}) is deprecated.",
267268
"DeprecationMessageHelpUrl": "Please see {0} for more information about this task.",

src/Test/L0/TestHostContext.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,12 @@ public string GetConfigFile(WellKnownConfigFile configFile)
359359
".setup_info");
360360
break;
361361

362+
case WellKnownConfigFile.TaskExceptionList:
363+
path = Path.Combine(
364+
GetDirectory(WellKnownDirectory.Bin),
365+
"tasks-exception-list.json");
366+
break;
367+
362368
default:
363369
throw new NotSupportedException($"Unexpected well known config file: '{configFile}'");
364370
}

0 commit comments

Comments
 (0)