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();
+ });
});