Skip to content

Commit f838fec

Browse files
authored
Refactor execution handler validation and version bump (#512)
* Refactor execution handler validation to improve clarity and ensure all handlers are validated consistently * Rev version
1 parent ca2b629 commit f838fec

File tree

2 files changed

+55
-25
lines changed

2 files changed

+55
-25
lines changed

app/lib/jsonvalidate.ts

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export function validateRunner(taskData: any, allMatchedPaths?: string[]) {
101101
}
102102
}
103103
}
104-
104+
105105
trace.warn("Task %s@%s is dependent on a task runner that is end-of-life and will be removed in the future. Please visit https://aka.ms/node-runner-guidance to learn how to upgrade the task.", taskData.name, taskData.version?.Major || "?")
106106
}
107107
}
@@ -132,32 +132,62 @@ export function validateTask(taskPath: string, taskData: any): string[] {
132132
issues.push(vn + ": instanceNameFormat is required");
133133
}
134134

135-
if (taskData.execution) {
136-
const supportedRunners = ["Node", "Node10", "Node16", "Node20_1", "PowerShell", "PowerShell3", "Process"]
137-
138-
for (var runner in taskData.execution) {
139-
if (supportedRunners.indexOf(runner) > -1) {
140-
var runnerData = taskData.execution[runner];
141-
if (!runnerData.target) {
142-
issues.push(vn + ": execution." + runner + ".target is required");
143-
} else {
144-
const target = runnerData.target.replace(/\$\(\s*currentdirectory\s*\)/i, ".");
135+
issues.push(...validateAllExecutionHandlers(taskPath, taskData, vn));
145136

146-
// target contains a variable
147-
if (target.match(/\$\([^)]+\)/)) {
148-
continue;
149-
}
150-
151-
// check if the target file exists
152-
if (!fs.existsSync(path.join(path.dirname(taskPath), target))) {
153-
issues.push(vn + ": execution target for " + runner + " references file that does not exist: " + target);
154-
}
155-
}
156-
}
157-
}
158-
}
159137
// Fix: Return issues array regardless of whether execution block exists or not
160138
// Previously this return was inside the if(taskData.execution) block, causing
161139
// tasks without execution configuration to return undefined instead of validation issues
162140
return (issues.length > 0) ? [taskPath, ...issues] : [];
163141
}
142+
143+
/**
144+
* Validates all execution/prejob/postjob handlers for a task
145+
* @param taskPath Path to the original json file
146+
* @param taskData The parsed json file
147+
* @param vn Name of the task or path
148+
* @returns Array of issues found for all handlers
149+
*/
150+
function validateAllExecutionHandlers(taskPath: string, taskData: any, vn: string): string[] {
151+
const issues: string[] = [];
152+
const executionProperties = ['execution', 'prejobexecution', 'postjobexecution'];
153+
const supportedRunners = ["Node", "Node10", "Node16", "Node20_1", "PowerShell", "PowerShell3", "Process"];
154+
executionProperties.forEach(executionType => {
155+
if (taskData[executionType]) {
156+
Object.keys(taskData[executionType]).forEach(runner => {
157+
if (supportedRunners.indexOf(runner) === -1) return;
158+
const target = taskData[executionType][runner]?.target;
159+
issues.push(...validateExecutionTarget(taskPath, vn, executionType, runner, target));
160+
});
161+
}
162+
});
163+
return issues;
164+
}
165+
166+
/**
167+
* Validates the target property for a given execution handler
168+
* @param taskPath Path to the original json file
169+
* @param vn Name of the task or path
170+
* @param executionType Type of execution handler (execution, prejobexecution, postjobexecution)
171+
* @param runner Name of the runner
172+
* @param target Execution handler's target
173+
* @returns Array of issues found for this runner
174+
*/
175+
function validateExecutionTarget(taskPath: string, vn: string, executionType: string, runner: string, target: string | undefined): string[] {
176+
const issues: string[] = [];
177+
if (!target) {
178+
issues.push(`${vn}: ${executionType}.${runner}.target is required`);
179+
} else {
180+
const normalizedTarget = target.replace(/\$\(\s*currentdirectory\s*\)/i, ".");
181+
182+
// target contains a variable
183+
if (normalizedTarget.match(/\$\([^)]+\)/)) {
184+
return issues;
185+
}
186+
187+
// check if the target file exists
188+
if (!fs.existsSync(path.join(path.dirname(taskPath), normalizedTarget))) {
189+
issues.push(`${vn}: ${executionType}.${runner}.target references file that does not exist: ${normalizedTarget}`);
190+
}
191+
}
192+
return issues;
193+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tfx-cli",
3-
"version": "0.22.0",
3+
"version": "0.22.1",
44
"description": "CLI for Azure DevOps Services and Team Foundation Server",
55
"repository": {
66
"type": "git",

0 commit comments

Comments
 (0)