You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitHub Actions:toJson返回null时返回空字符串及脚本优化求助

解决GitHub Actions Slack PR通知的空值问题与代码优化

一、空值问题解决方案

Slack API要求Text Object的text字段为必填项,当PR内容或评论内容为空时,会导致生成无效JSON而执行失败。可以通过以下方式处理:

1. 用coalesce函数设置默认值

GitHub Actions支持coalesce函数,它会返回第一个非空的参数值,适合处理多场景下的空值:

CONTENT_BODY: ${{ toJson(coalesce(github.event.pull_request.body, github.event.comment.body, 'N/A')) }}
  • 优先取PR正文,若为空则取评论正文,两者都为空时用N/A替代
  • 外层包裹toJson确保文本转义正确,避免破坏JSON结构

2. 三元运算符兜底

如果需要更明确的条件判断,也可以用三元运算符:

CONTENT_BODY: ${{ toJson(github.event.pull_request.body != '' ? github.event.pull_request.body : (github.event.comment.body != '' ? github.event.comment.body : 'N/A')) }}

二、代码优化方案

原脚本通过多个独立步骤处理不同PR状态,存在大量重复代码。可以通过动态环境变量+单发送步骤的方式重构:

核心思路

将不同状态的差异化参数(颜色、图标、时间、操作人等)通过条件表达式定义在环境变量中,然后在统一的Slack发送步骤里引用这些变量,实现代码复用。

优化后的完整脚本

name: Pull Request Notice
on:
  pull_request:
    types: [opened, closed]
    branches: ['main']
  issue_comment:
    types: [created]
  workflow_dispatch:

jobs:
  pr_notification:
    runs-on: ubuntu-latest
    env:
      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
      SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
      # 动态设置通知颜色
      NOTIFICATION_COLOR: >-
        ${{ 
          github.event_name == 'pull_request' && github.event.action == 'opened' ? '#36a64f' :
          github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged ? '#8250df' :
          github.event_name == 'issue_comment' && github.event.issue.pull_request && github.event.issue.state == 'closed' && github.event.issue.pull_request.merged ? '#8250df' :
          '#cf222e'
        }}
      # 动态设置标题图标与状态文本
      NOTIFICATION_HEADER: >-
        ${{ 
          github.event_name == 'pull_request' && github.event.action == 'opened' ? ':recycle: PR Opened: ' :
          github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged ? ':scorpius: PR Merged: ' :
          github.event_name == 'issue_comment' && github.event.issue.pull_request && github.event.issue.state == 'closed' && github.event.issue.pull_request.merged ? ':scorpius: PR Merged: ' :
          ':x: PR Closed: '
        }}
      # 统一PR核心字段(兼容不同触发事件的路径差异)
      PR_TITLE: ${{ github.event.pull_request.title || github.event.issue.title }}
      PR_URL: ${{ github.event.pull_request.html_url || github.event.issue.html_url }}
      PR_BRANCH: ${{ github.event.pull_request.head.ref || github.head_ref || github.ref_name }}
      # 动态设置时间戳
      TIMESTAMP: >-
        ${{ 
          github.event_name == 'pull_request' && github.event.action == 'opened' ? github.event.pull_request.created_at :
          github.event_name == 'pull_request' && github.event.action == 'closed' ? github.event.pull_request.closed_at :
          github.event.issue.closed_at
        }}
      # 动态设置操作人
      ACTOR: >-
        ${{ 
          github.event_name == 'pull_request' && github.event.action == 'opened' ? github.event.pull_request.user.login :
          github.event_name == 'pull_request' && github.event.action == 'closed' ? github.event.pull_request.merged_by.login :
          github.event.comment.user.login
        }}
      # 处理空内容的正文
      CONTENT_BODY: ${{ toJson(coalesce(github.event.pull_request.body, github.event.comment.body, 'N/A')) }}
      # 动态设置内容标题(Message/Comment)
      CONTENT_LABEL: ${{ github.event_name == 'pull_request' && github.event.action == 'opened' ? 'Message' : 'Comment' }}

    steps:
      - name: Send PR Notification to Slack
        uses: slackapi/slack-github-action@v1.21.0
        if: >-
          (github.event_name == 'pull_request') ||
          (github.event_name == 'issue_comment' && github.event.issue.pull_request)
        with:
          payload: |
            {
              "attachments": [
                {
                  "color": "${{ env.NOTIFICATION_COLOR }}",
                  "blocks": [
                    {
                      "type": "header",
                      "text": {
                        "type": "plain_text",
                        "text": "${{ env.NOTIFICATION_HEADER }} ${{ github.event.repository.name }}"
                      }
                    },
                    {
                      "type": "context",
                      "elements": [
                        {
                          "text": "*${{ env.TIMESTAMP }}*  |  ${{ env.NOTIFICATION_HEADER == ':recycle: PR Opened: ' && 'Opened by' || env.NOTIFICATION_HEADER == ':scorpius: PR Merged: ' && 'Merged by' || 'Closed by' }}: ${{ env.ACTOR }}",
                          "type": "mrkdwn"
                        }
                      ]
                    },
                    {
                      "type": "divider"
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*${{ env.PR_TITLE }}*\n${{ env.PR_URL }}"
                      }
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*Branch:* `${{ env.PR_BRANCH }}`"
                      }
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": "*${{ env.CONTENT_LABEL }}:*"
                      }
                    },
                    {
                      "type": "section",
                      "text": {
                        "type": "mrkdwn",
                        "text": ${{ env.CONTENT_BODY }}
                      }
                    }
                  ]
                }
              ]
            }

优化点说明

  1. 合并重复步骤:将原有的3个发送步骤合并为1个,通过环境变量动态适配不同PR状态
  2. 兼容多触发场景:统一处理pull_request(打开、合并、关闭)和issue_comment触发的通知逻辑
  3. 空值全局处理:通过coalesce+toJson确保所有文本字段不会为空,避免JSON语法错误
  4. 逻辑更严谨:修正了原脚本中合并状态判断的不准确问题,明确区分合并关闭与直接关闭的场景

内容的提问来源于stack exchange,提问作者kenfai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 07:45:32