Skip to content

Commit 400ee20

Browse files
committed
Adds new app.config settings update task
1 parent ffbeb70 commit 400ee20

18 files changed

+703
-7
lines changed

appcfg-settings-extension.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"manifestVersion": 1,
3+
"id": "appcfg-settings",
4+
"name": "Update .NET XML Config Settings",
5+
"version": "0.1.0",
6+
"publisher": "rezStream",
7+
"targets": [
8+
{
9+
"id": "Microsoft.VisualStudio.Services"
10+
}
11+
],
12+
"description": "Updates .NET app.config and web.config settings.",
13+
"categories": [
14+
"Azure Pipelines"
15+
],
16+
"icons": {
17+
"default": "images/icon.png"
18+
},
19+
"files": [
20+
{
21+
"path": "appcfg-settings"
22+
}
23+
],
24+
"contributions": [
25+
{
26+
"id": "appcfg-settings",
27+
"type": "ms.vss-distributed-task.task",
28+
"targets": [
29+
"ms.vss-distributed-task.tasks"
30+
],
31+
"properties": {
32+
"name": "appcfg-settings"
33+
}
34+
}
35+
]
36+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<configSections>
4+
<section name="thing" type="Stuff, Thing" />
5+
</configSections>
6+
<appSettings>
7+
<add key="foo.blank" value="" />
8+
<add key="foo.bar" value="bar" />
9+
</appSettings>
10+
<connectionStrings>
11+
<clear />
12+
<add name="My.ConnectionA" providerName="System.Data.ProviderName" connectionString="" />
13+
<add name="my.connection_b" providerName="System.Data.ProviderName" connectionString="Dev Connection String;" />
14+
</connectionStrings>
15+
</configuration>

appcfg-settings/icon.png

1.54 KB
Loading

appcfg-settings/index.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import tl = require('azure-pipelines-task-lib/task');
2+
import { promises as fsPromises } from 'fs';
3+
import { DOMParser, XMLSerializer } from 'xmldom';
4+
5+
async function run() {
6+
try {
7+
const targetFilePath: string | undefined = tl.getInput('targetFilePath', true);
8+
if (targetFilePath === '' || targetFilePath == null) {
9+
tl.setResult(tl.TaskResult.Failed, 'A file path to transform is required');
10+
return;
11+
}
12+
13+
let fileMutated = false;
14+
15+
const originalContents = await fsPromises.readFile(targetFilePath, 'utf8');
16+
const parser = new DOMParser();
17+
18+
let doc = parser.parseFromString(originalContents, 'text/xml');
19+
let rootNode = doc.documentElement;
20+
if (rootNode.nodeName.toUpperCase() !== 'CONFIGURATION') {
21+
tl.setResult(tl.TaskResult.Failed, 'Config file missing root configuration element');
22+
return;
23+
}
24+
25+
const overrideNode = function(node: Node, nameKey: string, valueKey: string) {
26+
let element = <Element>node;
27+
const settingName = element.getAttribute(nameKey);
28+
if (!settingName) {
29+
return;
30+
}
31+
32+
let overrideValue = tl.getVariable(settingName);
33+
34+
if (overrideValue != null) {
35+
tl.debug(`Override found for ${settingName}`);
36+
element.setAttribute(valueKey, overrideValue);
37+
fileMutated = true;
38+
}
39+
};
40+
41+
let appSettingsNode = Array.from(rootNode.childNodes).filter(n => n.nodeType === 1 && n.nodeName.toUpperCase() === 'APPSETTINGS')[0];
42+
if (appSettingsNode) {
43+
Array.from(appSettingsNode.childNodes)
44+
.filter(n => n.nodeType === 1 && n.nodeName.toUpperCase() === 'ADD')
45+
.forEach(n => overrideNode(n, 'key', 'value'));
46+
}
47+
48+
let connStrNode = Array.from(rootNode.childNodes).filter(n => n.nodeType === 1 && n.nodeName.toUpperCase() === 'CONNECTIONSTRINGS')[0];
49+
if (connStrNode) {
50+
Array.from(connStrNode.childNodes)
51+
.filter(n => n.nodeType === 1 && n.nodeName.toUpperCase() === 'ADD')
52+
.forEach(n => overrideNode(n, 'name', 'connectionString'));
53+
}
54+
55+
if (fileMutated) {
56+
const newContents = new XMLSerializer().serializeToString(doc);
57+
await fsPromises.writeFile(targetFilePath, newContents);
58+
}
59+
else {
60+
tl.warning("No variable updates were applied to the file.");
61+
}
62+
63+
}
64+
catch (err) {
65+
tl.setResult(tl.TaskResult.Failed, err.message);
66+
}
67+
}
68+
69+
run();

0 commit comments

Comments
 (0)