Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems persist using payload file #203

Open
filmaj opened this issue May 27, 2023 · 12 comments
Open

Problems persist using payload file #203

filmaj opened this issue May 27, 2023 · 12 comments
Assignees
Labels
bug Something isn't working
Milestone

Comments

@filmaj
Copy link
Contributor

filmaj commented May 27, 2023

See #159 (comment) 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.

@filmaj filmaj added the bug Something isn't working label May 27, 2023
@rd-florian-stagliano
Copy link

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?

@victorouse
Copy link

I'm not using self hosted runners and getting the same:

image

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/slack-github-action@v1.24.0
        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 ???:

image

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 }}"
            }
          ]
        }
      ]
    }
  ]
}

@victorouse
Copy link

victorouse commented Jun 20, 2023

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/slack-github-action@v1.24.0
        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.

image

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/slack-github-action@v1.24.0
        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/slack-github-action@v1.24.0
        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 }}"
            }
          ]
        }
      ]
    }
  ]
}

@joshua-reddish
Copy link

+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.

@rd-florian-stagliano
Copy link

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 filmaj self-assigned this Jun 27, 2023
@filmaj filmaj added this to the 1.25 milestone Jun 27, 2023
@joshua-reddish
Copy link

@filmaj Let me know if you need any help recreating the issue. I can share context where I am facing the same issue

@filmaj
Copy link
Contributor Author

filmaj commented Jul 13, 2023

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.

@Darwiner
Copy link

It needs to be mentioned that the workaround as suggested by @victorouse in #203 (comment) works perfectly.

ps. I have to agree that the way you've found does come to being much cleaner. :)

@joshua-reddish
Copy link

@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/slack-github-action@v1.24.0
        env:
          SLACK_WEBHOOK_URL: ${{ env.SLACK_WEBHOOK_URL }}
          SLACK_WEBHOOK_TYPE: ${{ env.slackWebhookType }}    
        with:
          payload-file-path: ${{ env.slackPayLoadFilePath }}

@vaidik
Copy link

vaidik commented Aug 30, 2023

I can confirm that this continues to be an issue, making it really hard to work with complex message structures

@zimeg
Copy link
Member

zimeg commented Apr 4, 2024

🗒️ 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!

@zimeg
Copy link
Member

zimeg commented Apr 19, 2024

🏷️ 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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants