Problems persist using payload file
See https://github.com/slackapi/slack-github-action/pull/159#issuecomment-1563399086 and follow-up comments.
However, the tests run by this repo in GitHub Actions seem to render correctly on our (internal) Slack workspace.
Need to reproduce / figure out what is going on.
Not sure if relevant, but we are using self-hosted runners on GH (and here the rendering of the variables in the payload file fails). Is your working example (mentioned above) also using self-hosted runners?
I'm not using self hosted runners and getting the same:
All of the ??? properties come from Github context variables, i.e. ${{ github.event_name }}.
The Status -> success in the screenshot above is actually coming from the JOB_STATUS environment variable which references a Github context variable:
- name: Slack message with build result
if: success() || failure()
uses: slackapi/[email protected]
env:
JOB_STATUS: ${{ job.status }}
with:
channel-id: ${{ vars.SLACK_CHANNEL }}
payload-file-path: .github/slack/ci_slack_message.json
If I reference it directly in the JSON file, i.e. ${{ job.status }} it also gets rendered as ???:
My JSON file is as follows:
{
"attachments": [
{
"color": "${{ env.JOB_STATUS == 'success' && vars.COLOR_GREEN || env.JOB_STATUS == 'failure' && vars.COLOR_RED || vars.COLOR_ORANGE }}",
"blocks": [
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Pull Request:*\n<${{ github.event.pull_request.html_url }}|${{ github.event.pull_request.title }}>"
},
{
"type": "mrkdwn",
"text": "*Status:*\n`${{ env.JOB_STATUS }}`"
}
]
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Author:*\n${{ github.event.pull_request.user.login }}"
},
{
"type": "mrkdwn",
"text": "*Event:*\n`${{ github.event_name }}`"
}
]
},
{
"type": "divider"
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Logs"
},
"url": "${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Commit"
},
"url": "${{ github.event.pull_request.head.repo.html_url }}/commit/${{ github.event.pull_request.head.sha }}"
}
]
}
]
}
]
}
I've resorted to a workaround, which is actually a little cleaner, but nonetheless.
Instead of referencing Github context variables in the JSON file, I've moved all of the variables to environment variables:
env:
PULL_REQUEST_TITLE: ${{ github.event.pull_request.title }}
PULL_REQUEST_URL: ${{ github.event.pull_request.html_url }}
PULL_REQUEST_AUTHOR: ${{ github.event.pull_request.user.login }}
PULL_REQUEST_EVENT_NAME: ${{ github.event_name }}
PULL_REQUEST_LOGS_URL: ${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}
PULL_REQUEST_COMMIT_URL: ${{ github.event.pull_request.head.repo.html_url }}/commit/${{ github.event.pull_request.head.sha }}
However, I did run into a related issue: not only do Github context variables not render, but it seems neither do Github expressions.
For example I had:
"color": "${{ job.status == 'success' && vars.COLOR_GREEN || job.status == 'failure' && vars.COLOR_RED || vars.COLOR_ORANGE }}",
But nothing was being returned.
So I resorted to adding a PULL_REQUEST_JOB_STATUS_COLOR environment variable on the job step:
- name: Slack message with build result
if: success() || failure()
uses: slackapi/[email protected]
env:
PULL_REQUEST_JOB_STATUS: ${{ job.status }}
PULL_REQUEST_JOB_STATUS_COLOR: ${{ job.status == 'success' && vars.COLOR_GREEN || job.status == 'failure' && vars.COLOR_RED || vars.COLOR_ORANGE }}
with:
channel-id: ${{ vars.SLACK_CHANNEL }}
payload-file-path: .github/slack/ci_slack_message.json
And then just referencing it as ${{ env.PULL_REQUEST_JOB_STATUS_COLOR }} which works.
Below is my Github actions file:
name: my_workflow
on:
workflow_dispatch:
pull_request:
types: [opened, synchronize]
env:
PULL_REQUEST_TITLE: ${{ github.event.pull_request.title }}
PULL_REQUEST_URL: ${{ github.event.pull_request.html_url }}
PULL_REQUEST_AUTHOR: ${{ github.event.pull_request.user.login }}
PULL_REQUEST_EVENT_NAME: ${{ github.event_name }}
PULL_REQUEST_LOGS_URL: ${{ github.event.repository.html_url }}/actions/runs/${{ github.run_id }}
PULL_REQUEST_COMMIT_URL: ${{ github.event.pull_request.head.repo.html_url }}/commit/${{ github.event.pull_request.head.sha }}
jobs:
checks:
runs-on: ubuntu-latest
steps:
- name: Setup repo
uses: actions/checkout@v3
with:
# Required to detect modified files
# between master and PR branches.
fetch-depth: 0
- name: Slack message on build start
uses: slackapi/[email protected]
env:
PULL_REQUEST_JOB_STATUS: running
PULL_REQUEST_JOB_STATUS_COLOR: ${{ vars.COLOR_ORANGE }}
with:
channel-id: ${{ vars.SLACK_CHANNEL }}
payload-file-path: .github/slack/ci_slack_message.json
- name: Slack message with build result
if: success() || failure()
uses: slackapi/[email protected]
env:
PULL_REQUEST_JOB_STATUS: ${{ job.status }}
PULL_REQUEST_JOB_STATUS_COLOR: ${{ job.status == 'success' && vars.COLOR_GREEN || job.status == 'failure' && vars.COLOR_RED || vars.COLOR_ORANGE }}
with:
channel-id: ${{ vars.SLACK_CHANNEL }}
payload-file-path: .github/slack/ci_slack_message.json
And my JSON file:
{
"attachments": [
{
"color": "${{ env.PULL_REQUEST_JOB_STATUS_COLOR }}",
"fallback": "test",
"blocks": [
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Pull Request:*\n<${{ env.PULL_REQUEST_URL }}|${{ env.PULL_REQUEST_TITLE }}>"
},
{
"type": "mrkdwn",
"text": "*Status:*\n`${{ env.PULL_REQUEST_JOB_STATUS }}`"
}
]
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Author:*\n`${{ env.PULL_REQUEST_AUTHOR }}`"
},
{
"type": "mrkdwn",
"text": "*Event:*\n`${{ env.PULL_REQUEST_EVENT_NAME }}`"
}
]
},
{
"type": "divider"
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Logs"
},
"url": "${{ env.PULL_REQUEST_LOGS_URL }}"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Commit"
},
"url": "${{ env.PULL_REQUEST_COMMIT_URL }}"
}
]
}
]
}
]
}
+1 this issue makes it way harder than it needs to be to write payload messages based on job status, even making the payload.json exactly the way the examples in the repo show it.
It would be amazing if this could be prioritized by the maintainers.
It would help us a lot to make our workflows slimmer, since we currently can't extract the payload json to a separate files exactly due to the issues described before.
@filmaj Let me know if you need any help recreating the issue. I can share context where I am facing the same issue
Sure @joshua-reddish any examples of the failure, including the payload, which GitHub event is triggering the failure and how this action is being called, is helpful.
It needs to be mentioned that the workaround as suggested by @victorouse in https://github.com/slackapi/slack-github-action/issues/203#issuecomment-1598441341 works perfectly.
ps. I have to agree that the way you've found does come to being much cleaner. :)
@filmaj
Workflow is triggered by push to a specific branch
Payload
{
"text": "`repoName` _feat_ deployment job# ${{ github.run_id }} triggered by *${{github.actor}}* ${{ jobs.deploy.result == 'success' && 'is successful :thumbsup:' || 'has failed :error:' }}\n${{ github.repositoryUrl }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "`repoName` _feat_ deployment job# *${{ github.run_id }}* triggered by *${{github.actor}}* *${{ jobs.deploy.result == 'success' && 'is successful :thumbsup:' || 'has failed :error:' }}*\n*${{ github.repositoryUrl }}*"
}
}
]
Oddly enough, the only thing that rendered correctly in this was the *${{github.actor}}* everything else is just ???
Here is the action call:
# Send a Slack message using Webhooks
- name: slack-webhook-message
id: slack-webhook-message
uses: slackapi/[email protected]
env:
SLACK_WEBHOOK_URL: ${{ env.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: ${{ env.slackWebhookType }}
with:
payload-file-path: ${{ env.slackPayLoadFilePath }}
I can confirm that this continues to be an issue, making it really hard to work with complex message structures
🗒️ Did a bit of digging into this and it's caused by how variables are parsed in payloads in the action versus from file.
Expressions defined in the action payload.yml are replaced using certain logic in the GitHub runner. This allows for variables like ${{ github.repository }} and boolean values to be evaluated before being passed to this action.
Templatized expressions in the payload-file-path don't have this same replacement logic and so are often left without a proper replacement value. From what I can tell, only values of the github.context and the step env can be retrieved within this action's code. Other variables are left undefined and will appear as ???.
@victorouse has a great workaround for this already! I'm not immediately sure how other variables can be included within the action replacement - those of github.* - or boolean expressions within the payload can be evaluated at this time, but it seems like a limitation with the payload-file-path approach.
I plan to add more documentation around this case soon, but let's keep this issue open to track progress and learnings on the topic!
🏷️ v1.26.0 now offers a payload-file-path-parsed input to determine if templated values in the JSON payload file should be parsed and replaced. Setting this to false will skip the replacement and leave the payload file unchanged.
Not a complete solution to the ??? but this might offer workarounds in workflows for the case of undefined variables!
👋 The documentation on this was made a bit more clear after suggestions in #347!
When using a payload file in slackapi/[email protected] the payload-templated variable can be used to configure parsings. These parsings do not match inline parsings!
- name: Send templated message data to a channel
uses: slackapi/[email protected]
with:
payload-file-path: "./payload-slack-content.json"
payload-templated: true
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
Instead, variables are gathered from the GitHub event context and payload specific to a webhook. These are accessed in payload files using variables like this:
github.shagithub.runIdgithub.payload.repository.full_name
This example shows how these might be used in an actual payload file!
Finding the exact variables to use remains a challenge for me, but I think we can close this issue with these references 🙏