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

Azure Pipelines手动验证任务无法通知外部邮箱的解决方案咨询

问题:Azure Pipelines ManualValidation@0 无法通知外部用户

我当前使用以下YAML代码从Redmine提取项目成员邮箱,在Azure Pipelines中添加ManualValidation@0任务发送审批通知:

- stage: approval
  jobs:
  - job: memberlist
    pool: 
      name: Azure Pipelines
      vmImage: 'windows-2019'   
    steps:
      - task: PowerShell@2
        inputs:
          targetType: 'inline'
          script: |
            try {
              $redmineUrl = "http://redmine/projects/${env:REDMINEPROJECTID}/memberships.json?key={key}&limit=100&Content-Type=application/json"
              Write-Host $redmineUrl
              $response = Invoke-RestMethod -Uri $redmineUrl -Method Get
              $redmineData = $response | ConvertTo-Json -Depth 100 | ConvertFrom-Json 
              # Write-Host $redmineData
              $filteredUsers = $redmineData.memberships | Where-Object {
                # dev members
                  $_.roles.id -contains 4 -or
                  $_.roles.id -contains 9 -or
                  $_.roles.id -contains 14 -or
                  $_.roles.id -contains 17 #-or
                  # PM members
                  # $_.roles.id -contains 3 -or
                  # architect members
                  # $_.roles.id -contains 16 -or
                  # $_.roles.id -contains 25 
              }
              $userIDs = $filteredUsers.user.id
              $emailAddresses = @()
              Write-Host $userIDs
              foreach ($userID in $userIDs) {
                $userUrl = "http://redmine/users/${userID}.json?key=946b8ee19b89bbe02b3ffd140eed83acd90b9724"
                $userDetails = Invoke-RestMethod -Uri $userUrl -Method Get
                $userData = $userDetails | ConvertTo-Json -Depth 100 | ConvertFrom-Json
                $userEmail = $userData.user.mail
                $emailAddresses += $userEmail
              }
              Write-Host $emailAddresses
              $emailAddressesString = $emailAddresses -join ";"
              Write-Host $emailAddressesString
              Write-Host "##vso[task.setvariable variable=DevMembers;isOutput=true]$emailAddresses"
              # Write-Output "##vso[task.setvariable variable=deploymentCounter;isOutput=true]1"
              
            }catch {
                Write-Host "Error: $_"
            }
        name: ProjectmembersDev
  - job: waitForValidation
    dependsOn: memberlist
    displayName: Wait for Approval  
    pool: server    
    timeoutInMinutes: 4320
    variables:
      DevStageVar: $[dependencies.memberlist.outputs['ProjectmembersDev.DevMembers']]
    steps: 
      - task: ManualValidation@0
        timeoutInMinutes: 1440 
        inputs:
          notifyUsers: |
            $(DevStageVar)
            name1@email.com
            name2@email.com
            name3@email.com   
          instructions: 'Please validate the build configuration and resume'
          onTimeout: 'reject'
        condition: and(succeeded(), ne(variables['DevStageVar'], ''))
        name: validation

当前组织内成员能正常收到审批邮件,但不在Azure组织中的外部用户无法收到通知,需要可行的解决办法。


解决方案

核心原因

Azure Pipelines的ManualValidation@0任务仅支持通知Azure AD组织内的正式成员,或已受邀加入组织的来宾用户,未加入组织的外部用户无法通过该任务的内置通知机制收到邮件。

方案1:将外部用户添加为Azure AD来宾用户

这是最直接的官方解决方案:

  • 操作步骤:
    1. 登录Azure Portal,进入Azure Active Directory → 用户
    2. 点击新建来宾用户,输入外部用户的邮箱地址,发送邀请链接
    3. 外部用户接受邀请后,即可作为来宾用户加入Azure组织
    4. 此时ManualValidation@0的notifyUsers字段中填写该用户邮箱,就能正常发送通知
  • 注意:需要Azure AD管理员权限,且用户必须接受邀请才能生效

方案2:自定义邮件通知(替代内置通知)

如果无法添加来宾用户,可以通过PowerShell任务自行发送邮件,配合ManualValidation的等待逻辑:

  1. 修改现有PowerShell任务,将收集到的邮箱用分号连接后输出变量(修正原代码的小问题):
    # 原代码中修改变量设置行:
    $emailAddressesString = $emailAddresses -join ";"
    Write-Host "##vso[task.setvariable variable=DevMembers;isOutput=true]$emailAddressesString"
    
  2. 在memberlist job中添加一个PowerShell任务,用SMTP发送自定义审批邮件:
    $smtpServer = "smtp.yourdomain.com" # 替换为你的SMTP服务器地址
    $smtpPort = 587 # 对应SMTP端口,通常是587或465
    $smtpUser = "your-service-email@domain.com" # 发件人邮箱
    $smtpPassword = "your-app-password-or-credentials" # 发件人密码(建议用应用密码)
    
    # 获取审批链接
    $approvalLink = "$(System.CollectionUri)$(System.TeamProject)/_build/results?buildId=$(Build.BuildId)"
    # 拼接收件人列表
    $toList = "$(DevStageVar);name1@email.com;name2@email.com;name3@email.com" -split ";" | Where-Object { $_ }
    
    $subject = "Azure Pipelines 构建审批请求"
    $body = @"
    <h3>需要您的审批确认</h3>
    <p>构建编号:$(Build.BuildId)</p>
    <p>请点击下方链接完成审批:</p>
    <a href='$approvalLink'>立即审批</a>
    <p>审批说明:请验证构建配置并恢复流程</p>
    "@
    
    # 发送邮件
    Send-MailMessage -From $smtpUser `
                     -To $toList `
                     -Subject $subject `
                     -Body $body `
                     -BodyAsHtml `
                     -SmtpServer $smtpServer `
                     -Port $smtpPort `
                     -UseSsl `
                     -Credential (New-Object System.Management.Automation.PSCredential ($smtpUser, (ConvertTo-SecureString $smtpPassword -AsPlainText -Force)))
    
  3. 保留ManualValidation@0任务,可将notifyUsers设置为组织内用户作为 fallback,或者留空,主要依赖自定义邮件通知外部用户

方案3:使用Azure Logic Apps触发邮件通知

通过Azure Logic Apps实现邮件发送,无需修改Pipeline内的代码逻辑:

  • 操作步骤:
    1. 在Azure Portal创建Logic App,选择触发器为当Azure DevOps事件发生,筛选事件类型为ManualValidation相关的审批事件
    2. 添加发送邮件动作(比如Office 365 Outlook或第三方邮件连接器),配置收件人为收集到的外部邮箱列表
    3. 在Pipeline的memberlist job中添加一个HTTP任务,调用Logic App的触发URL,传递审批链接、邮箱列表等参数
  • 优势:无需在Pipeline中维护SMTP配置,适合企业级场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 06:25:02