azure-pipelines-tasks-webdeployment-common 4.226.0 → 4.229.0
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/deployusingmsdeploy.js +3 -2
- package/msdeployutility.js +94 -1
- package/package.json +1 -1
package/deployusingmsdeploy.js
CHANGED
|
@@ -171,8 +171,9 @@ function executeMSDeploy(msDeployCmdArgs) {
|
|
|
171
171
|
for (var i = 0; i < msDeployCmdArgs.length; i++) {
|
|
172
172
|
tl.debug("arg#" + i + ": " + msDeployCmdArgs[i]);
|
|
173
173
|
}
|
|
174
|
-
//
|
|
175
|
-
|
|
174
|
+
// set shell: true because C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe has folder with spaces
|
|
175
|
+
// see https://github.com/microsoft/azure-pipelines-tasks/issues/17634
|
|
176
|
+
yield tl.exec("msdeploy", msDeployCmdArgs, { failOnStdErr: true, errStream: errObj, windowsVerbatimArguments: true, shell: true });
|
|
176
177
|
deferred.resolve("Azure App service successfully deployed");
|
|
177
178
|
}
|
|
178
179
|
catch (error) {
|
package/msdeployutility.js
CHANGED
|
@@ -82,7 +82,7 @@ function getMSDeployCmdArgs(webAppPackage, webAppName, publishingProfile, remove
|
|
|
82
82
|
msDeployCmdArgs += ' -skip:Directory=App_Data';
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
-
additionalArguments = additionalArguments ? additionalArguments : ' ';
|
|
85
|
+
additionalArguments = additionalArguments ? escapeQuotes(additionalArguments) : ' ';
|
|
86
86
|
msDeployCmdArgs += ' ' + additionalArguments;
|
|
87
87
|
if (!(removeAdditionalFilesFlag && useWebDeploy)) {
|
|
88
88
|
msDeployCmdArgs += " -enableRule:DoNotDeleteRule";
|
|
@@ -97,6 +97,99 @@ function getMSDeployCmdArgs(webAppPackage, webAppName, publishingProfile, remove
|
|
|
97
97
|
return msDeployCmdArgs;
|
|
98
98
|
}
|
|
99
99
|
exports.getMSDeployCmdArgs = getMSDeployCmdArgs;
|
|
100
|
+
/**
|
|
101
|
+
* Escapes quotes in a string to ensure proper command-line parsing.
|
|
102
|
+
* @param {string} additionalArguments - The string to format.
|
|
103
|
+
* @returns {string} The formatted string with escaped quotes.
|
|
104
|
+
*/
|
|
105
|
+
function escapeQuotes(additionalArguments) {
|
|
106
|
+
const parsedArgs = parseAdditionalArguments(additionalArguments);
|
|
107
|
+
const separator = ",";
|
|
108
|
+
const formattedArgs = parsedArgs.map(function (arg) {
|
|
109
|
+
let formattedArg = '';
|
|
110
|
+
let equalsSignEncountered = false;
|
|
111
|
+
for (let i = 0; i < arg.length; i++) {
|
|
112
|
+
const char = arg.charAt(i);
|
|
113
|
+
if (char == separator && equalsSignEncountered) {
|
|
114
|
+
equalsSignEncountered = false;
|
|
115
|
+
arg = arg.replace(formattedArg, escapeArg(formattedArg));
|
|
116
|
+
formattedArg = '';
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (equalsSignEncountered) {
|
|
120
|
+
formattedArg += char;
|
|
121
|
+
}
|
|
122
|
+
if (char == '=') {
|
|
123
|
+
equalsSignEncountered = true;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
;
|
|
127
|
+
if (formattedArg.length > 0) {
|
|
128
|
+
arg = arg.replace(formattedArg, escapeArg(formattedArg));
|
|
129
|
+
}
|
|
130
|
+
return arg;
|
|
131
|
+
});
|
|
132
|
+
return formattedArgs.join(' ');
|
|
133
|
+
}
|
|
134
|
+
exports.escapeQuotes = escapeQuotes;
|
|
135
|
+
/**
|
|
136
|
+
* Escapes special characters in a string to ensure proper command-line parsing.
|
|
137
|
+
* @param {string} arg - The string to format.
|
|
138
|
+
* @returns {string} The formatted string with escaped characters.
|
|
139
|
+
*/
|
|
140
|
+
function escapeArg(arg) {
|
|
141
|
+
var escapedChars = new RegExp(/[\\\^\.\*\?\-\&\|\(\)\<\>\t\n\r\f]/);
|
|
142
|
+
// If the argument starts with dowble quote and ends with double quote, the replace it with escaped double quotes
|
|
143
|
+
if (arg.startsWith('"') && arg.endsWith('"')) {
|
|
144
|
+
return '"\\' + arg.slice(0, arg.length - 1) + '\\""';
|
|
145
|
+
}
|
|
146
|
+
// If the argument starts with single quote and ends with single quote, then replace it with escaped double qoutes
|
|
147
|
+
if (arg.startsWith("'") && arg.endsWith("'")) {
|
|
148
|
+
return '"\\"' + arg.slice(1, arg.length - 1) + '\\""';
|
|
149
|
+
}
|
|
150
|
+
if (escapedChars.test(arg)) {
|
|
151
|
+
return '"\\"' + arg + '\\""';
|
|
152
|
+
}
|
|
153
|
+
return arg;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Parses additional arguments for the msdeploy command-line utility.
|
|
157
|
+
* @param {string} additionalArguments - The additional arguments to parse.
|
|
158
|
+
* @returns {string[]} An array of parsed arguments.
|
|
159
|
+
*/
|
|
160
|
+
function parseAdditionalArguments(additionalArguments) {
|
|
161
|
+
var parsedArgs = [];
|
|
162
|
+
var isInsideQuotes = false;
|
|
163
|
+
for (let i = 0; i < additionalArguments.length; i++) {
|
|
164
|
+
var arg = '';
|
|
165
|
+
var qouteSymbol = '';
|
|
166
|
+
let char = additionalArguments.charAt(i);
|
|
167
|
+
// command parse start
|
|
168
|
+
if (char === '-') {
|
|
169
|
+
while (i < additionalArguments.length) {
|
|
170
|
+
char = additionalArguments.charAt(i);
|
|
171
|
+
const prevSym = additionalArguments.charAt(i - 1);
|
|
172
|
+
// If we reach space and we are not inside quotes, then it is the end of the argument
|
|
173
|
+
if (char === ' ' && !isInsideQuotes)
|
|
174
|
+
break;
|
|
175
|
+
// If we reach unescaped comma and we inside qoutes we assume that it is the end of quoted line
|
|
176
|
+
if (isInsideQuotes && char === qouteSymbol && prevSym !== '\\') {
|
|
177
|
+
isInsideQuotes = false;
|
|
178
|
+
qouteSymbol = '';
|
|
179
|
+
// If we reach unescaped comma and we are not inside qoutes we assume that it is the beggining of quoted line
|
|
180
|
+
}
|
|
181
|
+
else if (!isInsideQuotes && (char === '"' || char === "'") && prevSym !== '\\') {
|
|
182
|
+
isInsideQuotes = !isInsideQuotes;
|
|
183
|
+
qouteSymbol = char;
|
|
184
|
+
}
|
|
185
|
+
arg += char;
|
|
186
|
+
i += 1;
|
|
187
|
+
}
|
|
188
|
+
parsedArgs.push(arg);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return parsedArgs;
|
|
192
|
+
}
|
|
100
193
|
function getWebDeployArgumentsString(webDeployArguments, publishingProfile) {
|
|
101
194
|
return __awaiter(this, void 0, void 0, function* () {
|
|
102
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);
|