diff --git a/Tasks/AzureTestPlanV0/Invokers/gradleinvoker.ts b/Tasks/AzureTestPlanV0/Invokers/gradleinvoker.ts index 0f559f2b04cf..f59fb69ac4b7 100644 --- a/Tasks/AzureTestPlanV0/Invokers/gradleinvoker.ts +++ b/Tasks/AzureTestPlanV0/Invokers/gradleinvoker.ts @@ -1,10 +1,9 @@ -import { spawn } from '../testexecutor' import tl = require('azure-pipelines-task-lib/task'); import utils = require('../utils'); import constants = require('../constants'); import { execGradleBuild } from '../testLibExecutor'; -export async function executegradletests(testsToBeExecuted: string[]) { +export async function executeGradleTests(testsToBeExecuted: string[]):Promise { //public doc link: https://docs.gradle.org/current/userguide/command_line_interface.html //gradle command like "gradlew clean test --tests --tests " @@ -26,5 +25,5 @@ export async function executegradletests(testsToBeExecuted: string[]) { var status = await execGradleBuild(args); - return { exitCode: status ?? 1 } + return status ?? 1; } \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/Invokers/maveninvoker.ts b/Tasks/AzureTestPlanV0/Invokers/maveninvoker.ts index 1608a00a7fcb..5dfb0fa92233 100644 --- a/Tasks/AzureTestPlanV0/Invokers/maveninvoker.ts +++ b/Tasks/AzureTestPlanV0/Invokers/maveninvoker.ts @@ -4,7 +4,7 @@ import utils = require('../utils'); import constants = require('../constants'); import { execMavenBuild } from '../testLibExecutor'; -export async function executemaventests(testsToBeExecuted: string[]) { +export async function executeMavenTests(testsToBeExecuted: string[]):Promise { //public doc link: https://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html //maven command like "mvn test -Dtest=," @@ -31,5 +31,7 @@ export async function executemaventests(testsToBeExecuted: string[]) { tl.debug("Executing java maven tests with executable : " + executable); tl.debug("Executing java maven tests with args :" + args); - await execMavenBuild(args); + let status = await execMavenBuild(args); + + return status ?? 1; } \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/Invokers/pythoninvoker.ts b/Tasks/AzureTestPlanV0/Invokers/pythoninvoker.ts index 77c6de3c5828..36ec39662b74 100644 --- a/Tasks/AzureTestPlanV0/Invokers/pythoninvoker.ts +++ b/Tasks/AzureTestPlanV0/Invokers/pythoninvoker.ts @@ -2,14 +2,14 @@ import { spawn, SpawnResult } from '../testexecutor'; import tl = require('azure-pipelines-task-lib/task'); import constants = require('../constants'); -export async function executepythontests(testsToBeExecuted: string[]) { +export async function executePythonTests(testsToBeExecuted: string[]):Promise { // Perform test discovery const discoveryArgs: string[] = ['--collect-only']; const discoveryResult = await runPytestCommand(discoveryArgs); if (discoveryResult.status !== 0) { tl.error("Error occurred during test discovery: " + (discoveryResult.error ? discoveryResult.error.message : "Unknown error")); - return { exitCode: 1 }; + return 1; } // Extract discovered tests from stdout @@ -20,7 +20,7 @@ export async function executepythontests(testsToBeExecuted: string[]) { if (testsToRun.length === 0) { tl.warning("No common tests found between specified tests and discovered tests."); - return { exitCode: 0 }; + return 0; } console.log(`Found ${testsToRun.length} tests to run`); @@ -34,10 +34,10 @@ export async function executepythontests(testsToBeExecuted: string[]) { if (error) { tl.error("Error executing pytest command: " + error.message); - return { exitCode: 1 }; + return 1; } - return { exitCode: status ?? 1 }; + return status ?? 1; } async function runPytestCommand(args: string[]): Promise { diff --git a/Tasks/AzureTestPlanV0/automatedTestInvoker.ts b/Tasks/AzureTestPlanV0/automatedTestInvoker.ts index 9b112d86ef9a..e2c7b34e1933 100644 --- a/Tasks/AzureTestPlanV0/automatedTestInvoker.ts +++ b/Tasks/AzureTestPlanV0/automatedTestInvoker.ts @@ -1,13 +1,16 @@ import * as tl from 'azure-pipelines-task-lib/task' -import { executepythontests } from './Invokers/pythoninvoker' -import { executemaventests } from './Invokers/maveninvoker' -import { executegradletests } from './Invokers/gradleinvoker' +import { executePythonTests } from './Invokers/pythoninvoker' +import { executeMavenTests } from './Invokers/maveninvoker' +import { executeGradleTests } from './Invokers/gradleinvoker' -export async function testInvoker(testsToBeExecuted: string[]) { +export async function testInvoker(testsToBeExecuted: string[]): Promise { const testLanguageStrings = tl.getDelimitedInput('testLanguageInput', ',', true); + let exitStatusCode = 0; + for (const testLanguage of testLanguageStrings) { + let exitCode = 0; if (testLanguage === null || testLanguage === undefined) { console.log("Please select the test framework language from the task dropdown list to execute automated tests"); @@ -16,21 +19,27 @@ export async function testInvoker(testsToBeExecuted: string[]) { switch (testLanguage) { case 'Java-Maven': - await executemaventests(testsToBeExecuted); + exitCode = await executeMavenTests(testsToBeExecuted); + tl.debug(`Execution Status Code for Maven: ${exitCode}`); break; case 'Java-Gradle': - await executegradletests(testsToBeExecuted); + exitCode = await executeGradleTests(testsToBeExecuted); + tl.debug(`Execution Status Code for Gradle: ${exitCode}`); break; case 'Python': - await executepythontests(testsToBeExecuted); + exitCode = await executePythonTests(testsToBeExecuted); + tl.debug(`Execution Status Code for Python: ${exitCode}`); break; default: console.log('Invalid test Language Input selected.'); } - + + exitStatusCode = exitStatusCode || exitCode; } - + + tl.debug(`Execution Status Code for Automated Execution Flow: ${exitStatusCode}`); + return exitStatusCode; } \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/automatedTests.ts b/Tasks/AzureTestPlanV0/automatedTests.ts index 16cff03b9404..8a2ec9f727f4 100644 --- a/Tasks/AzureTestPlanV0/automatedTests.ts +++ b/Tasks/AzureTestPlanV0/automatedTests.ts @@ -1,28 +1,39 @@ import tl = require('azure-pipelines-task-lib/task'); -import { testInvoker } from './automatedTestInvoker' -import { TestPlanData } from './testPlanData' -import { publishAutomatedTestResult } from './publishAutomatedTests' +import { testInvoker } from './automatedTestInvoker'; +import { TestPlanData } from './testPlanData'; +import { publishAutomatedTestResult } from './publishAutomatedTests'; +export async function automatedTestsFlow(testPlanInfo: TestPlanData, testSelectorInput: string): Promise { + let listOfTestsToBeExecuted: string[] = testPlanInfo.listOfFQNOfTestCases; + let testInvokerStatusCode = 0; -export async function automatedTestsFlow(testPlanInfo: TestPlanData, testSelectorInput: string) { + if (listOfTestsToBeExecuted !== null && listOfTestsToBeExecuted !== undefined && listOfTestsToBeExecuted.length > 0) { + tl.debug('Invoking test execution for tests: ' + listOfTestsToBeExecuted); - let listOfTestsToBeExecuted: string[] = testPlanInfo.listOfFQNOfTestCases; - - console.log(tl.loc('automatedTestTriggered')); - - if (listOfTestsToBeExecuted !== null && listOfTestsToBeExecuted !== undefined && listOfTestsToBeExecuted.length > 0) { - tl.debug("Invoking test execution for tests: " + listOfTestsToBeExecuted); - await testInvoker(listOfTestsToBeExecuted); - publishAutomatedTestResult(JSON.stringify(testPlanInfo.listOfAutomatedTestPoints)); + try { + testInvokerStatusCode = await testInvoker(listOfTestsToBeExecuted); + } catch (err) { + tl.debug(`Unable to invoke automated test execution. Err:( ${err} )`); + testInvokerStatusCode = 1; } - else { - console.log("No automated tests found for given test plan inputs "); - if (testSelectorInput === 'automatedTests') { - tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnNoAutomatedTestsFound')); - } - else { - tl.setResult(tl.TaskResult.Succeeded, "Successfully triggered manual test execution"); - } + + try { + await publishAutomatedTestResult(JSON.stringify(testPlanInfo.listOfAutomatedTestPoints)); + } catch (err) { + tl.error(`Error while publishing automated Test Results with err : ( ${err} )`); + return 1; } + tl.debug(`Execution Status Code for test Invoker: ${testInvokerStatusCode}`); + return testInvokerStatusCode; + } else { + console.log('No automated tests found for given test plan inputs '); + if (testSelectorInput === 'automatedTests') { + tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnNoAutomatedTestsFound')); + return 1; + } else { + tl.setResult(tl.TaskResult.Succeeded, 'Successfully triggered manual test execution'); + return 0; + } + } } diff --git a/Tasks/AzureTestPlanV0/manualTests.ts b/Tasks/AzureTestPlanV0/manualTests.ts index 4ae0e2dde00e..20804591656c 100644 --- a/Tasks/AzureTestPlanV0/manualTests.ts +++ b/Tasks/AzureTestPlanV0/manualTests.ts @@ -1,13 +1,20 @@ import tl = require('azure-pipelines-task-lib/task'); import { TestPlanData, createManualTestRun, ManualTestRunData } from './testPlanData'; -export async function manualTestsFlow(testPlanInfo: TestPlanData) { +export async function manualTestsFlow(testPlanInfo: TestPlanData):Promise { let manualTestRun: ManualTestRunData = { testRunId: 0, runUrl: "" }; - manualTestRun = await createManualTestRun(testPlanInfo); - + try{ + manualTestRun = await createManualTestRun(testPlanInfo); + } + catch (err){ + tl.debug(`Unable to create Manual Test Run. Err:( ${err} )`); + return 1; + } + console.log('Test run id created: ', manualTestRun.testRunId); console.log('Test run url: ', manualTestRun.runUrl); + return 0; } \ No newline at end of file diff --git a/Tasks/AzureTestPlanV0/runTestPlan.ts b/Tasks/AzureTestPlanV0/runTestPlan.ts index 539300a9115a..dacaf31eb491 100644 --- a/Tasks/AzureTestPlanV0/runTestPlan.ts +++ b/Tasks/AzureTestPlanV0/runTestPlan.ts @@ -10,12 +10,21 @@ export async function run() { const testPlanInfo = await getTestPlanData(); + let manualTestFlowReturnCode = 0; + let automatedTestFlowReturnCode = 0; + // trigger manual, automated or both tests based on user's input if (testSelectorInput.includes('manualTests')) { - await manualTestsFlow(testPlanInfo); + manualTestFlowReturnCode = await manualTestsFlow(testPlanInfo); + tl.debug(`Execution Status Code for Manual Test Flow is ${manualTestFlowReturnCode}`); } if (testSelectorInput.includes('automatedTests')) { - await automatedTestsFlow(testPlanInfo, testSelectorInput); + automatedTestFlowReturnCode = await automatedTestsFlow(testPlanInfo, testSelectorInput); + tl.debug(`Execution Status Code for Automated Test Flow is ${automatedTestFlowReturnCode}`); + } + + if( manualTestFlowReturnCode || automatedTestFlowReturnCode){ + tl.setResult(tl.TaskResult.Failed, "Faced error in execution."); } } diff --git a/Tasks/AzureTestPlanV0/task.json b/Tasks/AzureTestPlanV0/task.json index 7168089ac897..2ffc9698e5ae 100644 --- a/Tasks/AzureTestPlanV0/task.json +++ b/Tasks/AzureTestPlanV0/task.json @@ -14,7 +14,7 @@ "version": { "Major": 0, "Minor": 238, - "Patch": 6 + "Patch": 8 }, "preview": true, "demands": [], diff --git a/Tasks/AzureTestPlanV0/task.loc.json b/Tasks/AzureTestPlanV0/task.loc.json index e8a1eecd468e..0fdd052349da 100644 --- a/Tasks/AzureTestPlanV0/task.loc.json +++ b/Tasks/AzureTestPlanV0/task.loc.json @@ -14,7 +14,7 @@ "version": { "Major": 0, "Minor": 238, - "Patch": 6 + "Patch": 8 }, "preview": true, "demands": [], diff --git a/Tasks/AzureTestPlanV0/testLibExecutor.ts b/Tasks/AzureTestPlanV0/testLibExecutor.ts index 2ba3d22ddba9..ce53da0f3689 100644 --- a/Tasks/AzureTestPlanV0/testLibExecutor.ts +++ b/Tasks/AzureTestPlanV0/testLibExecutor.ts @@ -54,35 +54,32 @@ function getExecOptions(): tr.IExecOptions { * @param args Arguments to execute via mvn * @returns execution Status Code */ -export async function execMavenBuild(args: string[]) { - +export async function execMavenBuild(args: string[]): Promise { var mvnExec = getMavenExec(); // Setup tool runner that executes Maven only to retrieve its version var mvnGetVersion = tl.tool(mvnExec); mvnGetVersion.arg('-version'); - // 1. Check that Maven exists by executing it to retrieve its version. - await mvnGetVersion.exec() - .fail(function (err) { - console.error("Maven is not installed on the agent"); - tl.setResult(tl.TaskResult.Failed, "Maven is not installed."); // tl.exit sets the step result but does not stop execution - process.exit(1); - }) - .then(async function (code) { - // Setup Maven Executable to run list of test runs provided as input - var mvnRun = tl.tool(mvnExec); - mvnRun.arg('-ntp'); - mvnRun.arg(args); - - // 3. Run Maven. Compilation or test errors will cause this to fail. - return mvnRun.exec(getExecOptions()); - }) - .fail(function (err) { - console.error(err.message); - tl.setResult(tl.TaskResult.Failed, "Build failed."); // tl.exit sets the step result but does not stop execution - process.exit(1); - }); + try { + // 1. Check that Maven exists by executing it to retrieve its version. + await mvnGetVersion.exec(); + + // Setup Maven Executable to run list of test runs provided as input + var mvnRun = tl.tool(mvnExec); + mvnRun.arg('-ntp'); + mvnRun.arg(args); + + // 3. Run Maven. Compilation or test errors will cause this to fail. + await mvnRun.exec(getExecOptions()); + + // Maven build succeeded + return 0; // Return 0 indicating success + } catch (err) { + console.error(err.message); + tl.setResult(tl.TaskResult.Failed, "Build failed."); + return 1; // Return 1 indicating failure + } } function getGradlewExec() { @@ -105,14 +102,16 @@ function getGradlewExec() { if (gradlewPath.length == 0) { tl.setResult(tl.TaskResult.Failed, "Missing gradlew file"); + return ""; } + var gradlewExec: string = gradlewPath[0]; + if (gradlewPath.length > 1) { tl.warning(tl.loc('MultipleMatchingGradlewFound')); + tl.debug(gradlewExec); } - var gradlewExec: string = gradlewPath[0]; - if (isWindows) { tl.debug('Append .bat extension name to gradlew script.'); gradlewExec += '.bat'; @@ -136,22 +135,27 @@ function getGradlewExec() { * @param args Arguments to execute via mvn * @returns execution Status Code */ -export async function execGradleBuild(args: string[]) { +export async function execGradleBuild(args: string[]): Promise { var gradleExec = getGradlewExec(); - // Setup tool runner that executes Maven only to retrieve its version + if (!gradleExec || gradleExec == "") { + return 1; // Return 1 indicating failure + } + + // Setup tool runner that executes Gradle var gradleRunner = tl.tool(gradleExec); // Add args prepared by invoker for executing individual test cases gradleRunner.arg('clean'); gradleRunner.arg(args); - var statusCode = await gradleRunner.exec(getExecOptions()) - .fail(function (err) { - console.error(err.message); - tl.setResult(tl.TaskResult.Failed, "Build failed."); // tl.exit sets the step result but does not stop execution - process.exit(1); - }); - - return statusCode; + try { + await gradleRunner.exec(getExecOptions()); + // Gradle build succeeded + return 0; // Return 0 indicating success + } catch (err) { + console.error(err.message); + tl.setResult(tl.TaskResult.Failed, "Build failed."); // Set the step result to Failed + return 1; // Return 1 indicating failure + } } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0.versionmap.txt b/_generated/AzureTestPlanV0.versionmap.txt index 577a32405e24..d7cbc5217a0d 100644 --- a/_generated/AzureTestPlanV0.versionmap.txt +++ b/_generated/AzureTestPlanV0.versionmap.txt @@ -1,2 +1,2 @@ -Default|0.238.6 -Node20-225|0.238.7 +Default|0.238.8 +Node20-225|0.238.9 diff --git a/_generated/AzureTestPlanV0/Invokers/gradleinvoker.ts b/_generated/AzureTestPlanV0/Invokers/gradleinvoker.ts index 0f559f2b04cf..f59fb69ac4b7 100644 --- a/_generated/AzureTestPlanV0/Invokers/gradleinvoker.ts +++ b/_generated/AzureTestPlanV0/Invokers/gradleinvoker.ts @@ -1,10 +1,9 @@ -import { spawn } from '../testexecutor' import tl = require('azure-pipelines-task-lib/task'); import utils = require('../utils'); import constants = require('../constants'); import { execGradleBuild } from '../testLibExecutor'; -export async function executegradletests(testsToBeExecuted: string[]) { +export async function executeGradleTests(testsToBeExecuted: string[]):Promise { //public doc link: https://docs.gradle.org/current/userguide/command_line_interface.html //gradle command like "gradlew clean test --tests --tests " @@ -26,5 +25,5 @@ export async function executegradletests(testsToBeExecuted: string[]) { var status = await execGradleBuild(args); - return { exitCode: status ?? 1 } + return status ?? 1; } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0/Invokers/maveninvoker.ts b/_generated/AzureTestPlanV0/Invokers/maveninvoker.ts index 1608a00a7fcb..5dfb0fa92233 100644 --- a/_generated/AzureTestPlanV0/Invokers/maveninvoker.ts +++ b/_generated/AzureTestPlanV0/Invokers/maveninvoker.ts @@ -4,7 +4,7 @@ import utils = require('../utils'); import constants = require('../constants'); import { execMavenBuild } from '../testLibExecutor'; -export async function executemaventests(testsToBeExecuted: string[]) { +export async function executeMavenTests(testsToBeExecuted: string[]):Promise { //public doc link: https://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html //maven command like "mvn test -Dtest=," @@ -31,5 +31,7 @@ export async function executemaventests(testsToBeExecuted: string[]) { tl.debug("Executing java maven tests with executable : " + executable); tl.debug("Executing java maven tests with args :" + args); - await execMavenBuild(args); + let status = await execMavenBuild(args); + + return status ?? 1; } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0/Invokers/pythoninvoker.ts b/_generated/AzureTestPlanV0/Invokers/pythoninvoker.ts index 77c6de3c5828..36ec39662b74 100644 --- a/_generated/AzureTestPlanV0/Invokers/pythoninvoker.ts +++ b/_generated/AzureTestPlanV0/Invokers/pythoninvoker.ts @@ -2,14 +2,14 @@ import { spawn, SpawnResult } from '../testexecutor'; import tl = require('azure-pipelines-task-lib/task'); import constants = require('../constants'); -export async function executepythontests(testsToBeExecuted: string[]) { +export async function executePythonTests(testsToBeExecuted: string[]):Promise { // Perform test discovery const discoveryArgs: string[] = ['--collect-only']; const discoveryResult = await runPytestCommand(discoveryArgs); if (discoveryResult.status !== 0) { tl.error("Error occurred during test discovery: " + (discoveryResult.error ? discoveryResult.error.message : "Unknown error")); - return { exitCode: 1 }; + return 1; } // Extract discovered tests from stdout @@ -20,7 +20,7 @@ export async function executepythontests(testsToBeExecuted: string[]) { if (testsToRun.length === 0) { tl.warning("No common tests found between specified tests and discovered tests."); - return { exitCode: 0 }; + return 0; } console.log(`Found ${testsToRun.length} tests to run`); @@ -34,10 +34,10 @@ export async function executepythontests(testsToBeExecuted: string[]) { if (error) { tl.error("Error executing pytest command: " + error.message); - return { exitCode: 1 }; + return 1; } - return { exitCode: status ?? 1 }; + return status ?? 1; } async function runPytestCommand(args: string[]): Promise { diff --git a/_generated/AzureTestPlanV0/automatedTestInvoker.ts b/_generated/AzureTestPlanV0/automatedTestInvoker.ts index 9b112d86ef9a..e2c7b34e1933 100644 --- a/_generated/AzureTestPlanV0/automatedTestInvoker.ts +++ b/_generated/AzureTestPlanV0/automatedTestInvoker.ts @@ -1,13 +1,16 @@ import * as tl from 'azure-pipelines-task-lib/task' -import { executepythontests } from './Invokers/pythoninvoker' -import { executemaventests } from './Invokers/maveninvoker' -import { executegradletests } from './Invokers/gradleinvoker' +import { executePythonTests } from './Invokers/pythoninvoker' +import { executeMavenTests } from './Invokers/maveninvoker' +import { executeGradleTests } from './Invokers/gradleinvoker' -export async function testInvoker(testsToBeExecuted: string[]) { +export async function testInvoker(testsToBeExecuted: string[]): Promise { const testLanguageStrings = tl.getDelimitedInput('testLanguageInput', ',', true); + let exitStatusCode = 0; + for (const testLanguage of testLanguageStrings) { + let exitCode = 0; if (testLanguage === null || testLanguage === undefined) { console.log("Please select the test framework language from the task dropdown list to execute automated tests"); @@ -16,21 +19,27 @@ export async function testInvoker(testsToBeExecuted: string[]) { switch (testLanguage) { case 'Java-Maven': - await executemaventests(testsToBeExecuted); + exitCode = await executeMavenTests(testsToBeExecuted); + tl.debug(`Execution Status Code for Maven: ${exitCode}`); break; case 'Java-Gradle': - await executegradletests(testsToBeExecuted); + exitCode = await executeGradleTests(testsToBeExecuted); + tl.debug(`Execution Status Code for Gradle: ${exitCode}`); break; case 'Python': - await executepythontests(testsToBeExecuted); + exitCode = await executePythonTests(testsToBeExecuted); + tl.debug(`Execution Status Code for Python: ${exitCode}`); break; default: console.log('Invalid test Language Input selected.'); } - + + exitStatusCode = exitStatusCode || exitCode; } - + + tl.debug(`Execution Status Code for Automated Execution Flow: ${exitStatusCode}`); + return exitStatusCode; } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0/automatedTests.ts b/_generated/AzureTestPlanV0/automatedTests.ts index 16cff03b9404..8a2ec9f727f4 100644 --- a/_generated/AzureTestPlanV0/automatedTests.ts +++ b/_generated/AzureTestPlanV0/automatedTests.ts @@ -1,28 +1,39 @@ import tl = require('azure-pipelines-task-lib/task'); -import { testInvoker } from './automatedTestInvoker' -import { TestPlanData } from './testPlanData' -import { publishAutomatedTestResult } from './publishAutomatedTests' +import { testInvoker } from './automatedTestInvoker'; +import { TestPlanData } from './testPlanData'; +import { publishAutomatedTestResult } from './publishAutomatedTests'; +export async function automatedTestsFlow(testPlanInfo: TestPlanData, testSelectorInput: string): Promise { + let listOfTestsToBeExecuted: string[] = testPlanInfo.listOfFQNOfTestCases; + let testInvokerStatusCode = 0; -export async function automatedTestsFlow(testPlanInfo: TestPlanData, testSelectorInput: string) { + if (listOfTestsToBeExecuted !== null && listOfTestsToBeExecuted !== undefined && listOfTestsToBeExecuted.length > 0) { + tl.debug('Invoking test execution for tests: ' + listOfTestsToBeExecuted); - let listOfTestsToBeExecuted: string[] = testPlanInfo.listOfFQNOfTestCases; - - console.log(tl.loc('automatedTestTriggered')); - - if (listOfTestsToBeExecuted !== null && listOfTestsToBeExecuted !== undefined && listOfTestsToBeExecuted.length > 0) { - tl.debug("Invoking test execution for tests: " + listOfTestsToBeExecuted); - await testInvoker(listOfTestsToBeExecuted); - publishAutomatedTestResult(JSON.stringify(testPlanInfo.listOfAutomatedTestPoints)); + try { + testInvokerStatusCode = await testInvoker(listOfTestsToBeExecuted); + } catch (err) { + tl.debug(`Unable to invoke automated test execution. Err:( ${err} )`); + testInvokerStatusCode = 1; } - else { - console.log("No automated tests found for given test plan inputs "); - if (testSelectorInput === 'automatedTests') { - tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnNoAutomatedTestsFound')); - } - else { - tl.setResult(tl.TaskResult.Succeeded, "Successfully triggered manual test execution"); - } + + try { + await publishAutomatedTestResult(JSON.stringify(testPlanInfo.listOfAutomatedTestPoints)); + } catch (err) { + tl.error(`Error while publishing automated Test Results with err : ( ${err} )`); + return 1; } + tl.debug(`Execution Status Code for test Invoker: ${testInvokerStatusCode}`); + return testInvokerStatusCode; + } else { + console.log('No automated tests found for given test plan inputs '); + if (testSelectorInput === 'automatedTests') { + tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnNoAutomatedTestsFound')); + return 1; + } else { + tl.setResult(tl.TaskResult.Succeeded, 'Successfully triggered manual test execution'); + return 0; + } + } } diff --git a/_generated/AzureTestPlanV0/manualTests.ts b/_generated/AzureTestPlanV0/manualTests.ts index 4ae0e2dde00e..20804591656c 100644 --- a/_generated/AzureTestPlanV0/manualTests.ts +++ b/_generated/AzureTestPlanV0/manualTests.ts @@ -1,13 +1,20 @@ import tl = require('azure-pipelines-task-lib/task'); import { TestPlanData, createManualTestRun, ManualTestRunData } from './testPlanData'; -export async function manualTestsFlow(testPlanInfo: TestPlanData) { +export async function manualTestsFlow(testPlanInfo: TestPlanData):Promise { let manualTestRun: ManualTestRunData = { testRunId: 0, runUrl: "" }; - manualTestRun = await createManualTestRun(testPlanInfo); - + try{ + manualTestRun = await createManualTestRun(testPlanInfo); + } + catch (err){ + tl.debug(`Unable to create Manual Test Run. Err:( ${err} )`); + return 1; + } + console.log('Test run id created: ', manualTestRun.testRunId); console.log('Test run url: ', manualTestRun.runUrl); + return 0; } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0/runTestPlan.ts b/_generated/AzureTestPlanV0/runTestPlan.ts index 539300a9115a..dacaf31eb491 100644 --- a/_generated/AzureTestPlanV0/runTestPlan.ts +++ b/_generated/AzureTestPlanV0/runTestPlan.ts @@ -10,12 +10,21 @@ export async function run() { const testPlanInfo = await getTestPlanData(); + let manualTestFlowReturnCode = 0; + let automatedTestFlowReturnCode = 0; + // trigger manual, automated or both tests based on user's input if (testSelectorInput.includes('manualTests')) { - await manualTestsFlow(testPlanInfo); + manualTestFlowReturnCode = await manualTestsFlow(testPlanInfo); + tl.debug(`Execution Status Code for Manual Test Flow is ${manualTestFlowReturnCode}`); } if (testSelectorInput.includes('automatedTests')) { - await automatedTestsFlow(testPlanInfo, testSelectorInput); + automatedTestFlowReturnCode = await automatedTestsFlow(testPlanInfo, testSelectorInput); + tl.debug(`Execution Status Code for Automated Test Flow is ${automatedTestFlowReturnCode}`); + } + + if( manualTestFlowReturnCode || automatedTestFlowReturnCode){ + tl.setResult(tl.TaskResult.Failed, "Faced error in execution."); } } diff --git a/_generated/AzureTestPlanV0/task.json b/_generated/AzureTestPlanV0/task.json index 43f1dc481307..39f7879138e0 100644 --- a/_generated/AzureTestPlanV0/task.json +++ b/_generated/AzureTestPlanV0/task.json @@ -14,7 +14,7 @@ "version": { "Major": 0, "Minor": 238, - "Patch": 6 + "Patch": 8 }, "preview": true, "demands": [], @@ -179,7 +179,7 @@ "MultipleMatchingGradlewFound": "Multiple gradlew files found. Selecting the first matched instance" }, "_buildConfigMapping": { - "Default": "0.238.6", - "Node20-225": "0.238.7" + "Default": "0.238.8", + "Node20-225": "0.238.9" } } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0/task.loc.json b/_generated/AzureTestPlanV0/task.loc.json index 1e76a6a7d2d0..ee821b5646ec 100644 --- a/_generated/AzureTestPlanV0/task.loc.json +++ b/_generated/AzureTestPlanV0/task.loc.json @@ -14,7 +14,7 @@ "version": { "Major": 0, "Minor": 238, - "Patch": 6 + "Patch": 8 }, "preview": true, "demands": [], @@ -179,7 +179,7 @@ "MultipleMatchingGradlewFound": "ms-resource:loc.messages.MultipleMatchingGradlewFound" }, "_buildConfigMapping": { - "Default": "0.238.6", - "Node20-225": "0.238.7" + "Default": "0.238.8", + "Node20-225": "0.238.9" } } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0/testLibExecutor.ts b/_generated/AzureTestPlanV0/testLibExecutor.ts index 2ba3d22ddba9..ce53da0f3689 100644 --- a/_generated/AzureTestPlanV0/testLibExecutor.ts +++ b/_generated/AzureTestPlanV0/testLibExecutor.ts @@ -54,35 +54,32 @@ function getExecOptions(): tr.IExecOptions { * @param args Arguments to execute via mvn * @returns execution Status Code */ -export async function execMavenBuild(args: string[]) { - +export async function execMavenBuild(args: string[]): Promise { var mvnExec = getMavenExec(); // Setup tool runner that executes Maven only to retrieve its version var mvnGetVersion = tl.tool(mvnExec); mvnGetVersion.arg('-version'); - // 1. Check that Maven exists by executing it to retrieve its version. - await mvnGetVersion.exec() - .fail(function (err) { - console.error("Maven is not installed on the agent"); - tl.setResult(tl.TaskResult.Failed, "Maven is not installed."); // tl.exit sets the step result but does not stop execution - process.exit(1); - }) - .then(async function (code) { - // Setup Maven Executable to run list of test runs provided as input - var mvnRun = tl.tool(mvnExec); - mvnRun.arg('-ntp'); - mvnRun.arg(args); - - // 3. Run Maven. Compilation or test errors will cause this to fail. - return mvnRun.exec(getExecOptions()); - }) - .fail(function (err) { - console.error(err.message); - tl.setResult(tl.TaskResult.Failed, "Build failed."); // tl.exit sets the step result but does not stop execution - process.exit(1); - }); + try { + // 1. Check that Maven exists by executing it to retrieve its version. + await mvnGetVersion.exec(); + + // Setup Maven Executable to run list of test runs provided as input + var mvnRun = tl.tool(mvnExec); + mvnRun.arg('-ntp'); + mvnRun.arg(args); + + // 3. Run Maven. Compilation or test errors will cause this to fail. + await mvnRun.exec(getExecOptions()); + + // Maven build succeeded + return 0; // Return 0 indicating success + } catch (err) { + console.error(err.message); + tl.setResult(tl.TaskResult.Failed, "Build failed."); + return 1; // Return 1 indicating failure + } } function getGradlewExec() { @@ -105,14 +102,16 @@ function getGradlewExec() { if (gradlewPath.length == 0) { tl.setResult(tl.TaskResult.Failed, "Missing gradlew file"); + return ""; } + var gradlewExec: string = gradlewPath[0]; + if (gradlewPath.length > 1) { tl.warning(tl.loc('MultipleMatchingGradlewFound')); + tl.debug(gradlewExec); } - var gradlewExec: string = gradlewPath[0]; - if (isWindows) { tl.debug('Append .bat extension name to gradlew script.'); gradlewExec += '.bat'; @@ -136,22 +135,27 @@ function getGradlewExec() { * @param args Arguments to execute via mvn * @returns execution Status Code */ -export async function execGradleBuild(args: string[]) { +export async function execGradleBuild(args: string[]): Promise { var gradleExec = getGradlewExec(); - // Setup tool runner that executes Maven only to retrieve its version + if (!gradleExec || gradleExec == "") { + return 1; // Return 1 indicating failure + } + + // Setup tool runner that executes Gradle var gradleRunner = tl.tool(gradleExec); // Add args prepared by invoker for executing individual test cases gradleRunner.arg('clean'); gradleRunner.arg(args); - var statusCode = await gradleRunner.exec(getExecOptions()) - .fail(function (err) { - console.error(err.message); - tl.setResult(tl.TaskResult.Failed, "Build failed."); // tl.exit sets the step result but does not stop execution - process.exit(1); - }); - - return statusCode; + try { + await gradleRunner.exec(getExecOptions()); + // Gradle build succeeded + return 0; // Return 0 indicating success + } catch (err) { + console.error(err.message); + tl.setResult(tl.TaskResult.Failed, "Build failed."); // Set the step result to Failed + return 1; // Return 1 indicating failure + } } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/Invokers/gradleinvoker.ts b/_generated/AzureTestPlanV0_Node20/Invokers/gradleinvoker.ts index 0f559f2b04cf..f59fb69ac4b7 100644 --- a/_generated/AzureTestPlanV0_Node20/Invokers/gradleinvoker.ts +++ b/_generated/AzureTestPlanV0_Node20/Invokers/gradleinvoker.ts @@ -1,10 +1,9 @@ -import { spawn } from '../testexecutor' import tl = require('azure-pipelines-task-lib/task'); import utils = require('../utils'); import constants = require('../constants'); import { execGradleBuild } from '../testLibExecutor'; -export async function executegradletests(testsToBeExecuted: string[]) { +export async function executeGradleTests(testsToBeExecuted: string[]):Promise { //public doc link: https://docs.gradle.org/current/userguide/command_line_interface.html //gradle command like "gradlew clean test --tests --tests " @@ -26,5 +25,5 @@ export async function executegradletests(testsToBeExecuted: string[]) { var status = await execGradleBuild(args); - return { exitCode: status ?? 1 } + return status ?? 1; } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/Invokers/maveninvoker.ts b/_generated/AzureTestPlanV0_Node20/Invokers/maveninvoker.ts index 1608a00a7fcb..5dfb0fa92233 100644 --- a/_generated/AzureTestPlanV0_Node20/Invokers/maveninvoker.ts +++ b/_generated/AzureTestPlanV0_Node20/Invokers/maveninvoker.ts @@ -4,7 +4,7 @@ import utils = require('../utils'); import constants = require('../constants'); import { execMavenBuild } from '../testLibExecutor'; -export async function executemaventests(testsToBeExecuted: string[]) { +export async function executeMavenTests(testsToBeExecuted: string[]):Promise { //public doc link: https://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html //maven command like "mvn test -Dtest=," @@ -31,5 +31,7 @@ export async function executemaventests(testsToBeExecuted: string[]) { tl.debug("Executing java maven tests with executable : " + executable); tl.debug("Executing java maven tests with args :" + args); - await execMavenBuild(args); + let status = await execMavenBuild(args); + + return status ?? 1; } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/Invokers/pythoninvoker.ts b/_generated/AzureTestPlanV0_Node20/Invokers/pythoninvoker.ts index 77c6de3c5828..36ec39662b74 100644 --- a/_generated/AzureTestPlanV0_Node20/Invokers/pythoninvoker.ts +++ b/_generated/AzureTestPlanV0_Node20/Invokers/pythoninvoker.ts @@ -2,14 +2,14 @@ import { spawn, SpawnResult } from '../testexecutor'; import tl = require('azure-pipelines-task-lib/task'); import constants = require('../constants'); -export async function executepythontests(testsToBeExecuted: string[]) { +export async function executePythonTests(testsToBeExecuted: string[]):Promise { // Perform test discovery const discoveryArgs: string[] = ['--collect-only']; const discoveryResult = await runPytestCommand(discoveryArgs); if (discoveryResult.status !== 0) { tl.error("Error occurred during test discovery: " + (discoveryResult.error ? discoveryResult.error.message : "Unknown error")); - return { exitCode: 1 }; + return 1; } // Extract discovered tests from stdout @@ -20,7 +20,7 @@ export async function executepythontests(testsToBeExecuted: string[]) { if (testsToRun.length === 0) { tl.warning("No common tests found between specified tests and discovered tests."); - return { exitCode: 0 }; + return 0; } console.log(`Found ${testsToRun.length} tests to run`); @@ -34,10 +34,10 @@ export async function executepythontests(testsToBeExecuted: string[]) { if (error) { tl.error("Error executing pytest command: " + error.message); - return { exitCode: 1 }; + return 1; } - return { exitCode: status ?? 1 }; + return status ?? 1; } async function runPytestCommand(args: string[]): Promise { diff --git a/_generated/AzureTestPlanV0_Node20/automatedTestInvoker.ts b/_generated/AzureTestPlanV0_Node20/automatedTestInvoker.ts index 9b112d86ef9a..e2c7b34e1933 100644 --- a/_generated/AzureTestPlanV0_Node20/automatedTestInvoker.ts +++ b/_generated/AzureTestPlanV0_Node20/automatedTestInvoker.ts @@ -1,13 +1,16 @@ import * as tl from 'azure-pipelines-task-lib/task' -import { executepythontests } from './Invokers/pythoninvoker' -import { executemaventests } from './Invokers/maveninvoker' -import { executegradletests } from './Invokers/gradleinvoker' +import { executePythonTests } from './Invokers/pythoninvoker' +import { executeMavenTests } from './Invokers/maveninvoker' +import { executeGradleTests } from './Invokers/gradleinvoker' -export async function testInvoker(testsToBeExecuted: string[]) { +export async function testInvoker(testsToBeExecuted: string[]): Promise { const testLanguageStrings = tl.getDelimitedInput('testLanguageInput', ',', true); + let exitStatusCode = 0; + for (const testLanguage of testLanguageStrings) { + let exitCode = 0; if (testLanguage === null || testLanguage === undefined) { console.log("Please select the test framework language from the task dropdown list to execute automated tests"); @@ -16,21 +19,27 @@ export async function testInvoker(testsToBeExecuted: string[]) { switch (testLanguage) { case 'Java-Maven': - await executemaventests(testsToBeExecuted); + exitCode = await executeMavenTests(testsToBeExecuted); + tl.debug(`Execution Status Code for Maven: ${exitCode}`); break; case 'Java-Gradle': - await executegradletests(testsToBeExecuted); + exitCode = await executeGradleTests(testsToBeExecuted); + tl.debug(`Execution Status Code for Gradle: ${exitCode}`); break; case 'Python': - await executepythontests(testsToBeExecuted); + exitCode = await executePythonTests(testsToBeExecuted); + tl.debug(`Execution Status Code for Python: ${exitCode}`); break; default: console.log('Invalid test Language Input selected.'); } - + + exitStatusCode = exitStatusCode || exitCode; } - + + tl.debug(`Execution Status Code for Automated Execution Flow: ${exitStatusCode}`); + return exitStatusCode; } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/automatedTests.ts b/_generated/AzureTestPlanV0_Node20/automatedTests.ts index 16cff03b9404..8a2ec9f727f4 100644 --- a/_generated/AzureTestPlanV0_Node20/automatedTests.ts +++ b/_generated/AzureTestPlanV0_Node20/automatedTests.ts @@ -1,28 +1,39 @@ import tl = require('azure-pipelines-task-lib/task'); -import { testInvoker } from './automatedTestInvoker' -import { TestPlanData } from './testPlanData' -import { publishAutomatedTestResult } from './publishAutomatedTests' +import { testInvoker } from './automatedTestInvoker'; +import { TestPlanData } from './testPlanData'; +import { publishAutomatedTestResult } from './publishAutomatedTests'; +export async function automatedTestsFlow(testPlanInfo: TestPlanData, testSelectorInput: string): Promise { + let listOfTestsToBeExecuted: string[] = testPlanInfo.listOfFQNOfTestCases; + let testInvokerStatusCode = 0; -export async function automatedTestsFlow(testPlanInfo: TestPlanData, testSelectorInput: string) { + if (listOfTestsToBeExecuted !== null && listOfTestsToBeExecuted !== undefined && listOfTestsToBeExecuted.length > 0) { + tl.debug('Invoking test execution for tests: ' + listOfTestsToBeExecuted); - let listOfTestsToBeExecuted: string[] = testPlanInfo.listOfFQNOfTestCases; - - console.log(tl.loc('automatedTestTriggered')); - - if (listOfTestsToBeExecuted !== null && listOfTestsToBeExecuted !== undefined && listOfTestsToBeExecuted.length > 0) { - tl.debug("Invoking test execution for tests: " + listOfTestsToBeExecuted); - await testInvoker(listOfTestsToBeExecuted); - publishAutomatedTestResult(JSON.stringify(testPlanInfo.listOfAutomatedTestPoints)); + try { + testInvokerStatusCode = await testInvoker(listOfTestsToBeExecuted); + } catch (err) { + tl.debug(`Unable to invoke automated test execution. Err:( ${err} )`); + testInvokerStatusCode = 1; } - else { - console.log("No automated tests found for given test plan inputs "); - if (testSelectorInput === 'automatedTests') { - tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnNoAutomatedTestsFound')); - } - else { - tl.setResult(tl.TaskResult.Succeeded, "Successfully triggered manual test execution"); - } + + try { + await publishAutomatedTestResult(JSON.stringify(testPlanInfo.listOfAutomatedTestPoints)); + } catch (err) { + tl.error(`Error while publishing automated Test Results with err : ( ${err} )`); + return 1; } + tl.debug(`Execution Status Code for test Invoker: ${testInvokerStatusCode}`); + return testInvokerStatusCode; + } else { + console.log('No automated tests found for given test plan inputs '); + if (testSelectorInput === 'automatedTests') { + tl.setResult(tl.TaskResult.Failed, tl.loc('ErrorFailTaskOnNoAutomatedTestsFound')); + return 1; + } else { + tl.setResult(tl.TaskResult.Succeeded, 'Successfully triggered manual test execution'); + return 0; + } + } } diff --git a/_generated/AzureTestPlanV0_Node20/manualTests.ts b/_generated/AzureTestPlanV0_Node20/manualTests.ts index 4ae0e2dde00e..20804591656c 100644 --- a/_generated/AzureTestPlanV0_Node20/manualTests.ts +++ b/_generated/AzureTestPlanV0_Node20/manualTests.ts @@ -1,13 +1,20 @@ import tl = require('azure-pipelines-task-lib/task'); import { TestPlanData, createManualTestRun, ManualTestRunData } from './testPlanData'; -export async function manualTestsFlow(testPlanInfo: TestPlanData) { +export async function manualTestsFlow(testPlanInfo: TestPlanData):Promise { let manualTestRun: ManualTestRunData = { testRunId: 0, runUrl: "" }; - manualTestRun = await createManualTestRun(testPlanInfo); - + try{ + manualTestRun = await createManualTestRun(testPlanInfo); + } + catch (err){ + tl.debug(`Unable to create Manual Test Run. Err:( ${err} )`); + return 1; + } + console.log('Test run id created: ', manualTestRun.testRunId); console.log('Test run url: ', manualTestRun.runUrl); + return 0; } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/runTestPlan.ts b/_generated/AzureTestPlanV0_Node20/runTestPlan.ts index 539300a9115a..dacaf31eb491 100644 --- a/_generated/AzureTestPlanV0_Node20/runTestPlan.ts +++ b/_generated/AzureTestPlanV0_Node20/runTestPlan.ts @@ -10,12 +10,21 @@ export async function run() { const testPlanInfo = await getTestPlanData(); + let manualTestFlowReturnCode = 0; + let automatedTestFlowReturnCode = 0; + // trigger manual, automated or both tests based on user's input if (testSelectorInput.includes('manualTests')) { - await manualTestsFlow(testPlanInfo); + manualTestFlowReturnCode = await manualTestsFlow(testPlanInfo); + tl.debug(`Execution Status Code for Manual Test Flow is ${manualTestFlowReturnCode}`); } if (testSelectorInput.includes('automatedTests')) { - await automatedTestsFlow(testPlanInfo, testSelectorInput); + automatedTestFlowReturnCode = await automatedTestsFlow(testPlanInfo, testSelectorInput); + tl.debug(`Execution Status Code for Automated Test Flow is ${automatedTestFlowReturnCode}`); + } + + if( manualTestFlowReturnCode || automatedTestFlowReturnCode){ + tl.setResult(tl.TaskResult.Failed, "Faced error in execution."); } } diff --git a/_generated/AzureTestPlanV0_Node20/task.json b/_generated/AzureTestPlanV0_Node20/task.json index 6232fa4d7658..0e648452ff18 100644 --- a/_generated/AzureTestPlanV0_Node20/task.json +++ b/_generated/AzureTestPlanV0_Node20/task.json @@ -14,7 +14,7 @@ "version": { "Major": 0, "Minor": 238, - "Patch": 7 + "Patch": 9 }, "preview": true, "demands": [], @@ -183,7 +183,7 @@ "MultipleMatchingGradlewFound": "Multiple gradlew files found. Selecting the first matched instance" }, "_buildConfigMapping": { - "Default": "0.238.6", - "Node20-225": "0.238.7" + "Default": "0.238.8", + "Node20-225": "0.238.9" } } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/task.loc.json b/_generated/AzureTestPlanV0_Node20/task.loc.json index 6305bec48393..5cf10f0b7cd3 100644 --- a/_generated/AzureTestPlanV0_Node20/task.loc.json +++ b/_generated/AzureTestPlanV0_Node20/task.loc.json @@ -14,7 +14,7 @@ "version": { "Major": 0, "Minor": 238, - "Patch": 7 + "Patch": 9 }, "preview": true, "demands": [], @@ -183,7 +183,7 @@ "MultipleMatchingGradlewFound": "ms-resource:loc.messages.MultipleMatchingGradlewFound" }, "_buildConfigMapping": { - "Default": "0.238.6", - "Node20-225": "0.238.7" + "Default": "0.238.8", + "Node20-225": "0.238.9" } } \ No newline at end of file diff --git a/_generated/AzureTestPlanV0_Node20/testLibExecutor.ts b/_generated/AzureTestPlanV0_Node20/testLibExecutor.ts index 2ba3d22ddba9..ce53da0f3689 100644 --- a/_generated/AzureTestPlanV0_Node20/testLibExecutor.ts +++ b/_generated/AzureTestPlanV0_Node20/testLibExecutor.ts @@ -54,35 +54,32 @@ function getExecOptions(): tr.IExecOptions { * @param args Arguments to execute via mvn * @returns execution Status Code */ -export async function execMavenBuild(args: string[]) { - +export async function execMavenBuild(args: string[]): Promise { var mvnExec = getMavenExec(); // Setup tool runner that executes Maven only to retrieve its version var mvnGetVersion = tl.tool(mvnExec); mvnGetVersion.arg('-version'); - // 1. Check that Maven exists by executing it to retrieve its version. - await mvnGetVersion.exec() - .fail(function (err) { - console.error("Maven is not installed on the agent"); - tl.setResult(tl.TaskResult.Failed, "Maven is not installed."); // tl.exit sets the step result but does not stop execution - process.exit(1); - }) - .then(async function (code) { - // Setup Maven Executable to run list of test runs provided as input - var mvnRun = tl.tool(mvnExec); - mvnRun.arg('-ntp'); - mvnRun.arg(args); - - // 3. Run Maven. Compilation or test errors will cause this to fail. - return mvnRun.exec(getExecOptions()); - }) - .fail(function (err) { - console.error(err.message); - tl.setResult(tl.TaskResult.Failed, "Build failed."); // tl.exit sets the step result but does not stop execution - process.exit(1); - }); + try { + // 1. Check that Maven exists by executing it to retrieve its version. + await mvnGetVersion.exec(); + + // Setup Maven Executable to run list of test runs provided as input + var mvnRun = tl.tool(mvnExec); + mvnRun.arg('-ntp'); + mvnRun.arg(args); + + // 3. Run Maven. Compilation or test errors will cause this to fail. + await mvnRun.exec(getExecOptions()); + + // Maven build succeeded + return 0; // Return 0 indicating success + } catch (err) { + console.error(err.message); + tl.setResult(tl.TaskResult.Failed, "Build failed."); + return 1; // Return 1 indicating failure + } } function getGradlewExec() { @@ -105,14 +102,16 @@ function getGradlewExec() { if (gradlewPath.length == 0) { tl.setResult(tl.TaskResult.Failed, "Missing gradlew file"); + return ""; } + var gradlewExec: string = gradlewPath[0]; + if (gradlewPath.length > 1) { tl.warning(tl.loc('MultipleMatchingGradlewFound')); + tl.debug(gradlewExec); } - var gradlewExec: string = gradlewPath[0]; - if (isWindows) { tl.debug('Append .bat extension name to gradlew script.'); gradlewExec += '.bat'; @@ -136,22 +135,27 @@ function getGradlewExec() { * @param args Arguments to execute via mvn * @returns execution Status Code */ -export async function execGradleBuild(args: string[]) { +export async function execGradleBuild(args: string[]): Promise { var gradleExec = getGradlewExec(); - // Setup tool runner that executes Maven only to retrieve its version + if (!gradleExec || gradleExec == "") { + return 1; // Return 1 indicating failure + } + + // Setup tool runner that executes Gradle var gradleRunner = tl.tool(gradleExec); // Add args prepared by invoker for executing individual test cases gradleRunner.arg('clean'); gradleRunner.arg(args); - var statusCode = await gradleRunner.exec(getExecOptions()) - .fail(function (err) { - console.error(err.message); - tl.setResult(tl.TaskResult.Failed, "Build failed."); // tl.exit sets the step result but does not stop execution - process.exit(1); - }); - - return statusCode; + try { + await gradleRunner.exec(getExecOptions()); + // Gradle build succeeded + return 0; // Return 0 indicating success + } catch (err) { + console.error(err.message); + tl.setResult(tl.TaskResult.Failed, "Build failed."); // Set the step result to Failed + return 1; // Return 1 indicating failure + } } \ No newline at end of file