diff --git a/Tasks/AzureRmWebAppDeployment/Tests/L0.ts b/Tasks/AzureRmWebAppDeployment/Tests/L0.ts index 47663e758b1f..4ef07fb10757 100644 --- a/Tasks/AzureRmWebAppDeployment/Tests/L0.ts +++ b/Tasks/AzureRmWebAppDeployment/Tests/L0.ts @@ -51,6 +51,21 @@ describe('AzureRmWebAppDeployment Suite', function() { assert(ltx.equal(resultFile, expectFile) , 'Should Transform attributes on Web.config'); done(); }); + + it('Validate MSDeploy parameters', (done:MochaDone) => { + let tp = path.join(__dirname, "..", "node_modules","webdeployment-common","Tests","L0MSDeployUtility.js"); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.stdout.search('MSBUILD DEFAULT PARAMS PASSED') > 0, 'should have printed MSBUILD DEFAULT PARAMS PASSED'); + assert(tr.stdout.search('ARGUMENTS WITH SET PARAMS PASSED') > 0, 'should have printed ARGUMENTS WITH SET PARAMS PASSED'); + assert(tr.stdout.search('ARGUMENT WITH FOLDER PACKAGE PASSED') > 0, 'should have printed ARGUMENT WITH FOLDER PACKAGE PASSED'); + assert(tr.stdout.search('ARGUMENT WITH EXCLUDE APP DATA PASSED') > 0, 'should have printed ARGUMENT WITH EXCLUDE APP DATA PASSED'); + assert(tr.stdout.search('ARGUMENT WITH WAR PACKAGE PASSED') > 0, 'should have printed ARGUMENT WITH WAR PACKAGE PASSED'); + assert(tr.stdout.search('ARGUMENT WITH OVERRIDE RETRY FLAG PASSED') > 0, 'should have printed ARGUMENT WITH OVERRIDE RETRY FLAG PASSED'); + + done(); + }); } else { diff --git a/Tasks/AzureRmWebAppDeployment/operations/TaskParameters.ts b/Tasks/AzureRmWebAppDeployment/operations/TaskParameters.ts index 34c3dab214c5..158eb935c496 100644 --- a/Tasks/AzureRmWebAppDeployment/operations/TaskParameters.ts +++ b/Tasks/AzureRmWebAppDeployment/operations/TaskParameters.ts @@ -45,7 +45,11 @@ export class TaskParametersUtility { taskParameters.RemoveAdditionalFilesFlag = tl.getBoolInput('RemoveAdditionalFilesFlag', false); taskParameters.SetParametersFile = tl.getPathInput('SetParametersFile', false); taskParameters.ExcludeFilesFromAppDataFlag = tl.getBoolInput('ExcludeFilesFromAppDataFlag', false) - taskParameters.AdditionalArguments = tl.getInput('AdditionalArguments', false); + taskParameters.AdditionalArguments = tl.getInput('AdditionalArguments', false) || ''; + } + else { + // Retry Attempt is passed by default + taskParameters.AdditionalArguments = '-retryAttempts:6 -retryInterval:10000'; } return taskParameters; diff --git a/Tasks/AzureRmWebAppDeployment/task.json b/Tasks/AzureRmWebAppDeployment/task.json index d073545cb394..3a14989abaa9 100644 --- a/Tasks/AzureRmWebAppDeployment/task.json +++ b/Tasks/AzureRmWebAppDeployment/task.json @@ -323,7 +323,7 @@ "type": "string", "label": "Additional arguments", "required": false, - "defaultValue": "", + "defaultValue": "-retryAttempts:6 -retryInterval:10000", "groupName": "AdditionalDeploymentOptions", "visibleRule": "UseWebDeploy == true", "helpMarkDown": "Additional Web Deploy arguments following the syntax -key:value .
These will be applied when deploying the Azure App Service. Example: -disableLink:AppPoolExtension -disableLink:ContentExtension.
For more examples of Web Deploy operation settings, refer to [this](https://go.microsoft.com/fwlink/?linkid=838471)." diff --git a/Tasks/AzureRmWebAppDeployment/task.loc.json b/Tasks/AzureRmWebAppDeployment/task.loc.json index 76c53a2c1ba3..ebc03937022a 100644 --- a/Tasks/AzureRmWebAppDeployment/task.loc.json +++ b/Tasks/AzureRmWebAppDeployment/task.loc.json @@ -331,7 +331,7 @@ "type": "string", "label": "ms-resource:loc.input.label.AdditionalArguments", "required": false, - "defaultValue": "", + "defaultValue": "-retryAttempts:6 -retryInterval:10000", "groupName": "AdditionalDeploymentOptions", "visibleRule": "UseWebDeploy == true", "helpMarkDown": "ms-resource:loc.input.help.AdditionalArguments" diff --git a/Tasks/Common/webdeployment-common/Tests/L0MSDeployUtility.ts b/Tasks/Common/webdeployment-common/Tests/L0MSDeployUtility.ts new file mode 100644 index 000000000000..d245e180c012 --- /dev/null +++ b/Tasks/Common/webdeployment-common/Tests/L0MSDeployUtility.ts @@ -0,0 +1,99 @@ +var msdeployUtility = require('webdeployment-common/msdeployutility.js'); + +function checkParametersIfPresent(argumentString: string, argumentCheckArray: Array) { + for(var argument of argumentCheckArray) { + if(argumentString.indexOf(argument) == -1) { + return false; + } + } + + return true; +} + +var defaultMSBuildPackageArgument: string = msdeployUtility.getMSDeployCmdArgs('package.zip', 'webapp_name', { + publishUrl: 'http://webapp_name.scm.azurewebsites.net:443', userName: '$webapp_name', userPWD: 'webapp_password' +}, true, false, true, null, null, null, true, false, false); + +console.log(` * MSBUILD DEFAULT PARAMS: ${defaultMSBuildPackageArgument}`); +if(checkParametersIfPresent(defaultMSBuildPackageArgument, ["-source:package=\"'package.zip'\"", + " -dest:auto,ComputerName=\"'https://http://webapp_name.scm.azurewebsites.net:443/msdeploy.axd?site=webapp_name'\",UserName=\"'$webapp_name'\",Password=\"'webapp_password'\",AuthType=\"'Basic'\"", + " -setParam:name=\"'IIS Web Application Name'\",value=\"'webapp_name'\"", '-enableRule:AppOffline']) && defaultMSBuildPackageArgument.indexOf('-setParamFile') == -1) { + console.log("MSBUILD DEFAULT PARAMS PASSED"); +} +else { + throw new Error('MSBUILD PACKAGE DEFAULT PARAMS FAILED'); +} + + +var packageWithSetParamArgument: string = msdeployUtility.getMSDeployCmdArgs('package.zip', 'webapp_name', { + publishUrl: 'http://webapp_name.scm.azurewebsites.net:443', userName: '$webapp_name', userPWD: 'webapp_password' +}, false, false, true, null, 'temp_param.xml', null, false, false, true); + + +console.log(` * PACKAGE WITh SET PARAMS: ${packageWithSetParamArgument}`); + + +if(checkParametersIfPresent(packageWithSetParamArgument, ['-setParamFile=temp_param.xml', "-dest:contentPath=\"'webapp_name'\"" , '-enableRule:DoNotDelete'])) { + console.log('ARGUMENTS WITH SET PARAMS PASSED'); +} +else { + throw Error('ARGUMENTS WITH SET PARAMS FAILED'); +} + +var folderPackageArgument: string = msdeployUtility.getMSDeployCmdArgs('c:/package/folder', 'webapp_name', { + publishUrl: 'http://webapp_name.scm.azurewebsites.net:443', userName: '$webapp_name', userPWD: 'webapp_password' +}, true, false, true, null, null, null, true, true, true); + +console.log(` * ARGUMENT WITh FOLDER AS PACKAGE: ${folderPackageArgument}`); +if(checkParametersIfPresent(folderPackageArgument, [ + "-source:IisApp=\"'c:/package/folder'\"", + " -dest:iisApp=\"'webapp_name'\"" +])) { + console.log('ARGUMENT WITH FOLDER PACKAGE PASSED'); +} +else { + throw Error('ARGUMENT WITH FOLDER PACKAGE FAILED'); +} + + +var packageWithExcludeAppDataArgument: string = msdeployUtility.getMSDeployCmdArgs('package.zip', 'webapp_name', { + publishUrl: 'http://webapp_name.scm.azurewebsites.net:443', userName: '$webapp_name', userPWD: 'webapp_password' +}, false, true, true, null, null, null, false, false, true); + +console.log(` * ARGUMENT WITh FOLDER AS PACKAGE: ${packageWithExcludeAppDataArgument}`); + +if(checkParametersIfPresent(packageWithExcludeAppDataArgument, ['-skip:Directory=App_Data'])) { + console.log('ARGUMENT WITH EXCLUDE APP DATA PASSED'); +} +else { + throw new Error('ARGUMENT WITH EXCLUDE APP DATA FAILED'); +} + + +var warDeploymentArgument: string = msdeployUtility.getMSDeployCmdArgs('package.war', 'webapp_name', { + publishUrl: 'http://webapp_name.scm.azurewebsites.net:443', userName: '$webapp_name', userPWD: 'webapp_password' +}, false, true, true, null, null, null, false, false, true); + +console.log(` * ARGUMENT WITh WAR FILE AS PACKAGE: ${warDeploymentArgument}`); +if(checkParametersIfPresent(warDeploymentArgument, [ + " -source:contentPath=\"'package.war'\"", + " -dest:contentPath=\"'/site/webapps/package.war'\"" +])) { + console.log('ARGUMENT WITH WAR PACKAGE PASSED'); +} +else { + throw new Error('ARGUMENT WITH WAR PACKAGE FAILED'); +} + +var overrideRetryArgument: string = msdeployUtility.getMSDeployCmdArgs('package.zip', 'webapp_name', { + publishUrl: 'http://webapp_name.scm.azurewebsites.net:443', userName: '$webapp_name', userPWD: 'webapp_password' +}, false, true, true, null, null, '-retryAttempts:11 -retryInterval:5000', false, false, true); + +console.log(` * ARGUMENTS WITH WAR FILE: ${overrideRetryArgument}`); + +if(checkParametersIfPresent(overrideRetryArgument, ['-retryAttempts:11', '-retryInterval:5000'])) { + console.log('ARGUMENT WITH OVERRIDE RETRY FLAG PASSED'); +} +else { + throw new Error('ARGUMENT WITH OVERRIDE RETRY FLAG FAILED'); +} diff --git a/Tasks/Common/webdeployment-common/msdeployutility.ts b/Tasks/Common/webdeployment-common/msdeployutility.ts index 9788107f6d21..00c734e61c97 100644 --- a/Tasks/Common/webdeployment-common/msdeployutility.ts +++ b/Tasks/Common/webdeployment-common/msdeployutility.ts @@ -83,12 +83,11 @@ export function getMSDeployCmdArgs(webAppPackage: string, webAppName: string, pu if(excludeFilesFromAppDataFlag) { msDeployCmdArgs += ' -skip:Directory=App_Data'; } - - if(additionalArguments) { - msDeployCmdArgs += ' ' + additionalArguments; - } } + additionalArguments = additionalArguments ? additionalArguments : ' '; + msDeployCmdArgs += ' ' + additionalArguments; + if(!(removeAdditionalFilesFlag && useWebDeploy)) { msDeployCmdArgs += " -enableRule:DoNotDeleteRule"; } diff --git a/Tasks/IISWebAppDeploymentOnMachineGroup/Tests/L0.ts b/Tasks/IISWebAppDeploymentOnMachineGroup/Tests/L0.ts index c78722fa46e3..4b84c23ee353 100644 --- a/Tasks/IISWebAppDeploymentOnMachineGroup/Tests/L0.ts +++ b/Tasks/IISWebAppDeploymentOnMachineGroup/Tests/L0.ts @@ -53,9 +53,9 @@ describe('IISWebsiteDeploymentOnMachineGroup test suite', function() { let tp = path.join(__dirname, 'L0WindowsFailDefault.js'); let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); - tr.run(); - - var expectedErr = 'Error: msdeploy failed with return code: 1'; + tr.run(); + + var expectedErr = 'Error: msdeploy failed with return code: 1'; assert(tr.invokedToolCount == 3, 'should have invoked tool thrice despite failure'); assert(tr.errorIssues.length > 0 || tr.stderr.length > 0, 'should have written to stderr'); assert(tr.stdErrContained(expectedErr) || tr.createdErrorIssue(expectedErr), 'E should have said: ' + expectedErr); @@ -96,7 +96,7 @@ describe('IISWebsiteDeploymentOnMachineGroup test suite', function() { let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); tr.run(); - assert(tr.invokedToolCount == 0, 'should not have invoked any tool'); + assert(tr.invokedToolCount == 0, 'should not have invoked any tool'); assert(tr.stderr.length > 0 || tr.errorIssues.length > 0, 'should have written to stderr'); var expectedErr = 'Error: loc_mock_MorethanonepackagematchedwithspecifiedpatternPleaserestrainthesearchpattern'; assert(tr.stdErrContained(expectedErr) || tr.createdErrorIssue(expectedErr), 'should have said: ' + expectedErr); @@ -226,4 +226,18 @@ describe('IISWebsiteDeploymentOnMachineGroup test suite', function() { assert(tr.stdout.search('## mkdir Successful ##') >= 0, 'should have created dir including dest folder'); done(); }); + + it('Validate MSDeploy parameters', (done:MochaDone) => { + let tp = path.join(__dirname, "..", "node_modules","webdeployment-common","Tests","L0MSDeployUtility.js"); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.stdout.search('MSBUILD DEFAULT PARAMS PASSED') > 0, 'should have printed MSBUILD DEFAULT PARAMS PASSED'); + assert(tr.stdout.search('ARGUMENTS WITH SET PARAMS PASSED') > 0, 'should have printed ARGUMENTS WITH SET PARAMS PASSED'); + assert(tr.stdout.search('ARGUMENT WITH FOLDER PACKAGE PASSED') > 0, 'should have printed ARGUMENT WITH FOLDER PACKAGE PASSED'); + assert(tr.stdout.search('ARGUMENT WITH EXCLUDE APP DATA PASSED') > 0, 'should have printed ARGUMENT WITH EXCLUDE APP DATA PASSED'); + assert(tr.stdout.search('ARGUMENT WITH WAR PACKAGE PASSED') > 0, 'should have printed ARGUMENT WITH WAR PACKAGE PASSED'); + assert(tr.stdout.search('ARGUMENT WITH OVERRIDE RETRY FLAG PASSED') > 0, 'should have printed ARGUMENT WITH OVERRIDE RETRY FLAG PASSED'); + done(); + }); });