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

如何在Azure Pipeline单阶段中选择运行QA/DEV环境

Azure DevOps流水线:单阶段手动选择运行QA/DEV环境

我在Azure DevOps中维护一条流水线,当前会同时构建QA和DEV两个环境的镜像。需求是手动触发流水线时,能选择仅运行其中一个环境的构建,并且只通过单个阶段实现,不需要拆分出独立的QA、DEV阶段。之前尝试用条件判断配置,但没达到预期效果,当前阶段代码如下:

# BUILD ENVIRONMENTS
- stage: build_envs
  dependsOn: quality_control
  displayName: Build Envs
  condition: |
   or 
    (
      and(eq(variables.isQa, true), ne(variables['Build.Reason'], 'PullRequest')),  eq(variables['Build.Reason'], 'Manual'),
      and(eq(variables.isDev, true), ne(variables['Build.Reason'], 'PullRequest')),  eq(variables['Build.Reason'], 'Manual')
    )
  jobs:
  - job: Job_build 
    displayName:  Application Build
    steps:
    - ${{ if eq(variables.isQa, true) }}:
      - checkout: backend-qa
        path: enext-data-platform-backend
      - script: rm -rf enext-data-platform-backend/enext-data-platform-frontend
      - checkout: frontend-qa
        path: enext-data-platform-backend/enext-data-platform-frontend
          #submodules: true
      - script: |
          ls -la $(Pipeline.Workspace)/enext-data-platform-backend
          ls -la $(Pipeline.Workspace)/enext-data-platform-backend/enext-data-platform-frontend
      - powershell: |
          Write-Host "##vso[build.addbuildtag]qa"
      #displayName: Application Build DEV
    - ${{ elseif eq(variables.isDev, true) }}:
      - checkout: backend-dev
        submodules: true
      - script: git rev-parse HEAD
      - script: ls -la   
      - powershell: |
          Write-Host "##vso[build.addbuildtag]dev"
      #displayName: 'Build Tag'

    - task: npmAuthenticate@0
      displayName: npm Authenticate enext-data-platform-backend/.npmrc
      inputs:
        ${{ if eq(variables.isQa, true) }}:
          workingFile: $(Pipeline.Workspace)/enext-data-platform-backend/.npmrc
        ${{ elseif eq(variables.isDev, true) }}:
          workingFile: .npmrc
      

    - task: npmAuthenticate@0
      displayName: npm Authenticate enext-data-platform-backend/enext-data-platform-frontend/.npmrc
      inputs:
        ${{ if eq(variables.isQa, true) }}:
          workingFile: $(Pipeline.Workspace)/enext-data-platform-backend/enext-data-platform-frontend/.npmrc
        ${{ elseif eq(variables.isDev, true) }}:
          workingFile: enext-data-platform-frontend/.npmrc
    
    - task: Docker@0
      displayName: 'Build an image'
      inputs:
        command: 'buildAndPush'
        containerregistrytype: 'Container Registry'
        imageName: "$(Build.Repository.Name):$(Build.BuildId)"
        ${{ if eq(variables.isQa, true) }}: 
          buildContext: $(Pipeline.Workspace)/enext-data-platform-backend/
          Dockerfile: $(Pipeline.Workspace)/enext-data-platform-backend/Dockerfile
        ${{ elseif eq(variables.isDev, true) }}:
          buildContext: enext-data-platform-backend
          Dockerfile: 'Dockerfile'

    - script: |
        set -x
        env
        pwd
        echo "CONTAINER_APP=$(Build.Repository.Name):$(Build.BuildId)" > artifact.txt
        source ./artifact.txt
        docker save $CONTAINER_APP > container.tar
        ls -la
      displayName: 'Shell Script: APP'

    - task: PublishPipelineArtifact@1
      displayName: 'Publish Pipeline Artifact - container id'
      inputs:
        targetPath: artifact.txt
        artifact: artifact

    - task: PublishPipelineArtifact@1
      displayName: 'Publish Pipeline Artifact - container data'
      inputs:
        targetPath: container.tar
        artifact: container

    - task: Docker@0
      displayName: 'Build an image'
      inputs:
        command: 'buildAndPush'
        containerregistrytype: 'Container Registry'
        imageName: "$(Build.Repository.Name):$(Build.BuildId)"
        ${{ if eq(variables.isQa, true) }}: 
          buildContext: $(Pipeline.Workspace)/enext-data-platform-backend/
          Dockerfile: $(Pipeline.Workspace)/enext-data-platform-backend/Dockerfile
        ${{ elseif eq(variables.isDev, true) }}:
          buildContext: enext-data-platform-backend
          Dockerfile: 'Dockerfile'

    - script: | 
        echo "CONTAINER_KNEX=$(Build.Repository.Name):$(Build.BuildId)" > artifact-knex.txt
        source ./artifact-knex.txt
        docker save $CONTAINER_KNEX > container-knex.tar
        ls -la 
      displayName: 'Shell Script: knex'

    - task: PublishPipelineArtifact@1
      displayName: 'Publish Pipeline Artifact - container id: knex'
      inputs:
        targetPath: artifact-knex.txt
        artifact: artifact-knex
    - task: PublishPipelineArtifact@1
      displayName: 'Publish Pipeline Artifact - container data: knex'
      inputs:
        targetPath: container-knex.tar
        artifact: container-knex 

  - job: dbschema
    displayName:  DB Schema
    steps:
    - checkout: dbschema
      submodules: true
    - script: ls -la

    - task: Docker@0
      displayName: 'Build an image'
      inputs:
        command: 'buildAndPush'
        buildContext: enext-matflow-dbschema
        containerregistrytype: 'Container Registry'
        imageName: "$(Build.Repository.Name):$(Build.BuildId)"
        Dockerfile: 'Dockerfile'

    - script: |
        echo "CONTAINER_DB=$(Build.Repository.Name):$(Build.BuildId)" > sql_artifact.txt
        source ./sql_artifact.txt
        docker save $CONTAINER_DB > sql_container.tar
        ls -la
      displayName: 'Shell Script: DB'
    
    - task: PublishPipelineArtifact@1
      displayName: 'Publish Pipeline Artifact - sql container id'
      inputs:
        targetPath: sql_artifact.txt
        artifact: sql_artifact

    - task: PublishPipelineArtifact@1
      displayName: 'Publish Pipeline Artifact - sql container data'
      inputs:
        targetPath: sql_container.tar
        artifact: sql_container

当前问题:流水线运行时会同时触发QA和DEV环境的构建,希望实现手动触发时能通过下拉选择指定环境(界面效果为:触发流水线时弹出选项框,可选择QA或DEV)。


解决方案步骤

1. 添加运行时参数

在yaml最顶部添加参数,让用户手动选择目标环境:

parameters:
- name: targetEnvironment
  type: string
  default: 'QA'
  values:
  - 'QA'
  - 'DEV'
  displayName: '选择要构建的环境'

2. 修正阶段条件

替换原有的condition,确保仅在手动触发时运行,且匹配选择的环境:

condition: and(eq(variables['Build.Reason'], 'Manual'), in('${{ parameters.targetEnvironment }}', 'QA', 'DEV'))

3. 替换变量判断逻辑

把所有eq(variables.isQa, true)和eq(variables.isDev, true)替换为参数判断:

  • QA环境判断:${{ eq(parameters.targetEnvironment, 'QA') }}
  • DEV环境判断:${{ eq(parameters.targetEnvironment, 'DEV') }}

修改后的完整代码

parameters:
- name: targetEnvironment
  type: string
  default: 'QA'
  values:
  - 'QA'
  - 'DEV'
  displayName: '选择要构建的环境'

# BUILD ENVIRONMENTS
- stage: build_envs
  dependsOn: quality_control
  displayName: Build Envs
  condition: and(eq(variables['Build.Reason'], 'Manual'), in('${{ parameters.targetEnvironment }}', 'QA', 'DEV'))
  jobs:
  - job: Job_build 
    displayName:  Application Build
    steps:
    - ${{ if eq(parameters.targetEnvironment, 'QA') }}:
      - checkout: backend-qa
        path: enext-data-platform-backend
      - script: rm -rf enext-data-platform-backend/enext-data-platform-frontend
      - checkout: frontend-qa
        path: enext-data-platform-backend/enext-data-platform-frontend
          #submodules: true
      - script: |
          ls -la $(Pipeline.Workspace)/enext-data-platform-backend
          ls -la $(Pipeline.Workspace)/enext-data-platform-backend/enext-data-platform-frontend
      - powershell: |
          Write-Host "##vso[build.addbuildtag]qa"
    - ${{ elseif eq(parameters.targetEnvironment, 'DEV') }}:
      - checkout: backend-dev
        submodules: true
      - script: git rev-parse HEAD
      - script: ls -la   
      - powershell: |
          Write-Host "##vso[build.addbuildtag]dev"

    - task: npmAuthenticate@0
      displayName: npm Authenticate enext-data-platform-backend/.npmrc
      inputs:
        ${{ if eq(parameters.targetEnvironment, 'QA') }}:
          workingFile: $(Pipeline.Workspace)/enext-data-platform-backend/.npmrc
        ${{ elseif eq(parameters.targetEnvironment, 'DEV') }}:
          workingFile: .npmrc
      

    - task: npmAuthenticate@0
      displayName: npm Authenticate enext-data-platform-backend/enext-data-platform-frontend/.npmrc
      inputs:
        ${{ if eq(parameters.targetEnvironment, 'QA') }}:
          workingFile: $(Pipeline.Workspace)/enext-data-platform-backend/enext-data-platform-frontend/.npmrc
        ${{ elseif eq(parameters.targetEnvironment, 'DEV') }}:
          workingFile: enext-data-platform-frontend/.npmrc
    
    - task: Docker@0
      displayName: 'Build an image'
      inputs:
        command: 'buildAndPush'
        containerregistrytype: 'Container Registry'
        imageName: "$(Build.Repository.Name):$(Build.BuildId)"
        ${{ if eq(parameters.targetEnvironment, 'QA') }}: 
          buildContext: $(Pipeline.Workspace)/enext-data-platform-backend/
          Dockerfile: $(Pipeline.Workspace)/enext-data-platform-backend/Dockerfile
        ${{ elseif eq(parameters.targetEnvironment, 'DEV') }}:
          buildContext: enext-data-platform-backend
          Dockerfile: 'Dockerfile'

    - script: |
        set -x
        env
        pwd
        echo "CONTAINER_APP=$(Build.Repository.Name):$(Build.BuildId)" > artifact.txt
        source ./artifact.txt
        docker save $CONTAINER_APP > container.tar
        ls -la
      displayName: 'Shell Script: APP'

    - task: PublishPipelineArtifact@1
      displayName: 'Publish Pipeline Artifact - container id'
      inputs:
        targetPath: artifact.txt
        artifact: artifact

    - task: PublishPipelineArtifact@1
      displayName: 'Publish Pipeline Artifact - container data'
      inputs:
        targetPath: container.tar
        artifact: container

    - task: Docker@0
      displayName: 'Build an image'
      inputs:
        command: 'buildAndPush'
        containerregistrytype: 'Container Registry'
        imageName: "$(Build.Repository.Name):$(Build.BuildId)"
        ${{ if eq(parameters.targetEnvironment, 'QA') }}: 
          buildContext: $(Pipeline.Workspace)/enext-data-platform-backend/
          Dockerfile: $(Pipeline.Workspace)/enext-data-platform-backend/Dockerfile
        ${{ elseif eq(parameters.targetEnvironment, 'DEV') }}:
          buildContext: enext-data-platform-backend
          Dockerfile: 'Dockerfile'

    - script: | 
        echo "CONTAINER_KNEX=$(Build.Repository.Name):$(Build.BuildId)" > artifact-knex.txt
        source ./artifact-knex.txt
        docker save $CONTAINER_KNEX > container-knex.tar
        ls -la 
      displayName: 'Shell Script: knex'

    - task: PublishPipelineArtifact@1
      displayName: 'Publish Pipeline Artifact - container id: knex'
      inputs:
        targetPath: artifact-knex.txt
        artifact: artifact-knex
    - task: PublishPipelineArtifact@1
      displayName: 'Publish Pipeline Artifact - container data: knex'
      inputs:
        targetPath: container-knex.tar
        artifact: container-knex 

  - job: dbschema
    displayName:  DB Schema
    steps:
    - checkout: dbschema
      submodules: true
    - script: ls -la

    - task: Docker@0
      displayName: 'Build an image'
      inputs:
        command: 'buildAndPush'
        buildContext: enext-matflow-dbschema
        containerregistrytype: 'Container Registry'
        imageName: "$(Build.Repository.Name):$(Build.BuildId)"
        Dockerfile: 'Dockerfile'

    - script: |
        echo "CONTAINER_DB=$(Build.Repository.Name):$(Build.BuildId)" > sql_artifact.txt
        source ./sql_artifact.txt
        docker save $CONTAINER_DB > sql_container.tar
        ls -la
      displayName: 'Shell Script: DB'
    
    - task: PublishPipelineArtifact@1
      displayName: 'Publish Pipeline Artifact - sql container id'
      inputs:
        targetPath: sql_artifact.txt
        artifact: sql_artifact

    - task: PublishPipelineArtifact@1
      displayName: 'Publish Pipeline Artifact - sql container data'
      inputs:
        targetPath: sql_container.tar
        artifact: sql_container

效果说明

手动触发流水线时,会出现下拉选项框,可选择QA或DEV,流水线会根据选择的环境执行对应分支的构建步骤,不会同时运行两个环境的任务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 03:37:03