-
Notifications
You must be signed in to change notification settings - Fork 173
Description
runs:
using: "composite"
steps:
- name: Post a message in a channel
uses: slackapi/slack-github-action@v2.0.0
with:
webhook: "${{ env.SLACK_WEBHOOK_URL }}"
webhook-type: incoming-webhook
# See: https://api.slack.com/reference/messaging/attachments
payload: |
attachments:
- color: "${{ inputs.status == 'success' && 'good' || inputs.status == 'failure' && 'danger' || '#808080' }}"
pretext: "${{ inputs.text }}"
title: "Build Status: ${{ inputs.status }}"
title_link: "${{ github.event.pull_request.html_url || github.event.head_commit.url }}"
fields:
- title: "Author"
value: "${{ github.event.head_commit.author.name }}"
short: true
- title: "Repository"
value: "<${{ github.event.repository.html_url }}|${{ github.event.repository.full_name }}>"
short: true
- title: "Head commit"
value: "<${{ github.event.head_commit.url }}|${{ github.event.head_commit.message }}>"
short: false
With the above call to slack-github-action
I ran into a parsing issue. For certain commit messages, the followed error occured.
file:///home/runner/_work/_actions/slackapi/slack-github-action/v2.0.0/src/content.js:93
throw new SlackError(
^
SlackError: Invalid input! Failed to parse contents of the provided payload
at Content.getContentPayload (file:///home/runner/_work/_actions/slackapi/slack-github-action/v2.0.0/src/content.js:93:1)
at Content.get (file:///home/runner/_work/_actions/slackapi/slack-github-action/v2.0.0/src/content.js:28:1)
at new Config (file:///home/runner/_work/_actions/slackapi/slack-github-action/v2.0.0/src/config.js:115:1)
at send (file:///home/runner/_work/_actions/slackapi/slack-github-action/v2.0.0/src/send.js:13:1)
at file:///home/runner/_work/_actions/slackapi/slack-github-action/v2.0.0/src/index.js:9:1
at ModuleJob.run (node:internal/modules/esm/module_job:263:25)
at ModuleLoader.import (node:internal/modules/esm/loader:540:24)
at asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5)
After trying a bunch of commit messages, I could simplify the string that would cause the above error to the following
\n---\n
This string would be inserted into ${{ github.event.head_commit.message }}>
This is a YAML-directive. Which is weird, because the variables do not exist at YAML-level.
Code
I then further tracked it down to the following code.
First, it translates the variables to their values. Here
slack-github-action/src/content.js
Line 121 in d07fadf
const content = this.templatize(config, input); |
And
slack-github-action/src/content.js
Lines 155 to 166 in d07fadf
templatize(config, input) { | |
if (!config.inputs.payloadTemplated) { | |
return input; | |
} | |
const template = input.replace(/\$\{\{/g, "{{"); // swap ${{ for {{ | |
const context = { | |
env: process.env, | |
github: github.context, | |
}; | |
return markup.up(template, context); | |
} | |
} |
It tries to parse the payload parameter as YAML
slack-github-action/src/content.js
Lines 64 to 77 in d07fadf
try { | |
const input = this.templatize(config, config.inputs.payload); | |
const content = /** @type {Content} */ ( | |
yaml.load(input, { | |
schema: yaml.JSON_SCHEMA, | |
}) | |
); | |
return /** @type {Content} */ (content); | |
} catch (error) { | |
if (error instanceof Error) { | |
config.core.debug("Failed to parse input payload as YAML"); | |
config.core.debug(error.message); | |
} | |
} |
If that fails, it tries to parse the payload parameter as JSON
slack-github-action/src/content.js
Lines 78 to 100 in d07fadf
try { | |
const trimmed = config.inputs.payload.trim(); | |
if ( | |
!config.inputs.payload.startsWith("{") && | |
!config.inputs.payload.endsWith("}") | |
) { | |
config.core.debug( | |
"Wrapping input payload in braces to create valid JSON", | |
); | |
const comma = trimmed.replace(/,$/, ""); // remove trailing comma | |
const wrap = `{${comma}}`; | |
return JSON.parse(wrap); | |
} | |
return JSON.parse(trimmed); | |
} catch (/** @type {any} */ error) { | |
throw new SlackError( | |
config.core, | |
"Invalid input! Failed to parse contents of the provided payload", | |
{ | |
cause: error, | |
}, | |
); | |
} |
If that fails, it exits.
What I think is the problem
The problem I see with this however, is that the order is incorrect. What is being done is:
- Change variables to their output value.
- Parse Yaml
What should be done is:
- Parse Yaml
- Change variables to their output value
This might also have security implications, since the inserted variables could modify the yaml document. I know to little about YAML and use cases for slack-github-action
to be sure.