fix: parse provided payloads before replacing templated variables (#449)
Co-authored-by: William Bergamin <[email protected]>
This commit is contained in:
co-authored by
William Bergamin
parent
6e4ac77331
commit
a3c435be3a
+31
-18
@@ -37,6 +37,9 @@ export default class Content {
|
||||
this.values = github.context;
|
||||
break;
|
||||
}
|
||||
if (config.inputs.payloadTemplated) {
|
||||
this.values = this.templatize(this.values);
|
||||
}
|
||||
if (config.inputs.payloadDelimiter) {
|
||||
this.values = flatten(this.values, {
|
||||
delimiter: config.inputs.payloadDelimiter,
|
||||
@@ -63,9 +66,8 @@ export default class Content {
|
||||
);
|
||||
}
|
||||
try {
|
||||
const input = this.templatize(config, config.inputs.payload);
|
||||
const content = /** @type {Content} */ (
|
||||
yaml.load(input, {
|
||||
yaml.load(config.inputs.payload, {
|
||||
schema: yaml.JSON_SCHEMA,
|
||||
})
|
||||
);
|
||||
@@ -119,18 +121,17 @@ export default class Content {
|
||||
path.resolve(config.inputs.payloadFilePath),
|
||||
"utf-8",
|
||||
);
|
||||
const content = this.templatize(config, input);
|
||||
if (
|
||||
config.inputs.payloadFilePath.endsWith("yaml") ||
|
||||
config.inputs.payloadFilePath.endsWith("yml")
|
||||
) {
|
||||
const load = yaml.load(content, {
|
||||
const load = yaml.load(input, {
|
||||
schema: yaml.JSON_SCHEMA,
|
||||
});
|
||||
return /** @type {Content} */ (load);
|
||||
}
|
||||
if (config.inputs.payloadFilePath.endsWith("json")) {
|
||||
return JSON.parse(content);
|
||||
return JSON.parse(input);
|
||||
}
|
||||
throw new SlackError(
|
||||
config.core,
|
||||
@@ -148,20 +149,32 @@ export default class Content {
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace templated variables in the provided content if requested.
|
||||
* @param {Config} config
|
||||
* @param {string} input - The initial value of the content.
|
||||
* @returns {string} Content with templatized variables replaced.
|
||||
* Replace templated variables in the provided content as requested.
|
||||
* @param {unknown} input - The initial value of the content.
|
||||
* @returns {unknown} Content with templatized variables replaced.
|
||||
*/
|
||||
templatize(config, input) {
|
||||
if (!config.inputs.payloadTemplated) {
|
||||
return input;
|
||||
templatize(input) {
|
||||
if (Array.isArray(input)) {
|
||||
return input.map((v) => this.templatize(v));
|
||||
}
|
||||
const template = input.replace(/\$\{\{/g, "{{"); // swap ${{ for {{
|
||||
const context = {
|
||||
env: process.env,
|
||||
github: github.context,
|
||||
};
|
||||
return markup.up(template, context);
|
||||
if (input && typeof input === "object") {
|
||||
/**
|
||||
* @type {Record<string, unknown>}
|
||||
*/
|
||||
const out = {};
|
||||
for (const [k, v] of Object.entries(input)) {
|
||||
out[k] = this.templatize(v);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
if (typeof input === "string") {
|
||||
const template = input.replace(/\$\{\{/g, "{{"); // swap ${{ for {{
|
||||
const context = {
|
||||
env: process.env,
|
||||
github: github.context,
|
||||
};
|
||||
return markup.up(template, context);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
+238
-6
@@ -84,16 +84,120 @@ describe("content", () => {
|
||||
assert.deepEqual(config.content.values, expected);
|
||||
});
|
||||
|
||||
it("templatizes variables requires configuration", async () => {
|
||||
mocks.core.getInput.withArgs("payload").returns(`{
|
||||
"message": "this matches an existing variable: \${{ github.apiUrl }}",
|
||||
"channel": "C0123456789"
|
||||
}
|
||||
`);
|
||||
const config = new Config(mocks.core);
|
||||
const expected = {
|
||||
message: "this matches an existing variable: ${{ github.apiUrl }}",
|
||||
channel: "C0123456789",
|
||||
};
|
||||
assert.deepEqual(config.content.values, expected);
|
||||
});
|
||||
|
||||
it("templatizes variables with matching variables", async () => {
|
||||
mocks.core.getInput
|
||||
.withArgs("payload")
|
||||
.returns("message: Served ${{ env.NUMBER }} from ${{ github.apiUrl }}");
|
||||
mocks.core.getInput.withArgs("payload").returns(`
|
||||
channel: C0123456789
|
||||
reply_broadcast: false
|
||||
message: Served \${{ env.NUMBER }} items
|
||||
blocks:
|
||||
- type: section
|
||||
text:
|
||||
type: mrkdwn
|
||||
text: "Served \${{ env.NUMBER }} items on: \${{ env.DETAILS }}"
|
||||
- type: divider
|
||||
- type: section
|
||||
block_id: selector
|
||||
text:
|
||||
type: mrkdwn
|
||||
text: Send feedback
|
||||
accessory:
|
||||
action_id: response
|
||||
type: multi_static_select
|
||||
placeholder:
|
||||
type: plain_text
|
||||
text: Select URL
|
||||
options:
|
||||
- text:
|
||||
type: plain_text
|
||||
text: "\${{ github.apiUrl }}"
|
||||
value: api
|
||||
- text:
|
||||
type: plain_text
|
||||
text: "\${{ github.serverUrl }}"
|
||||
value: server
|
||||
- text:
|
||||
type: plain_text
|
||||
text: "\${{ github.graphqlUrl }}"
|
||||
value: graphql
|
||||
`);
|
||||
mocks.core.getBooleanInput.withArgs("payload-templated").returns(true);
|
||||
process.env.DETAILS = `
|
||||
-fri
|
||||
-sat
|
||||
-sun`;
|
||||
process.env.NUMBER = 12;
|
||||
const config = new Config(mocks.core);
|
||||
process.env.DETAILS = undefined;
|
||||
process.env.NUMBER = undefined;
|
||||
const expected = {
|
||||
message: "Served 12 from https://api.github.com",
|
||||
channel: "C0123456789",
|
||||
reply_broadcast: false,
|
||||
message: "Served 12 items",
|
||||
blocks: [
|
||||
{
|
||||
type: "section",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: "Served 12 items on: \n-fri\n-sat\n-sun",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "divider",
|
||||
},
|
||||
{
|
||||
type: "section",
|
||||
block_id: "selector",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: "Send feedback",
|
||||
},
|
||||
accessory: {
|
||||
action_id: "response",
|
||||
type: "multi_static_select",
|
||||
placeholder: {
|
||||
type: "plain_text",
|
||||
text: "Select URL",
|
||||
},
|
||||
options: [
|
||||
{
|
||||
text: {
|
||||
type: "plain_text",
|
||||
text: "https://api.github.com",
|
||||
},
|
||||
value: "api",
|
||||
},
|
||||
{
|
||||
text: {
|
||||
type: "plain_text",
|
||||
text: "https://github.com",
|
||||
},
|
||||
value: "server",
|
||||
},
|
||||
{
|
||||
text: {
|
||||
type: "plain_text",
|
||||
text: "https://api.github.com/graphql",
|
||||
},
|
||||
value: "graphql",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
assert.deepEqual(config.content.values, expected);
|
||||
});
|
||||
@@ -252,19 +356,147 @@ describe("content", () => {
|
||||
assert.deepEqual(config.content.values, expected);
|
||||
});
|
||||
|
||||
it("templatizes variables requires configuration", async () => {
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("example.json");
|
||||
mocks.fs.readFileSync
|
||||
.withArgs(path.resolve("example.json"), "utf-8")
|
||||
.returns(`{
|
||||
"message": "this matches an existing variable: \${{ github.apiUrl }}",
|
||||
"channel": "C0123456789"
|
||||
}
|
||||
`);
|
||||
const config = new Config(mocks.core);
|
||||
const expected = {
|
||||
message: "this matches an existing variable: ${{ github.apiUrl }}",
|
||||
channel: "C0123456789",
|
||||
};
|
||||
assert.deepEqual(config.content.values, expected);
|
||||
});
|
||||
|
||||
it("templatizes variables with matching variables", async () => {
|
||||
mocks.core.getInput.withArgs("payload-file-path").returns("example.json");
|
||||
mocks.fs.readFileSync
|
||||
.withArgs(path.resolve("example.json"), "utf-8")
|
||||
.returns(`{
|
||||
"message": "Served $\{\{ env.NUMBER }} from $\{\{ github.apiUrl }}"
|
||||
"channel": "C0123456789",
|
||||
"reply_broadcast": false,
|
||||
"message": "Served \${{ env.NUMBER }} items",
|
||||
"blocks": [
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "Served \${{ env.NUMBER }} items on: \${{ env.DETAILS }}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "divider"
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"block_id": "selector",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "Send feedback"
|
||||
},
|
||||
"accessory": {
|
||||
"action_id": "response",
|
||||
"type": "multi_static_select",
|
||||
"placeholder": {
|
||||
"type": "plain_text",
|
||||
"text": "Select URL"
|
||||
},
|
||||
"options": [
|
||||
{
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "\${{ github.apiUrl }}"
|
||||
},
|
||||
"value": "api"
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "\${{ github.serverUrl }}"
|
||||
},
|
||||
"value": "server"
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "\${{ github.graphqlUrl }}"
|
||||
},
|
||||
"value": "graphql"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}`);
|
||||
mocks.core.getBooleanInput.withArgs("payload-templated").returns(true);
|
||||
process.env.DETAILS = `
|
||||
-fri
|
||||
-sat
|
||||
-sun`;
|
||||
process.env.NUMBER = 12;
|
||||
const config = new Config(mocks.core);
|
||||
process.env.DETAILS = undefined;
|
||||
process.env.NUMBER = undefined;
|
||||
const expected = {
|
||||
message: "Served 12 from https://api.github.com",
|
||||
channel: "C0123456789",
|
||||
reply_broadcast: false,
|
||||
message: "Served 12 items",
|
||||
blocks: [
|
||||
{
|
||||
type: "section",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: "Served 12 items on: \n-fri\n-sat\n-sun",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "divider",
|
||||
},
|
||||
{
|
||||
type: "section",
|
||||
block_id: "selector",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: "Send feedback",
|
||||
},
|
||||
accessory: {
|
||||
action_id: "response",
|
||||
type: "multi_static_select",
|
||||
placeholder: {
|
||||
type: "plain_text",
|
||||
text: "Select URL",
|
||||
},
|
||||
options: [
|
||||
{
|
||||
text: {
|
||||
type: "plain_text",
|
||||
text: "https://api.github.com",
|
||||
},
|
||||
value: "api",
|
||||
},
|
||||
{
|
||||
text: {
|
||||
type: "plain_text",
|
||||
text: "https://github.com",
|
||||
},
|
||||
value: "server",
|
||||
},
|
||||
{
|
||||
text: {
|
||||
type: "plain_text",
|
||||
text: "https://api.github.com/graphql",
|
||||
},
|
||||
value: "graphql",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
assert.deepEqual(config.content.values, expected);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user