I have a pipeline in Azure Devops that runs two Environments, QA and DEV and I need it to select on Azure DevOps which environment to run from a single stage instead of using two separate stages for QA and DEV
Here's the stage code that I'm using for both environments:
# 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
And in Azure DevOps when I run the pipeline looks like this:
And it runs the two environments at the same time, and what I'm trying to do is that I can select on Azure DevOPs which Env to run like this:
As of now I'm trying with conditionals but I'm very lost.
I've been trying with conditionals but I'm really new to Azure and I don't know how to set them in a correct way
The Stages to run
function only displays each - stage
under stages
of a YAML definition. From the YAML definition you shared, it only contained one single stage - stage: build_envs
and ${if}
insertions will not expand one stage into two.
For this, you may consider using ${each}
expression to expand the stage. Please refer to the sample below. Since there are only two environments, you may also consider evaluating the value of an object type of parameter.
parameters:
- name: Envs
type: object
default:
- QA
- DEV
stages:
- stage: quality_control
displayName: Quality Control
jobs:
- job: Job1
steps:
- checkout: none
# BUILD ENVIRONMENTS
- ${{ each env in parameters.Envs }}:
- stage: build_${{ env }}
dependsOn: quality_control
displayName: Build ${{ env }}
condition: eq(variables['Build.Reason'], 'Manual')
jobs:
- job: Job_build
displayName: Application Build
steps:
- ${{ if eq(env, 'QA') }}:
- checkout: backend-qa
path: enext-data-platform-backend
- script: echo ${{ env }}
- ${{ elseif eq(env, 'Dev') }}:
- checkout: backend-dev
submodules: true
- script: echo ${{ env }}
- stage: publish_artifact
displayName: Pulish Artifact
jobs:
- job: Job1
steps:
- checkout: none
Besides, since your pipeline will use either QA
or DEV
environment and the build_envs
stage is only executed when the pipeline is manually triggered, you may consider setting Envs
parameter value at queue time and run different sets of steps accordingly. Here is another sample for your reference.
parameters:
- name: Envs
type: string
default: QA
values:
- QA
- DEV
stages:
- stage: quality_control
displayName: Quality Control
jobs:
- job: Job1
steps:
- checkout: none
# BUILD ENVIRONMENTS
- stage: build_${{ parameters.Envs}}
dependsOn: quality_control
displayName: Build ${{ parameters.Envs }}
condition: eq(variables['Build.Reason'], 'Manual')
jobs:
- job: Job_build
displayName: Application Build
steps:
- ${{ if eq(parameters.Envs, 'QA') }}:
- checkout: backend-qa
path: enext-data-platform-backend
- script: echo ${{ parameters.Envs}}
- ${{ elseif eq(parameters.Envs, 'Dev') }}:
- checkout: backend-dev
submodules: true
- script: echo ${{ parameters.Envs }}