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

求助:Azure DevOps YAML流水线PR构建后Slack通知配置问题

Azure DevOps PR Slack通知流水线实现问题

需求目标

针对目标为main分支的Pull Request(PR),构建完成后执行以下Slack通知逻辑:

  • 若构建成功且所有分支策略、状态检查通过,向指定Slack频道发送通知;
  • 若构建失败或任意分支策略不通过,向PR创建者发送Slack私信;
  • PR活跃期间有新提交或评论被解决时,流水线自动重跑并执行上述逻辑。

当前遇到的具体问题

  • 无法设置正确条件区分成功与失败场景;
  • 无法获取Slack User ID及其他变量填充消息;
  • Slack消息格式无法正常显示;
  • 无法确保流水线仅在除“至少1位审核者批准”外的所有分支策略通过后执行(分支策略为继承而来);
  • 无法添加状态检查的触发条件。

现有流水线YAML代码

trigger:
  - none  # Disable automatic trigger for commits. Trigger only for PRs.

resources:
  repositories:
    - repository: templates
      type: git
      name: Hagerty/azure-pipelines-templates

pr:
  branches:
    include:
      - main  # Only trigger for PRs targeting 'main'

pool:
  vmImage: 'windows-latest'

variables:
  - group: billing_pr_slack_notification  # ADO variable group

stages:
  - stage: BuildAndNotify
    displayName: 'Billing PR Slack Notifications'
    # Ensure this stage runs only after all PR policies succeed
    condition: and(succeeded(), eq(coalesce(variables['System.PullRequest.IsDraft'], false), false), startsWith(variables['Build.SourceBranch'], 'refs/pull/'))
    jobs:
      - job: LogVariables
        displayName: 'Log Pipeline Variables'
        steps:
          - script: |
              echo '=== Debugging Variables ==='
              echo 'AZURE_DEVOPS_ORG: $(AZURE_DEVOPS_ORG)'
              echo 'AZURE_DEVOPS_PROJECT: $(AZURE_DEVOPS_PROJECT)'
              echo 'SLACK_API_URL: $(SLACK_API_URL)'
              echo 'SLACK_BOT_TOKEN: $(SLACK_BOT_TOKEN)'
              echo 'SLACK_CHANNEL: $(SLACK_CHANNEL)'
              echo 'PRODUCT_BILLING_DEV_WEBHOOK_URL: $(PRODUCT_BILLING_DEV_WEBHOOK_URL)'
              echo 'System.PullRequest.IsDraft: $(System.PullRequest.IsDraft)'
              echo 'System.PullRequest.SourceBranch: $(System.PullRequest.SourceBranch)'
              echo 'System.PullRequest.TargetBranch: $(System.PullRequest.TargetBranch)'
            displayName: 'Output Debugging Variables'

      - job: FetchSlackUserID
        displayName: 'Fetch Slack User ID'
        dependsOn: LogVariables
        steps:
          - powershell: |
              $creatorEmail = $env:BUILD_REQUESTEDFOR
              if (-not $creatorEmail) {
                  Write-Host "##vso[task.logissue type=error]The Build.RequestedFor email is empty. Cannot proceed to fetch Slack User ID."
                  exit 1
              }
              $slackToken = "$env:SLACK_BOT_TOKEN"
              $response = Invoke-RestMethod -Uri "https://slack.com/api/users.lookupByEmail?email=$creatorEmail" -Headers @{Authorization="Bearer $slackToken"}

              if ($response.ok -eq $true -and $response.user.id) {
                  $userId = $response.user.id
                  Write-Host "##vso[task.setvariable variable=userId]$userId"
                  Write-Host "Successfully retrieved Slack User ID: $userId"
                  Write-Host "Debug: Slack User ID is $userId"
              } else {
                  Write-Host "Defaulting to Slack channel $env:SLACK_CHANNEL."
                  Write-Host "##vso[task.setvariable variable=userId]$env:SLACK_CHANNEL"
              }
            displayName: 'Fetch Slack User ID'

      - job: SlackNotification
        displayName: 'Send Slack Notifications'
        dependsOn: FetchSlackUserID
        steps:
          # Send a channel notification only on success
          - powershell: |
              $webhookUrl = "$env:PRODUCT_BILLING_DEV_WEBHOOK_URL"
              $createdBy = $env:SYSTEM_PULLREQUEST_CREATEDBY
              $prTitle = $env:SYSTEM_PULLREQUEST_TITLE
              $prDescription = $env:SYSTEM_PULLREQUEST_DESCRIPTION
              $prUrl = $env:SYSTEM_PULLREQUEST_URL

              # Handle unset variables by providing default values
              if (-not $createdBy) { $createdBy = "Unknown User" }
              if (-not $prTitle) { $prTitle = "Untitled PR" }
              if (-not $prDescription) { $prDescription = "No description provided." }
              if (-not $prUrl) { $prUrl = "No link available." }

              $message = @{
                  text = "<@here> [$createdBy] has created a new Pull Request & is ready for Code Review:
**Title**: $prTitle
**Description**: $prDescription
[View PR]($prUrl)"
              } | ConvertTo-Json -Depth 10

              Invoke-RestMethod -Uri $webhookUrl -Method Post -Body $message -ContentType 'application/json'
              Write-Host "Slack channel notification sent successfully."
            displayName: 'Send Slack Notification'
            condition: and(succeeded(), endsWith(variables['System.PullRequest.TargetBranch'], '/main'))

          # Send a direct message only on failure
          - powershell: |
              $gifUrls = @(
                  "https://media.giphy.com/media/Ju7l5y9osyymQ/giphy.gif",
                  "https://media.giphy.com/media/26AHONQ79FdWZhAI0/giphy.gif",
                  "https://media.giphy.com/media/3o6Zt481isNVuQI1l6/giphy.gif"
              )
              $randomGif = $gifUrls | Get-Random
              $slackToken = "$env:SLACK_BOT_TOKEN"
              $userId = "$env:userId"

              $prTitle = $env:SYSTEM_PULLREQUEST_TITLE
              $prUrl = $env:SYSTEM_PULLREQUEST_URL

              # Handle unset variables by providing default values
              if (-not $prTitle) { $prTitle = "Untitled PR" }
              if (-not $prUrl) { $prUrl = "No link available." }

              $message = if ($env:BUILD_STATUS -eq "Failed") {
                  "Your Pull Request **$prTitle** failed to build. Please review your branch.
[View PR]($prUrl)

![Failure GIF]($randomGif)"
              } else {
                  "Your Pull Request **$prTitle** failed the following policy check: $env:BUILD_DEFINITIONNAME. Please review your branch.
[View PR]($prUrl)

![Failure GIF]($randomGif)"
              }

              $body = @{
                  channel = $userId
                  text    = $message
              } | ConvertTo-Json -Depth 10

              Invoke-RestMethod -Uri "https://slack.com/api/chat.postMessage" -Method Post -Headers @{Authorization="Bearer $slackToken"} -Body $body
              Write-Host "Slack DM sent successfully to user $userId."
            displayName: 'Send Slack DM if Build or Policy Fails'
            condition: failed()

参考截图

  • 分支策略配置
  • 状态检查配置
  • Slack消息格式示例

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 16:57:32