@@ -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 * c u r r e n t d i r e c t o r y \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 * c u r r e n t d i r e c t o r y \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+ }
0 commit comments