Skip to content

Commit

Permalink
Merge pull request #537 from getwud/feature/#520_improve_templates
Browse files Browse the repository at this point in the history
⭐ [TRIGGER] - Improve  and  templates
  • Loading branch information
fmartinou authored Dec 30, 2024
2 parents e93642f + b35064e commit 93e92a8
Show file tree
Hide file tree
Showing 25 changed files with 218 additions and 174 deletions.
62 changes: 27 additions & 35 deletions app/model/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,30 +73,36 @@ const schema = joi.object({

/**
* Render Link template.
* @param linkTemplate
* @param tagValue
* @param isSemver
* @param container
* @returns {undefined|*}
*/
function getLink(linkTemplate, tagValue, isSemver) {
if (!linkTemplate) {
function getLink(container, originalTagValue) {
if (!container || !container.linkTemplate) {
return undefined;
}
const raw = tagValue;
let link = linkTemplate;
link = link.replace(/\${\s*raw\s*}/g, raw);
if (isSemver) {
const versionSemver = parseSemver(tagValue);
const { major, minor, patch, prerelease } = versionSemver;
link = link.replace(/\${\s*major\s*}/g, major);
link = link.replace(/\${\s*minor\s*}/g, minor);
link = link.replace(/\${\s*patch\s*}/g, patch);
link = link.replace(
/\${\s*prerelease\s*}/g,
prerelease && prerelease.length > 0 ? prerelease[0] : '',
);

// Export vars for dynamic template interpolation
const raw = originalTagValue; // deprecated, kept for backward compatibility
const original = originalTagValue;
const transformed = container.transformTags
? transformTag(container.transformTags, originalTagValue)
: originalTagValue;
let major = '';
let minor = '';
let patch = '';
let prerelease = '';

if (container.image.tag.semver) {
const versionSemver = parseSemver(transformed);
major = versionSemver.major;
minor = versionSemver.minor;
patch = versionSemver.patch;
prerelease =
versionSemver.prerelease && versionSemver.prerelease.length > 0
? prerelease[0]
: '';
}
return link;
return eval('`' + container.linkTemplate + '`');
}

/**
Expand Down Expand Up @@ -161,29 +167,15 @@ function addLinkProperty(container) {
Object.defineProperty(container, 'link', {
enumerable: true,
get() {
return getLink(
container.linkTemplate,
transformTag(
container.transformTags,
container.image.tag.value,
),
container.image.tag.semver,
);
return getLink(container, container.image.tag.value);
},
});

if (container.result) {
Object.defineProperty(container.result, 'link', {
enumerable: true,
get() {
return getLink(
container.linkTemplate,
transformTag(
container.transformTags,
container.result.tag,
),
container.image.tag.semver,
);
return getLink(container, container.result.tag);
},
});
}
Expand Down
11 changes: 9 additions & 2 deletions app/model/container.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,16 @@ test('getLink should render link templates when called', () => {
const getLink = container.__get__('getLink');
expect(
getLink(
'https://test-${major}.${minor}.${patch}.acme.com',
{
linkTemplate:
'https://test-${major}.${minor}.${patch}.acme.com',
image: {
tag: {
semver: true,
},
},
},
'10.5.2',
true,
),
).toEqual('https://test-10.5.2.acme.com');
});
Expand Down
66 changes: 29 additions & 37 deletions app/triggers/providers/Trigger.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,35 @@ const { fullName } = require('../../model/container');
* @returns {*}
*/
function renderSimple(template, container) {
let value = template;
value = value.replace(/\${\s*id\s*}/g, container.id ? container.id : '');
value = value.replace(
/\${\s*name\s*}/g,
container.name ? container.name : '',
);
value = value.replace(
/\${\s*watcher\s*}/g,
container.watcher ? container.watcher : '',
);
value = value.replace(
/\${\s*kind\s*}/g,
// Set deprecated vars for backward compatibility
const id = container.id;
const name = container.name;
const watcher = container.watcher;
const kind =
container.updateKind && container.updateKind.kind
? container.updateKind.kind
: '',
);
value = value.replace(
/\${\s*semver\s*}/g,
: '';
const semver =
container.updateKind && container.updateKind.semverDiff
? container.updateKind.semverDiff
: '',
);
value = value.replace(
/\${\s*local\s*}/g,
: '';
const local =
container.updateKind && container.updateKind.localValue
? container.updateKind.localValue
: '',
);
value = value.replace(
/\${\s*remote\s*}/g,
: '';
const remote =
container.updateKind && container.updateKind.remoteValue
? container.updateKind.remoteValue
: '',
);
value = value.replace(
/\${\s*link\s*}/g,
container.result && container.result.link ? container.result.link : '',
);
return value;
: '';
const link =
container.result && container.result.link ? container.result.link : '';
return eval('`' + template + '`');
}

function renderBatch(template, containers) {
// Set deprecated vars for backward compatibility
const count = containers ? containers.length : 0;
return eval('`' + template + '`');
}

/**
Expand Down Expand Up @@ -296,13 +286,17 @@ class Trigger extends Component {
once: this.joi.boolean().default(true),
simpletitle: this.joi
.string()
.default('New ${kind} found for container ${name}'),
.default(
'New ${container.updateKind.kind} found for container ${container.name}',
),
simplebody: this.joi
.string()
.default(
'Container ${name} running with ${kind} ${local} can be updated to ${kind} ${remote}\n${link}',
'Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? "\\n" + container.result.link : ""}',
),
batchtitle: this.joi.string().default('${count} updates available'),
batchtitle: this.joi
.string()
.default('${containers.length} updates available'),
});
const schemaValidated =
schemaWithDefaultOptions.validate(configuration);
Expand Down Expand Up @@ -368,9 +362,7 @@ class Trigger extends Component {
* @returns {*}
*/
renderBatchTitle(containers) {
let title = this.configuration.batchtitle;
title = title.replace(/\$\{\s*count\s*\}/g, containers.length);
return title;
return renderBatch(this.configuration.batchtitle, containers);
}

/**
Expand Down
26 changes: 23 additions & 3 deletions app/triggers/providers/Trigger.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ const configurationValid = {
once: true,
mode: 'simple',
auto: true,
simpletitle: 'New ${kind} found for container ${name}',
simpletitle:
'New ${container.updateKind.kind} found for container ${container.name}',

simplebody:
'Container ${name} running with ${kind} ${local} can be updated to ${kind} ${remote}\n${link}',
'Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? "\\n" + container.result.link : ""}',

batchtitle: '${count} updates available',
batchtitle: '${containers.length} updates available',
};

beforeEach(() => {
Expand Down Expand Up @@ -408,6 +409,25 @@ test('renderSimpleBody should replace placeholders when template is a customized
);
});

test('renderSimpleBody should evaluate js functions when template is a customized one', async () => {
trigger.configuration.simplebody =
'Container ${name} update from ${local.substring(0, 15)} to ${remote.substring(0, 15)}';
expect(
trigger.renderSimpleBody({
name: 'container-name',
updateKind: {
kind: 'digest',
localValue:
'sha256:9a82d5773ccfcb73ba341619fd44790a30750731568c25a6e070c2c44aa30bde',
remoteValue:
'sha256:6cdd479147e4d2f1f853c7205ead7e2a0b0ccbad6e3ff0986e01936cbd179c17',
},
}),
).toEqual(
'Container container-name update from sha256:9a82d577 to sha256:6cdd4791',
);
});

test('renderBatchTitle should replace placeholders when called', async () => {
expect(
trigger.renderBatchTitle([
Expand Down
9 changes: 5 additions & 4 deletions app/triggers/providers/apprise/Apprise.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ const configurationValid = {
once: true,
mode: 'simple',

simpletitle: 'New ${kind} found for container ${name}',
simpletitle:
'New ${container.updateKind.kind} found for container ${container.name}',

simplebody:
'Container ${name} running with ${kind} ${local} can be updated to ${kind} ${remote}\n${link}',
'Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? "\\n" + container.result.link : ""}',

batchtitle: '${count} updates available',
batchtitle: '${containers.length} updates available',
};

beforeEach(() => {
Expand Down Expand Up @@ -76,7 +77,7 @@ test('trigger should send POST http request to notify endpoint', async () => {
body: {
urls: 'maito://user:[email protected]',
title: 'New tag found for container container1',
body: 'Container container1 running with tag 1.0.0 can be updated to tag 2.0.0\n',
body: 'Container container1 running with tag 1.0.0 can be updated to tag 2.0.0',
format: 'text',
type: 'info',
},
Expand Down
7 changes: 4 additions & 3 deletions app/triggers/providers/command/Command.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ const configurationValid = {
mode: 'simple',
once: true,
auto: true,
simpletitle: 'New ${kind} found for container ${name}',
simpletitle:
'New ${container.updateKind.kind} found for container ${container.name}',
simplebody:
'Container ${name} running with ${kind} ${local} can be updated to ${kind} ${remote}\n${link}',
batchtitle: '${count} updates available',
'Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? "\\n" + container.result.link : ""}',
batchtitle: '${containers.length} updates available',
};

beforeEach(() => {
Expand Down
16 changes: 9 additions & 7 deletions app/triggers/providers/discord/Discord.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ const configurationValid = {
mode: 'simple',
once: true,
auto: true,
simpletitle: 'New ${kind} found for container ${name}',
simpletitle:
'New ${container.updateKind.kind} found for container ${container.name}',

simplebody:
'Container ${name} running with ${kind} ${local} can be updated to ${kind} ${remote}\n${link}',
'Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? "\\n" + container.result.link : ""}',

batchtitle: '${count} updates available',
batchtitle: '${containers.length} updates available',
};

beforeEach(() => {
Expand All @@ -44,7 +45,7 @@ test('validateConfiguration should throw error when invalid', () => {
test('maskConfiguration should mask sensitive data', () => {
discord.configuration = configurationValid;
expect(discord.maskConfiguration()).toEqual({
batchtitle: '${count} updates available',
batchtitle: '${containers.length} updates available',
botusername: 'Bot Name',
url: 'h********************************1',
mode: 'simple',
Expand All @@ -53,9 +54,10 @@ test('maskConfiguration should mask sensitive data', () => {
once: true,
auto: true,
simplebody:
'Container ${name} running with ${kind} ${local} can be updated to ${kind} ${remote}\n${link}',
'Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? "\\n" + container.result.link : ""}',

simpletitle: 'New ${kind} found for container ${name}',
simpletitle:
'New ${container.updateKind.kind} found for container ${container.name}',
threshold: 'all',
});
});
Expand Down Expand Up @@ -91,7 +93,7 @@ test('trigger should send POST http request to webhook endpoint', async () => {
fields: [
{
name: 'Container',
value: 'Container container1 running with tag 1.0.0 can be updated to tag 2.0.0\n',
value: 'Container container1 running with tag 1.0.0 can be updated to tag 2.0.0',
},
],
},
Expand Down
7 changes: 4 additions & 3 deletions app/triggers/providers/docker/Docker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ const configurationValid = {
mode: 'simple',
once: true,
auto: true,
simpletitle: 'New ${kind} found for container ${name}',
simpletitle:
'New ${container.updateKind.kind} found for container ${container.name}',
simplebody:
'Container ${name} running with ${kind} ${local} can be updated to ${kind} ${remote}\n${link}',
batchtitle: '${count} updates available',
'Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? "\\n" + container.result.link : ""}',
batchtitle: '${containers.length} updates available',
};

const docker = new Docker();
Expand Down
7 changes: 4 additions & 3 deletions app/triggers/providers/gotify/Gotify.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ const configurationValid = {
threshold: 'all',
once: true,
auto: true,
simpletitle: 'New ${kind} found for container ${name}',
simpletitle:
'New ${container.updateKind.kind} found for container ${container.name}',
simplebody:
'Container ${name} running with ${kind} ${local} can be updated to ${kind} ${remote}\n${link}',
'Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? "\\n" + container.result.link : ""}',

batchtitle: '${count} updates available',
batchtitle: '${containers.length} updates available',
};

test('validateConfiguration should return validated configuration when valid', () => {
Expand Down
7 changes: 4 additions & 3 deletions app/triggers/providers/http/Http.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ const configurationValid = {
mode: 'simple',
once: true,
auto: true,
simpletitle: 'New ${kind} found for container ${name}',
simpletitle:
'New ${container.updateKind.kind} found for container ${container.name}',

simplebody:
'Container ${name} running with ${kind} ${local} can be updated to ${kind} ${remote}\n${link}',
'Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? "\\n" + container.result.link : ""}',

batchtitle: '${count} updates available',
batchtitle: '${containers.length} updates available',
};

beforeEach(() => {
Expand Down
Loading

0 comments on commit 93e92a8

Please sign in to comment.