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.
- package/MSDeploy/M229/MSDeploy3.6/Microsoft.VisualStudio.RemoteControl.dll +0 -0
- package/MSDeploy/M229/MSDeploy3.6/Microsoft.VisualStudio.Telemetry.dll +0 -0
- package/MSDeploy/M229/MSDeploy3.6/Microsoft.VisualStudio.Utilities.Internal.dll +0 -0
- package/MSDeploy/M229/MSDeploy3.6/Microsoft.Web.Delegation.dll +0 -0
- package/MSDeploy/M229/MSDeploy3.6/Microsoft.Web.Deployment.Powershell.dll +0 -0
- package/MSDeploy/M229/MSDeploy3.6/Microsoft.Web.Deployment.Tracing.dll +0 -0
- package/MSDeploy/M229/MSDeploy3.6/Microsoft.Web.Deployment.dll +0 -0
- package/MSDeploy/M229/MSDeploy3.6/Newtonsoft.Json.dll +0 -0
- package/MSDeploy/M229/MSDeploy3.6/msdeploy.exe +0 -0
- package/MSDeploy/M229/MSDeploy3.6/msdeploy.exe.config +7 -0
- package/Tests/L0.d.ts +1 -0
- package/Tests/L0.js +23 -0
- package/Tests/L0.ts +22 -0
- package/Tests/L0CopyDirectory.d.ts +1 -5
- package/Tests/L0CopyDirectory.js +89 -51
- package/Tests/L0CopyDirectory.ts +93 -55
- package/Tests/L0GenerateWebConfig.d.ts +1 -2
- package/Tests/L0GenerateWebConfig.js +55 -24
- package/Tests/L0GenerateWebConfig.ts +51 -31
- package/Tests/L0MSDeployUtility.d.ts +2 -15
- package/Tests/L0MSDeployUtility.js +91 -87
- package/Tests/L0MSDeployUtility.ts +93 -90
- package/Tests/L1JSONVarSubWithComments.d.ts +1 -1
- package/Tests/L1JSONVarSubWithComments.js +31 -46
- package/Tests/L1JSONVarSubWithComments.ts +40 -52
- package/Tests/L1JsonVarSub.d.ts +1 -1
- package/Tests/L1JsonVarSub.js +58 -66
- package/Tests/L1JsonVarSub.ts +67 -66
- package/Tests/L1JsonVarSubV2.d.ts +1 -1
- package/Tests/L1JsonVarSubV2.js +82 -93
- package/Tests/L1JsonVarSubV2.ts +82 -94
- package/Tests/L1ValidateFileEncoding.d.ts +2 -5
- package/Tests/L1ValidateFileEncoding.js +52 -65
- package/Tests/L1ValidateFileEncoding.ts +61 -77
- package/Tests/L1XdtTransform.d.ts +2 -3
- package/Tests/L1XdtTransform.js +48 -6
- package/Tests/L1XdtTransform.ts +57 -6
- package/Tests/L1XmlVarSub.d.ts +2 -3
- package/Tests/L1XmlVarSub.js +56 -20
- package/Tests/L1XmlVarSub.ts +81 -24
- package/ctt/ctt/ctt.exe +0 -0
- package/deployusingmsdeploy.d.ts +2 -2
- package/deployusingmsdeploy.js +18 -12
- package/module.json +5 -1
- package/msdeployutility.d.ts +7 -4
- package/msdeployutility.js +102 -54
- package/package.json +7 -3
- package/packageUtility.js +6 -5
- package/utility.js +1 -1
- package/webconfigutil.d.ts +3 -1
- package/xdttransformationutility.js +1 -1
- /package/{MSDeploy3.6 → MSDeploy/M142}/MSDeploy3.6/Microsoft.Web.Delegation.dll +0 -0
- /package/{MSDeploy3.6 → MSDeploy/M142}/MSDeploy3.6/Microsoft.Web.Deployment.Tracing.dll +0 -0
- /package/{MSDeploy3.6 → MSDeploy/M142}/MSDeploy3.6/Microsoft.Web.Deployment.dll +0 -0
- /package/{MSDeploy3.6 → MSDeploy/M142}/MSDeploy3.6/msdeploy.exe +0 -0
- /package/{MSDeploy3.6 → MSDeploy/M142}/MSDeploy3.6/msdeploy.exe.config +0 -0
package/Tests/L1XmlVarSub.js
CHANGED
|
@@ -1,19 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
73
|
+
exports.runL1XmlVarSubTests = runL1XmlVarSubTests;
|
package/Tests/L1XmlVarSub.ts
CHANGED
|
@@ -1,29 +1,86 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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();
|
package/ctt/ctt/ctt.exe
ADDED
|
Binary file
|
package/deployusingmsdeploy.d.ts
CHANGED
|
@@ -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(
|
|
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>;
|
package/deployusingmsdeploy.js
CHANGED
|
@@ -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(
|
|
84
|
+
function executeWebDeploy(webDeployArguments) {
|
|
84
85
|
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
-
|
|
86
|
+
const args = yield msdeployutility_1.getWebDeployArgumentsString(webDeployArguments);
|
|
87
|
+
const originalPathVar = process.env.PATH;
|
|
86
88
|
try {
|
|
87
|
-
|
|
88
|
-
|
|
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(
|
|
92
|
+
yield executeMSDeploy(args);
|
|
93
|
+
return {
|
|
94
|
+
isSuccess: true
|
|
95
|
+
};
|
|
92
96
|
}
|
|
93
97
|
catch (exception) {
|
|
94
|
-
|
|
95
|
-
|
|
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:
|
|
103
|
+
errorCode: msdeployutility_1.getWebDeployErrorCode(errorFileContent)
|
|
100
104
|
};
|
|
101
105
|
}
|
|
102
|
-
|
|
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
|
}
|
package/msdeployutility.d.ts
CHANGED
|
@@ -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
|
|
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,
|
|
20
|
-
export declare function getWebDeployArgumentsString(
|
|
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<
|
|
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;
|
package/msdeployutility.js
CHANGED
|
@@ -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
|
|
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,
|
|
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 (
|
|
68
|
-
msDeployCmdArgs +=
|
|
69
|
-
msDeployCmdArgs +=
|
|
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 (
|
|
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(
|
|
193
|
+
function getWebDeployArgumentsString(args) {
|
|
194
194
|
return __awaiter(this, void 0, void 0, function* () {
|
|
195
|
-
|
|
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
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
-
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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.
|
|
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": "
|
|
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
|
-
|
|
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
|
|
77
|
-
this._isMSBuildPackage
|
|
78
|
-
|
|
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
|
-
|
|
17
|
+
const zipUtility = require("./ziputility");
|
|
18
18
|
/**
|
|
19
19
|
* Validates the input package and finds out input type
|
|
20
20
|
*
|