Is it possible to run tasks/scripts within a job before a deployment job runs?
Yes
I have an approval on the environment, which I want triggered by the deployment job, but it seems to want the approval before it runs job1 instead of running the tasks within job1 and then asking for approval before running the deployment job.
If I understand correctly, you (like me) want to prepare a build and have a human interact with the pipeline to give the go-nogo to the rest of the pipeline which is the deployment to an environment.
What I do not recommend for the above scenario
If that's the case, then I have to say that you need two different pipelines.
- would create the build for the environment, without attaching the environment to the build. Publish this artifact
- Pick the artifact from No.1 and then have a deployment with the specific environment.
the environmental approval has to be done in a different pipeline where you pick up the artifact from the first build.
What I do recommend for the above scenario
The following part is using multiple stages. Dev, staging and prd.
Dev environment does not need a validation but other two needs. So, in my case of dev, while on job waitForValidation I am checking if the previous build was successful and if the stage is not development. If it is, then it bypasses the job and goes directly to the nest job, deployment.
In case the waitForValidation job is not bypassed, a validation is needed to continue further with the pipeline.
In job deployment, there are two ifs probably out of your scope of the question but good to have in case someone else sees that in the future:
- If stage is development and if build job is successful, then continue with build
- if stage is not development and if job
waitForValidation was successful
then continue with build.
parameters:
- name: 'stages'
type: object
default:
- stage: Development
dependsOn:
- stage: Staging
dependsOn: 'Development'
- stage: Production
dependsOn: 'Staging'
stages:
- ${{each stage in parameters.stages}}:
- stage: ${{ stage.stage }}
dependsOn: ${{ stage.dependsOn }}
displayName: ${{ stage.stage }}
pool:
vmImage: $(vmImageName)
jobs:
- job: Build
displayName: Build for ${{ stage.stage }}
steps:
- script: |
... <code/steps/jobs goes here>
- publish: $(Build.ArtifactStagingDirectory)
artifact: '${{ stage.stage }}.$(ArtifactName)'
- ${{ if ne(stage.stage, 'Development') }}:
- job: waitForValidation
displayName: 'Validation to Deploy $(ArtifactName) to ${{ stage.stage }} - $(ArtifactName), ${{variables.ArtifactName}}, and $[ ArtifactName ]'
condition: and(succeeded(), ne('${{ stage.stage }}', 'Development'))
dependsOn: 'Build'
pool: server
timeoutInMinutes: 43200 # job times out in 30 days
steps:
- task: ManualValidation@0
timeoutInMinutes: 1 # task times out in 1 day
inputs:
notifyUsers:
instructions: 'Please validate the build configuration and resume'
onTimeout: reject
- deployment: ${{ stage.stage }}
displayName: Deploy to ${{ stage.stage }}
environment: ${{ stage.stage }}
${{ if eq('${{ stage.stage }}', 'Development') }}:
dependsOn: 'Build'
condition: and(eq(dependencies.Build.result,'Succeeded'), ne(variables['Build.Reason'], 'PullRequest'))
${{ if ne('${{ stage.stage }}', 'Development') }}:
dependsOn: 'waitForValidation'
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
strategy:
runOnce:
deploy:
steps:
- task: Bash@3
inputs:
targetType: 'inline'
script: |
<rest of deployment>
I hope I am in par with your questions.