azure-pipelines-tasks-webdeployment-common 4.230.0 → 4.230.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/MSDeploy/M229/MSDeploy3.6/Microsoft.VisualStudio.RemoteControl.dll +0 -0
  2. package/MSDeploy/M229/MSDeploy3.6/Microsoft.VisualStudio.Telemetry.dll +0 -0
  3. package/MSDeploy/M229/MSDeploy3.6/Microsoft.VisualStudio.Utilities.Internal.dll +0 -0
  4. package/MSDeploy/M229/MSDeploy3.6/Microsoft.Web.Delegation.dll +0 -0
  5. package/MSDeploy/M229/MSDeploy3.6/Microsoft.Web.Deployment.Powershell.dll +0 -0
  6. package/MSDeploy/M229/MSDeploy3.6/Microsoft.Web.Deployment.Tracing.dll +0 -0
  7. package/MSDeploy/M229/MSDeploy3.6/Microsoft.Web.Deployment.dll +0 -0
  8. package/MSDeploy/M229/MSDeploy3.6/Newtonsoft.Json.dll +0 -0
  9. package/MSDeploy/M229/MSDeploy3.6/msdeploy.exe +0 -0
  10. package/MSDeploy/M229/MSDeploy3.6/msdeploy.exe.config +7 -0
  11. package/Tests/L0.d.ts +1 -0
  12. package/Tests/L0.js +23 -0
  13. package/Tests/L0.ts +22 -0
  14. package/Tests/L0CopyDirectory.d.ts +1 -5
  15. package/Tests/L0CopyDirectory.js +89 -51
  16. package/Tests/L0CopyDirectory.ts +93 -55
  17. package/Tests/L0GenerateWebConfig.d.ts +1 -2
  18. package/Tests/L0GenerateWebConfig.js +55 -24
  19. package/Tests/L0GenerateWebConfig.ts +51 -31
  20. package/Tests/L0MSDeployUtility.d.ts +2 -15
  21. package/Tests/L0MSDeployUtility.js +91 -87
  22. package/Tests/L0MSDeployUtility.ts +93 -90
  23. package/Tests/L1JSONVarSubWithComments.d.ts +1 -1
  24. package/Tests/L1JSONVarSubWithComments.js +31 -46
  25. package/Tests/L1JSONVarSubWithComments.ts +40 -52
  26. package/Tests/L1JsonVarSub.d.ts +1 -1
  27. package/Tests/L1JsonVarSub.js +58 -66
  28. package/Tests/L1JsonVarSub.ts +67 -66
  29. package/Tests/L1JsonVarSubV2.d.ts +1 -1
  30. package/Tests/L1JsonVarSubV2.js +82 -93
  31. package/Tests/L1JsonVarSubV2.ts +82 -94
  32. package/Tests/L1ValidateFileEncoding.d.ts +2 -5
  33. package/Tests/L1ValidateFileEncoding.js +52 -65
  34. package/Tests/L1ValidateFileEncoding.ts +61 -77
  35. package/Tests/L1XdtTransform.d.ts +2 -3
  36. package/Tests/L1XdtTransform.js +48 -6
  37. package/Tests/L1XdtTransform.ts +57 -6
  38. package/Tests/L1XmlVarSub.d.ts +2 -3
  39. package/Tests/L1XmlVarSub.js +56 -20
  40. package/Tests/L1XmlVarSub.ts +81 -24
  41. package/ctt/ctt/ctt.exe +0 -0
  42. package/deployusingmsdeploy.d.ts +2 -2
  43. package/deployusingmsdeploy.js +18 -12
  44. package/module.json +5 -1
  45. package/msdeployutility.d.ts +7 -4
  46. package/msdeployutility.js +102 -54
  47. package/package.json +7 -3
  48. package/packageUtility.js +6 -5
  49. package/utility.js +1 -1
  50. package/webconfigutil.d.ts +3 -1
  51. package/xdttransformationutility.js +1 -1
  52. /package/{MSDeploy3.6 → MSDeploy/M142}/MSDeploy3.6/Microsoft.Web.Delegation.dll +0 -0
  53. /package/{MSDeploy3.6 → MSDeploy/M142}/MSDeploy3.6/Microsoft.Web.Deployment.Tracing.dll +0 -0
  54. /package/{MSDeploy3.6 → MSDeploy/M142}/MSDeploy3.6/Microsoft.Web.Deployment.dll +0 -0
  55. /package/{MSDeploy3.6 → MSDeploy/M142}/MSDeploy3.6/msdeploy.exe +0 -0
  56. /package/{MSDeploy3.6 → MSDeploy/M142}/MSDeploy3.6/msdeploy.exe.config +0 -0
@@ -1,19 +1,38 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runL1XmlVarSubTests = void 0;
4
+ const path = require("path");
5
+ const assert = require("assert");
6
+ const ltx = require("ltx");
7
+ const fs = require("fs");
8
+ const tl = require("azure-pipelines-task-lib");
9
+ const xmlvariablesubstitutionutility_1 = require("../xmlvariablesubstitutionutility");
10
+ const fileencoding_1 = require("../fileencoding");
11
+ function runL1XmlVarSubTests() {
12
+ this.timeout(60000);
13
+ beforeEach(function (done) {
14
+ tl.cp(getAbsolutePath('Web.config'), getAbsolutePath('Web_test.config'), '-f', false);
15
+ tl.cp(getAbsolutePath('Web.Debug.config'), getAbsolutePath('Web_test.Debug.config'), '-f', false);
16
+ tl.cp(getAbsolutePath('parameters.xml'), getAbsolutePath('parameters_test.xml'), '-f', false);
17
+ done();
8
18
  });
9
- };
10
- var xmlSubstitutionUtility = require('azure-pipelines-tasks-webdeployment-common/xmlvariablesubstitutionutility.js');
11
- var path = require('path');
12
- function xmlVarSub() {
13
- return __awaiter(this, void 0, void 0, function* () {
14
- var tags = ["applicationSettings", "appSettings", "connectionStrings", "configSections"];
15
- var configFiles = [path.join(__dirname, 'L1XmlVarSub/Web_test.config'), path.join(__dirname, 'L1XmlVarSub/Web_test.Debug.config')];
16
- var variableMap = {
19
+ afterEach(done => {
20
+ try {
21
+ tl.rmRF(getAbsolutePath('parameters_test.xml'));
22
+ tl.rmRF(getAbsolutePath('Web_test.Debug.config'));
23
+ tl.rmRF(getAbsolutePath('Web_test.config'));
24
+ }
25
+ catch (error) {
26
+ tl.debug(error);
27
+ }
28
+ finally {
29
+ done();
30
+ }
31
+ });
32
+ it("Runs successfully with XML variable substitution", done => {
33
+ const parameterFilePath = getAbsolutePath('parameters_test.xml');
34
+ const tags = ["applicationSettings", "appSettings", "connectionStrings", "configSections"];
35
+ const variableMap = {
17
36
  'conntype': 'new_connType',
18
37
  "MyDB": "TestDB",
19
38
  'webpages:Version': '1.1.7.3',
@@ -28,10 +47,27 @@ function xmlVarSub() {
28
47
  'log_level': 'error,warning',
29
48
  'Email:ToOverride': ''
30
49
  };
31
- var parameterFilePath = path.join(__dirname, 'L1XmlVarSub/parameters_test.xml');
32
- for (var configFile of configFiles) {
33
- yield xmlSubstitutionUtility.substituteXmlVariables(configFile, tags, variableMap, parameterFilePath);
34
- }
50
+ xmlvariablesubstitutionutility_1.substituteXmlVariables(getAbsolutePath('Web_test.config'), tags, variableMap, parameterFilePath);
51
+ xmlvariablesubstitutionutility_1.substituteXmlVariables(getAbsolutePath('Web_test.Debug.config'), tags, variableMap, parameterFilePath);
52
+ assert(compareXmlFiles('Web_test.config', 'Web_Expected.config'), 'Should have substituted variables in Web.config file');
53
+ assert(compareXmlFiles('Web_test.Debug.config', 'Web_Expected.Debug.config'), 'Should have substituted variables in Web.Debug.config file');
54
+ assert(compareXmlFiles('parameters_test.xml', 'parameters_Expected.xml'), 'Should have substituted variables in parameters.xml file');
55
+ done();
35
56
  });
57
+ function getAbsolutePath(file) {
58
+ return path.join(__dirname, 'L1XmlVarSub', file);
59
+ }
60
+ function compareXmlFiles(actualFile, expectedFile) {
61
+ const actualFilePath = getAbsolutePath(actualFile);
62
+ const expectedFilePath = getAbsolutePath(expectedFile);
63
+ var actualXml = ltx.parse(readFile(actualFilePath));
64
+ var expectedXml = ltx.parse(readFile(expectedFilePath));
65
+ return ltx.equal(actualXml, expectedXml);
66
+ }
67
+ function readFile(path) {
68
+ const buffer = fs.readFileSync(path);
69
+ const encoding = fileencoding_1.detectFileEncoding(path, buffer)[0].toString();
70
+ return buffer.toString(encoding).replace(/(?<!\r)[\n]+/gm, "\r\n");
71
+ }
36
72
  }
37
- xmlVarSub();
73
+ exports.runL1XmlVarSubTests = runL1XmlVarSubTests;
@@ -1,29 +1,86 @@
1
- var xmlSubstitutionUtility = require('azure-pipelines-tasks-webdeployment-common/xmlvariablesubstitutionutility.js');
2
- var path = require('path');
3
-
4
- async function xmlVarSub() {
5
- var tags = ["applicationSettings", "appSettings", "connectionStrings", "configSections"];
6
- var configFiles = [path.join(__dirname, 'L1XmlVarSub/Web_test.config'), path.join(__dirname, 'L1XmlVarSub/Web_test.Debug.config')];
7
- var variableMap = {
8
- 'conntype' : 'new_connType',
9
- "MyDB": "TestDB",
10
- 'webpages:Version' : '1.1.7.3',
11
- 'xdt:Transform' : 'DelAttributes',
12
- 'xdt:Locator' : 'Match(tag)',
13
- 'DefaultConnection': "Url=https://primary;Database=db1;ApiKey=11111111-1111-1111-1111-111111111111;Failover = {Url:'https://secondary', ApiKey:'11111111-1111-1111-1111-111111111111'}",
14
- 'OtherDefaultConnection': 'connectionStringValue2',
15
- 'ParameterConnection': 'New_Connection_String From xml var subs',
16
- 'connectionString': 'replaced_value',
17
- 'invariantName': 'System.Data.SqlServer',
18
- 'blatvar': 'ApplicationSettingReplacedValue',
19
- 'log_level': 'error,warning',
20
- 'Email:ToOverride': ''
1
+ import * as path from 'path';
2
+ import * as assert from 'assert';
3
+ import * as ltx from 'ltx';
4
+ import * as fs from 'fs';
5
+
6
+ import * as tl from 'azure-pipelines-task-lib';
7
+
8
+ import { substituteXmlVariables } from '../xmlvariablesubstitutionutility';
9
+ import { detectFileEncoding } from "../fileencoding";
10
+
11
+ export function runL1XmlVarSubTests(this: Mocha.Suite): void {
12
+
13
+ this.timeout(60000);
14
+
15
+ beforeEach(function (done: Mocha.Done) {
16
+ tl.cp(getAbsolutePath('Web.config'), getAbsolutePath('Web_test.config'), '-f', false);
17
+ tl.cp(getAbsolutePath('Web.Debug.config'), getAbsolutePath('Web_test.Debug.config'), '-f', false);
18
+ tl.cp(getAbsolutePath('parameters.xml'), getAbsolutePath('parameters_test.xml'), '-f', false);
19
+
20
+ done();
21
+ });
22
+
23
+ afterEach(done => {
24
+ try {
25
+ tl.rmRF(getAbsolutePath('parameters_test.xml'));
26
+ tl.rmRF(getAbsolutePath('Web_test.Debug.config'));
27
+ tl.rmRF(getAbsolutePath('Web_test.config'));
28
+ }
29
+ catch (error) {
30
+ tl.debug(error);
31
+ }
32
+ finally {
33
+ done();
34
+ }
35
+ });
36
+
37
+ it("Runs successfully with XML variable substitution", done => {
38
+ const parameterFilePath = getAbsolutePath('parameters_test.xml');
39
+ const tags = ["applicationSettings", "appSettings", "connectionStrings", "configSections"];
40
+ const variableMap = {
41
+ 'conntype': 'new_connType',
42
+ "MyDB": "TestDB",
43
+ 'webpages:Version': '1.1.7.3',
44
+ 'xdt:Transform': 'DelAttributes',
45
+ 'xdt:Locator': 'Match(tag)',
46
+ 'DefaultConnection': "Url=https://primary;Database=db1;ApiKey=11111111-1111-1111-1111-111111111111;Failover = {Url:'https://secondary', ApiKey:'11111111-1111-1111-1111-111111111111'}",
47
+ 'OtherDefaultConnection': 'connectionStringValue2',
48
+ 'ParameterConnection': 'New_Connection_String From xml var subs',
49
+ 'connectionString': 'replaced_value',
50
+ 'invariantName': 'System.Data.SqlServer',
51
+ 'blatvar': 'ApplicationSettingReplacedValue',
52
+ 'log_level': 'error,warning',
53
+ 'Email:ToOverride': ''
54
+ };
55
+
56
+ substituteXmlVariables(getAbsolutePath('Web_test.config'), tags, variableMap, parameterFilePath);
57
+ substituteXmlVariables(getAbsolutePath('Web_test.Debug.config'), tags, variableMap, parameterFilePath);
58
+
59
+ assert(compareXmlFiles('Web_test.config', 'Web_Expected.config'), 'Should have substituted variables in Web.config file');
60
+ assert(compareXmlFiles('Web_test.Debug.config', 'Web_Expected.Debug.config'), 'Should have substituted variables in Web.Debug.config file');
61
+ assert(compareXmlFiles('parameters_test.xml', 'parameters_Expected.xml'), 'Should have substituted variables in parameters.xml file');
62
+
63
+ done();
64
+ });
65
+
66
+ function getAbsolutePath(file: string): string {
67
+ return path.join(__dirname, 'L1XmlVarSub', file);
68
+ }
69
+
70
+ function compareXmlFiles(actualFile: string, expectedFile: string): boolean {
71
+ const actualFilePath = getAbsolutePath(actualFile);
72
+ const expectedFilePath = getAbsolutePath(expectedFile);
73
+
74
+ var actualXml = ltx.parse(readFile(actualFilePath));
75
+ var expectedXml = ltx.parse(readFile(expectedFilePath));
76
+
77
+ return ltx.equal(actualXml, expectedXml);
21
78
  }
22
79
 
23
- var parameterFilePath = path.join(__dirname, 'L1XmlVarSub/parameters_test.xml');
24
- for(var configFile of configFiles) {
25
- await xmlSubstitutionUtility.substituteXmlVariables(configFile, tags, variableMap, parameterFilePath);
80
+ function readFile(path: string): string {
81
+ const buffer = fs.readFileSync(path);
82
+ const encoding = detectFileEncoding(path, buffer)[0].toString();
83
+ return buffer.toString(encoding).replace(/(?<!\r)[\n]+/gm, "\r\n");
26
84
  }
27
85
  }
28
86
 
29
- xmlVarSub();
Binary file
@@ -13,5 +13,5 @@ import { WebDeployArguments, WebDeployResult } from './msdeployutility';
13
13
  * @param additionalArguments Arguments provided by user
14
14
  *
15
15
  */
16
- export declare function DeployUsingMSDeploy(webDeployPkg: any, webAppName: any, publishingProfile: any, removeAdditionalFilesFlag: any, excludeFilesFromAppDataFlag: any, takeAppOfflineFlag: any, virtualApplication: any, setParametersFile: any, additionalArguments: any, isFolderBasedDeployment: any, useWebDeploy: any): Promise<void>;
17
- export declare function executeWebDeploy(WebDeployArguments: WebDeployArguments, publishingProfile: any): Promise<WebDeployResult>;
16
+ export declare function DeployUsingMSDeploy(webDeployPkg: any, webAppName: any, publishingProfile: any, removeAdditionalFilesFlag: any, excludeFilesFromAppDataFlag: any, takeAppOfflineFlag: any, virtualApplication: any, setParametersFile: any, additionalArguments: any, isFolderBasedDeployment: any, useWebDeploy: any, authType?: string): Promise<void>;
17
+ export declare function executeWebDeploy(webDeployArguments: WebDeployArguments): Promise<WebDeployResult>;
@@ -14,6 +14,7 @@ const tl = require("azure-pipelines-task-lib/task");
14
14
  const fs = require("fs");
15
15
  const path = require("path");
16
16
  const Q = require("q");
17
+ const msdeployutility_1 = require("./msdeployutility");
17
18
  var msDeployUtility = require('./msdeployutility.js');
18
19
  var utility = require('./utility.js');
19
20
  const DEFAULT_RETRY_COUNT = 3;
@@ -31,7 +32,7 @@ const DEFAULT_RETRY_COUNT = 3;
31
32
  * @param additionalArguments Arguments provided by user
32
33
  *
33
34
  */
34
- function DeployUsingMSDeploy(webDeployPkg, webAppName, publishingProfile, removeAdditionalFilesFlag, excludeFilesFromAppDataFlag, takeAppOfflineFlag, virtualApplication, setParametersFile, additionalArguments, isFolderBasedDeployment, useWebDeploy) {
35
+ function DeployUsingMSDeploy(webDeployPkg, webAppName, publishingProfile, removeAdditionalFilesFlag, excludeFilesFromAppDataFlag, takeAppOfflineFlag, virtualApplication, setParametersFile, additionalArguments, isFolderBasedDeployment, useWebDeploy, authType) {
35
36
  return __awaiter(this, void 0, void 0, function* () {
36
37
  var msDeployPath = yield msDeployUtility.getMSDeployFullPath();
37
38
  var msDeployDirectory = msDeployPath.slice(0, msDeployPath.lastIndexOf('\\') + 1);
@@ -43,7 +44,7 @@ function DeployUsingMSDeploy(webDeployPkg, webAppName, publishingProfile, remove
43
44
  setParametersFileName = setParametersFile.slice(setParametersFile.lastIndexOf('\\') + 1, setParametersFile.length);
44
45
  }
45
46
  var isParamFilePresentInPackage = isFolderBasedDeployment ? false : yield utility.isMSDeployPackage(webDeployPkg);
46
- var msDeployCmdArgs = msDeployUtility.getMSDeployCmdArgs(webDeployPkg, webAppName, publishingProfile, removeAdditionalFilesFlag, excludeFilesFromAppDataFlag, takeAppOfflineFlag, virtualApplication, setParametersFileName, additionalArguments, isParamFilePresentInPackage, isFolderBasedDeployment, useWebDeploy);
47
+ var msDeployCmdArgs = msDeployUtility.getMSDeployCmdArgs(webDeployPkg, webAppName, publishingProfile, removeAdditionalFilesFlag, excludeFilesFromAppDataFlag, takeAppOfflineFlag, virtualApplication, setParametersFileName, additionalArguments, isParamFilePresentInPackage, isFolderBasedDeployment, useWebDeploy, authType);
47
48
  var retryCountParam = tl.getVariable("appservice.msdeployretrycount");
48
49
  var retryCount = (retryCountParam && !(isNaN(Number(retryCountParam)))) ? Number(retryCountParam) : DEFAULT_RETRY_COUNT;
49
50
  try {
@@ -80,26 +81,31 @@ function DeployUsingMSDeploy(webDeployPkg, webAppName, publishingProfile, remove
80
81
  });
81
82
  }
82
83
  exports.DeployUsingMSDeploy = DeployUsingMSDeploy;
83
- function executeWebDeploy(WebDeployArguments, publishingProfile) {
84
+ function executeWebDeploy(webDeployArguments) {
84
85
  return __awaiter(this, void 0, void 0, function* () {
85
- var webDeployArguments = yield msDeployUtility.getWebDeployArgumentsString(WebDeployArguments, publishingProfile);
86
+ const args = yield msdeployutility_1.getWebDeployArgumentsString(webDeployArguments);
87
+ const originalPathVar = process.env.PATH;
86
88
  try {
87
- var msDeployPath = yield msDeployUtility.getMSDeployFullPath();
88
- var msDeployDirectory = msDeployPath.slice(0, msDeployPath.lastIndexOf('\\') + 1);
89
- var pathVar = process.env.PATH;
89
+ const msDeployPath = yield msdeployutility_1.getMSDeployFullPath();
90
+ const msDeployDirectory = msDeployPath.slice(0, msDeployPath.lastIndexOf('\\') + 1);
90
91
  process.env.PATH = msDeployDirectory + ";" + process.env.PATH;
91
- yield executeMSDeploy(webDeployArguments);
92
+ yield executeMSDeploy(args);
93
+ return {
94
+ isSuccess: true
95
+ };
92
96
  }
93
97
  catch (exception) {
94
- var msDeployErrorFilePath = tl.getVariable('System.DefaultWorkingDirectory') + '\\' + 'error.txt';
95
- var errorFileContent = tl.exist(msDeployErrorFilePath) ? fs.readFileSync(msDeployErrorFilePath, 'utf-8') : "";
98
+ const msDeployErrorFilePath = tl.getVariable('System.DefaultWorkingDirectory') + '\\' + 'error.txt';
99
+ const errorFileContent = tl.exist(msDeployErrorFilePath) ? fs.readFileSync(msDeployErrorFilePath, 'utf-8') : "";
96
100
  return {
97
101
  isSuccess: false,
98
102
  error: errorFileContent,
99
- errorCode: msDeployUtility.getWebDeployErrorCode(errorFileContent)
103
+ errorCode: msdeployutility_1.getWebDeployErrorCode(errorFileContent)
100
104
  };
101
105
  }
102
- return { isSuccess: true };
106
+ finally {
107
+ process.env.PATH = originalPathVar;
108
+ }
103
109
  });
104
110
  }
105
111
  exports.executeWebDeploy = executeWebDeploy;
package/module.json CHANGED
@@ -30,6 +30,10 @@
30
30
  "VariableSubstitutionInitiated" : "Initiated variable substitution in config file : %s",
31
31
  "ConfigFileUpdated" : "Config file : %s updated.",
32
32
  "SkippedUpdatingFile" : "Skipped Updating file: %s",
33
- "PwshNotAvailable": "##WARNING##:PowerShell Core (pwsh.exe) is not available on agent machine. Falling back to using Windows PowerShell (powershell.exe). This can cause reduced performance. Please install the newer version of PowerShell for improved performance."
33
+ "PwshNotAvailable": "##WARNING##:PowerShell Core (pwsh.exe) is not available on agent machine. Falling back to using Windows PowerShell (powershell.exe). This can cause reduced performance. Please install the newer version of PowerShell for improved performance.",
34
+ "UnabletofindthelocationofMSDeployfromregistryonmachineError": "Unable to find the location of MSDeploy from registry. Error: %s",
35
+ "MissingMSDeployVersionRegistryKey": "Missing MSDeploy Version registry key.",
36
+ "UnsupportedMSDeployVersion": "MSDeploy %s does not support token base authentication. Please upgrade to MSDeploy 9.0.7225.0 or higher.",
37
+ "MissingMSDeployInstallPathRegistryKey": "Missing MSDeploy InstallPath registry key."
34
38
  }
35
39
  }
@@ -4,7 +4,7 @@ import { Package } from './packageUtility';
4
4
  *
5
5
  * @param webAppPackage Web deploy package
6
6
  * @param webAppName web App Name
7
- * @param publishingProfile Azure RM Connection Details
7
+ * @param profile Azure RM Connection Details
8
8
  * @param removeAdditionalFilesFlag Flag to set DoNotDeleteRule rule
9
9
  * @param excludeFilesFromAppDataFlag Flag to prevent App Data from publishing
10
10
  * @param takeAppOfflineFlag Flag to enable AppOffline rule
@@ -13,17 +13,19 @@ import { Package } from './packageUtility';
13
13
  * @param additionalArguments Arguments provided by user
14
14
  * @param isParamFilePresentInPacakge Flag to check Paramter.xml file
15
15
  * @param isFolderBasedDeployment Flag to check if given web package path is a folder
16
+ * @param authType Type of authentication to use
16
17
  *
17
18
  * @returns string
18
19
  */
19
- export declare function getMSDeployCmdArgs(webAppPackage: string, webAppName: string, publishingProfile: any, removeAdditionalFilesFlag: boolean, excludeFilesFromAppDataFlag: boolean, takeAppOfflineFlag: boolean, virtualApplication: string, setParametersFile: string, additionalArguments: string, isParamFilePresentInPacakge: boolean, isFolderBasedDeployment: boolean, useWebDeploy: boolean): string;
20
- export declare function getWebDeployArgumentsString(webDeployArguments: WebDeployArguments, publishingProfile: any): Promise<string>;
20
+ export declare function getMSDeployCmdArgs(webAppPackage: string, webAppName: string, profile: any, removeAdditionalFilesFlag: boolean, excludeFilesFromAppDataFlag: boolean, takeAppOfflineFlag: boolean, virtualApplication: string, setParametersFile: string, additionalArguments: string, isParamFilePresentInPacakge: boolean, isFolderBasedDeployment: boolean, useWebDeploy: boolean, authType?: string): string;
21
+ export declare function getWebDeployArgumentsString(args: WebDeployArguments): Promise<string>;
22
+ export declare function shouldUseMSDeployTokenAuth(): boolean;
21
23
  /**
22
24
  * Gets the full path of MSDeploy.exe
23
25
  *
24
26
  * @returns string
25
27
  */
26
- export declare function getMSDeployFullPath(): Promise<any>;
28
+ export declare function getMSDeployFullPath(): Promise<string>;
27
29
  /**
28
30
  * 1. Checks if msdeploy during execution redirected any error to
29
31
  * error stream ( saved in error.txt) , display error to console
@@ -44,6 +46,7 @@ export interface WebDeployArguments {
44
46
  setParametersFile?: string;
45
47
  additionalArguments?: string;
46
48
  useWebDeploy?: boolean;
49
+ authType?: string;
47
50
  }
48
51
  export interface WebDeployResult {
49
52
  isSuccess: boolean;
@@ -9,8 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.getWebDeployErrorCode = exports.redirectMSDeployErrorToConsole = exports.getMSDeployFullPath = exports.getWebDeployArgumentsString = exports.getMSDeployCmdArgs = void 0;
13
- const Q = require("q");
12
+ exports.getWebDeployErrorCode = exports.redirectMSDeployErrorToConsole = exports.getMSDeployFullPath = exports.shouldUseMSDeployTokenAuth = exports.getWebDeployArgumentsString = exports.getMSDeployCmdArgs = void 0;
14
13
  const tl = require("azure-pipelines-task-lib/task");
15
14
  const fs = require("fs");
16
15
  const path = require("path");
@@ -22,7 +21,7 @@ const ERROR_FILE_NAME = "error.txt";
22
21
  *
23
22
  * @param webAppPackage Web deploy package
24
23
  * @param webAppName web App Name
25
- * @param publishingProfile Azure RM Connection Details
24
+ * @param profile Azure RM Connection Details
26
25
  * @param removeAdditionalFilesFlag Flag to set DoNotDeleteRule rule
27
26
  * @param excludeFilesFromAppDataFlag Flag to prevent App Data from publishing
28
27
  * @param takeAppOfflineFlag Flag to enable AppOffline rule
@@ -31,10 +30,11 @@ const ERROR_FILE_NAME = "error.txt";
31
30
  * @param additionalArguments Arguments provided by user
32
31
  * @param isParamFilePresentInPacakge Flag to check Paramter.xml file
33
32
  * @param isFolderBasedDeployment Flag to check if given web package path is a folder
33
+ * @param authType Type of authentication to use
34
34
  *
35
35
  * @returns string
36
36
  */
37
- function getMSDeployCmdArgs(webAppPackage, webAppName, publishingProfile, removeAdditionalFilesFlag, excludeFilesFromAppDataFlag, takeAppOfflineFlag, virtualApplication, setParametersFile, additionalArguments, isParamFilePresentInPacakge, isFolderBasedDeployment, useWebDeploy) {
37
+ function getMSDeployCmdArgs(webAppPackage, webAppName, profile, removeAdditionalFilesFlag, excludeFilesFromAppDataFlag, takeAppOfflineFlag, virtualApplication, setParametersFile, additionalArguments, isParamFilePresentInPacakge, isFolderBasedDeployment, useWebDeploy, authType) {
38
38
  var msDeployCmdArgs = " -verb:sync";
39
39
  var webApplicationDeploymentPath = (virtualApplication) ? webAppName + "/" + virtualApplication : webAppName;
40
40
  if (isFolderBasedDeployment) {
@@ -64,9 +64,9 @@ function getMSDeployCmdArgs(webAppPackage, webAppName, publishingProfile, remove
64
64
  }
65
65
  }
66
66
  }
67
- if (publishingProfile != null) {
68
- msDeployCmdArgs += ",ComputerName=\"'https://" + publishingProfile.publishUrl + "/msdeploy.axd?site=" + webAppName + "'\",";
69
- msDeployCmdArgs += "UserName=\"'" + publishingProfile.userName + "'\",Password=\"'" + publishingProfile.userPWD + "'\",AuthType=\"'Basic'\"";
67
+ if (profile != null) {
68
+ msDeployCmdArgs += `,ComputerName=\"'https://${profile.publishUrl}/msdeploy.axd?site=${webAppName}'\",`;
69
+ msDeployCmdArgs += `UserName=\"'${profile.userName}'\",Password=\"'${profile.userPWD}'\",AuthType=\"'${authType || "Basic"}'\"`;
70
70
  }
71
71
  if (isParamFilePresentInPacakge) {
72
72
  msDeployCmdArgs += " -setParam:name=\"'IIS Web Application Name'\",value=\"'" + webApplicationDeploymentPath + "'\"";
@@ -87,7 +87,7 @@ function getMSDeployCmdArgs(webAppPackage, webAppName, publishingProfile, remove
87
87
  if (!(removeAdditionalFilesFlag && useWebDeploy)) {
88
88
  msDeployCmdArgs += " -enableRule:DoNotDeleteRule";
89
89
  }
90
- if (publishingProfile != null) {
90
+ if (profile != null) {
91
91
  var userAgent = tl.getVariable("AZURE_HTTP_USER_AGENT");
92
92
  if (userAgent) {
93
93
  msDeployCmdArgs += ' -userAgent:' + userAgent;
@@ -190,12 +190,21 @@ function parseAdditionalArguments(additionalArguments) {
190
190
  }
191
191
  return parsedArgs;
192
192
  }
193
- function getWebDeployArgumentsString(webDeployArguments, publishingProfile) {
193
+ function getWebDeployArgumentsString(args) {
194
194
  return __awaiter(this, void 0, void 0, function* () {
195
- return getMSDeployCmdArgs(webDeployArguments.package.getPath(), webDeployArguments.appName, publishingProfile, webDeployArguments.removeAdditionalFilesFlag, webDeployArguments.excludeFilesFromAppDataFlag, webDeployArguments.takeAppOfflineFlag, webDeployArguments.virtualApplication, webDeployArguments.setParametersFile, webDeployArguments.additionalArguments, yield webDeployArguments.package.isMSBuildPackage(), webDeployArguments.package.isFolder(), webDeployArguments.useWebDeploy);
195
+ const profile = {
196
+ userPWD: args.password,
197
+ userName: args.userName,
198
+ publishUrl: args.publishUrl
199
+ };
200
+ return getMSDeployCmdArgs(args.package.getPath(), args.appName, profile, args.removeAdditionalFilesFlag, args.excludeFilesFromAppDataFlag, args.takeAppOfflineFlag, args.virtualApplication, args.setParametersFile, args.additionalArguments, yield args.package.isMSBuildPackage(), args.package.isFolder(), args.useWebDeploy, args.authType);
196
201
  });
197
202
  }
198
203
  exports.getWebDeployArgumentsString = getWebDeployArgumentsString;
204
+ function shouldUseMSDeployTokenAuth() {
205
+ return (tl.getVariable("USE_MSDEPLOY_TOKEN_AUTH") || "").toLowerCase() === "true";
206
+ }
207
+ exports.shouldUseMSDeployTokenAuth = shouldUseMSDeployTokenAuth;
199
208
  /**
200
209
  * Gets the full path of MSDeploy.exe
201
210
  *
@@ -204,65 +213,104 @@ exports.getWebDeployArgumentsString = getWebDeployArgumentsString;
204
213
  function getMSDeployFullPath() {
205
214
  return __awaiter(this, void 0, void 0, function* () {
206
215
  try {
207
- var msDeployInstallPathRegKey = "\\SOFTWARE\\Microsoft\\IIS Extensions\\MSDeploy";
208
- var msDeployLatestPathRegKey = yield getMSDeployLatestRegKey(msDeployInstallPathRegKey);
209
- var msDeployFullPath = yield getMSDeployInstallPath(msDeployLatestPathRegKey);
210
- msDeployFullPath = msDeployFullPath + "msdeploy.exe";
211
- return msDeployFullPath;
216
+ const msDeployInstallPathRegKey = "\\SOFTWARE\\Microsoft\\IIS Extensions\\MSDeploy";
217
+ const msDeployLatestPathRegKey = yield getMSDeployLatestRegKey(msDeployInstallPathRegKey);
218
+ return (yield getMSDeployInstallPath(msDeployLatestPathRegKey)) + "msdeploy.exe";
212
219
  }
213
220
  catch (error) {
214
221
  tl.debug(error);
215
- return path.join(__dirname, "MSDeploy3.6/MSDeploy3.6", "msdeploy.exe");
222
+ const subfolder = shouldUseMSDeployTokenAuth() ? "M229" : "M142";
223
+ return path.join(__dirname, "MSDeploy", subfolder, "MSDeploy3.6", "msdeploy.exe");
216
224
  }
217
225
  });
218
226
  }
219
227
  exports.getMSDeployFullPath = getMSDeployFullPath;
220
228
  function getMSDeployLatestRegKey(registryKey) {
221
- var defer = Q.defer();
222
- var regKey = new winreg({
223
- hive: winreg.HKLM,
224
- key: registryKey
225
- });
226
- regKey.keys(function (err, subRegKeys) {
227
- if (err) {
228
- defer.reject(tl.loc("UnabletofindthelocationofMSDeployfromregistryonmachineError", err));
229
- return;
230
- }
231
- var latestKeyVersion = 0;
232
- var latestSubKey;
233
- for (var index in subRegKeys) {
234
- var subRegKey = subRegKeys[index].key;
235
- var subKeyVersion = subRegKey.substr(subRegKey.lastIndexOf('\\') + 1, subRegKey.length - 1);
236
- if (!isNaN(subKeyVersion)) {
237
- var subKeyVersionNumber = parseFloat(subKeyVersion);
238
- if (subKeyVersionNumber > latestKeyVersion) {
239
- latestKeyVersion = subKeyVersionNumber;
240
- latestSubKey = subRegKey;
229
+ return new Promise((resolve, reject) => {
230
+ var regKey = new winreg({
231
+ hive: winreg.HKLM,
232
+ key: registryKey
233
+ });
234
+ regKey.keys(function (err, subRegKeys) {
235
+ if (err) {
236
+ reject(tl.loc("UnabletofindthelocationofMSDeployfromregistryonmachineError", err));
237
+ return;
238
+ }
239
+ var latestKeyVersion = 0;
240
+ var latestSubKey;
241
+ for (var index in subRegKeys) {
242
+ var subRegKey = subRegKeys[index].key;
243
+ var subKeyVersion = subRegKey.substr(subRegKey.lastIndexOf('\\') + 1, subRegKey.length - 1);
244
+ if (!isNaN(subKeyVersion)) {
245
+ var subKeyVersionNumber = parseFloat(subKeyVersion);
246
+ if (subKeyVersionNumber > latestKeyVersion) {
247
+ latestKeyVersion = subKeyVersionNumber;
248
+ latestSubKey = subRegKey;
249
+ }
241
250
  }
242
251
  }
243
- }
244
- if (latestKeyVersion < 3) {
245
- defer.reject(tl.loc("UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove", latestKeyVersion));
246
- return;
247
- }
248
- defer.resolve(latestSubKey);
252
+ if (latestKeyVersion < 3) {
253
+ reject(tl.loc("UnsupportedinstalledversionfoundforMSDeployversionshouldbeatleast3orabove", latestKeyVersion));
254
+ return;
255
+ }
256
+ resolve(latestSubKey);
257
+ });
249
258
  });
250
- return defer.promise;
251
259
  }
252
260
  function getMSDeployInstallPath(registryKey) {
253
- var defer = Q.defer();
254
- var regKey = new winreg({
255
- hive: winreg.HKLM,
256
- key: registryKey
261
+ return new Promise((resolve, reject) => {
262
+ var regKey = new winreg({
263
+ hive: winreg.HKLM,
264
+ key: registryKey
265
+ });
266
+ regKey.values(function (err, items) {
267
+ if (err) {
268
+ reject(tl.loc("UnabletofindthelocationofMSDeployfromregistryonmachineError", err));
269
+ }
270
+ if (shouldUseMSDeployTokenAuth()) {
271
+ const versionItem = items.find(item => item.name === "Version");
272
+ if (!versionItem) {
273
+ reject(tl.loc("MissingMSDeployVersionRegistryKey"));
274
+ }
275
+ const minimalSupportedVersion = "9.0.7225.0";
276
+ const version = versionItem.value;
277
+ tl.debug(`Installed MSDeploy Version: ${version}`);
278
+ // MSDeploy 9.0.7225.0 is the first version to support token auth
279
+ if (compareVersions(version, minimalSupportedVersion) < 0) {
280
+ reject(tl.loc("UnsupportedMSDeployVersion", version));
281
+ }
282
+ }
283
+ const installPathItem = items.find(item => item.name === "InstallPath");
284
+ if (!installPathItem) {
285
+ reject(tl.loc("MissingMSDeployInstallPathRegistryKey"));
286
+ }
287
+ resolve(installPathItem.value);
288
+ });
257
289
  });
258
- regKey.get("InstallPath", function (err, item) {
259
- if (err) {
260
- defer.reject(tl.loc("UnabletofindthelocationofMSDeployfromregistryonmachineError", err));
261
- return;
290
+ }
291
+ function compareVersions(version1, version2) {
292
+ if (version1 === version2) {
293
+ return 0;
294
+ }
295
+ const separator = ".";
296
+ const parts1 = version1.split(separator).map(Number);
297
+ const parts2 = version2.split(separator).map(Number);
298
+ const length = Math.min(parts1.length, parts2.length);
299
+ for (let i = 0; i < length; i++) {
300
+ if (parts1[i] > parts2[i]) {
301
+ return 1;
262
302
  }
263
- defer.resolve(item.value);
264
- });
265
- return defer.promise;
303
+ if (parts1[i] < parts2[i]) {
304
+ return -1;
305
+ }
306
+ }
307
+ if (parts1.length > parts2.length) {
308
+ return 1;
309
+ }
310
+ if (parts1.length < parts2.length) {
311
+ return -1;
312
+ }
313
+ return 0;
266
314
  }
267
315
  /**
268
316
  * 1. Checks if msdeploy during execution redirected any error to
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "azure-pipelines-tasks-webdeployment-common",
3
- "version": "4.230.0",
3
+ "version": "4.230.2",
4
4
  "description": "Common Lib for MSDeploy Utility",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+ssh://git@github.com/Microsoft/azure-pipelines-tasks.git"
8
8
  },
9
9
  "scripts": {
10
- "build": "node ../build-scripts/downloadArchive.js https://vstsagenttools.blob.core.windows.net/tools/7zip/1/7zip.zip ./7zip && node ../build-scripts/downloadArchive.js https://vstsagenttools.blob.core.windows.net/tools/MSDeploy/3.6/M142/MSDeploy.zip ./MSDeploy3.6 && node make.js"
10
+ "build": "pwsh build.ps1",
11
+ "test": "nyc --all --src ./_build mocha ./_build/Tests/L0.js"
11
12
  },
12
13
  "author": "Microsoft Corporation",
13
14
  "license": "MIT",
@@ -19,6 +20,7 @@
19
20
  "@types/mocha": "^5.2.7",
20
21
  "@types/node": "^10.17.0",
21
22
  "@xmldom/xmldom": "git+https://github.com/xmldom/xmldom.git#0.8.6",
23
+ "@types/ltx": "3.0.6",
22
24
  "archiver": "1.2.0",
23
25
  "azure-pipelines-task-lib": "^4.2.0",
24
26
  "decompress-zip": "^0.3.3",
@@ -29,6 +31,8 @@
29
31
  "xml2js": "0.6.2"
30
32
  },
31
33
  "devDependencies": {
32
- "typescript": "4.0.2"
34
+ "typescript": "4.0.2",
35
+ "mocha": "^6.2.3",
36
+ "nyc": "^15.1.0"
33
37
  }
34
38
  }
package/packageUtility.js CHANGED
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.Package = exports.PackageUtility = exports.PackageType = void 0;
13
13
  const tl = require("azure-pipelines-task-lib/task");
14
14
  const utility = require("./utility");
15
- var zipUtility = require('azure-pipelines-tasks-webdeployment-common/ziputility.js');
15
+ const ziputility_1 = require("./ziputility");
16
16
  const path = require("path");
17
17
  var PackageType;
18
18
  (function (PackageType) {
@@ -73,10 +73,11 @@ class Package {
73
73
  }
74
74
  isMSBuildPackage() {
75
75
  return __awaiter(this, void 0, void 0, function* () {
76
- if (this._isMSBuildPackage == undefined) {
77
- this._isMSBuildPackage = this.getPackageType() != PackageType.folder && (yield zipUtility.checkIfFilesExistsInZip(this._path, ["parameters.xml", "systeminfo.xml"]));
78
- tl.debug("Is the package an msdeploy package : " + this._isMSBuildPackage);
79
- }
76
+ if (this._isMSBuildPackage !== undefined)
77
+ return this._isMSBuildPackage;
78
+ const shouldCheckFiles = this.getPackageType() !== PackageType.folder;
79
+ this._isMSBuildPackage = shouldCheckFiles && (yield ziputility_1.checkIfFilesExistsInZip(this._path, ["parameters.xml", "systeminfo.xml"]));
80
+ tl.debug(`Is the package an msdeploy package : ${this._isMSBuildPackage}`);
80
81
  return this._isMSBuildPackage;
81
82
  });
82
83
  }
package/utility.js CHANGED
@@ -14,7 +14,7 @@ const path = require("path");
14
14
  const os = require("os");
15
15
  const tl = require("azure-pipelines-task-lib/task");
16
16
  const packageUtility_1 = require("./packageUtility");
17
- var zipUtility = require('azure-pipelines-tasks-webdeployment-common/ziputility.js');
17
+ const zipUtility = require("./ziputility");
18
18
  /**
19
19
  * Validates the input package and finds out input type
20
20
  *