We're using several sets of parallel steps to speed up deployments. We're using environment in every step that doesn't have a deployment so it has all of the relevant environment variables. If someone merges to the development branch a deployment kicks off. If something else is then merged, another deployment of the development branch kicks off and we end up with failures in one or more of the deployment steps.
We would like to prevent multiple concurrent deployments of the same branch but we have not been able to find a good way of doing that because of our usage of parallel steps.
Is there a way to block a branch deployment when a deployment of that branch is already in progress?
Before answering, take the following into consideration:
The actual pipeline file is a little over 600 lines long but here is a highly truncated example of what we're currently doing:
image: atlassian/default-image:5
options:
max-time: 60 # Set a maximum time limit for the pipeline to run
definitions:
steps:
- step: &configure-deployment
- step: &deploy-something-to-cf
- step: &check-base-backend
- step: &check-backend
- step: &check-foo
- step: &check-bar
- step: &build-backend
- step: &build-healthcheck
- step: &build-frontend
- step: &app-upload
- step: &app-deploy
- step: &foo-upload
- step: &foo-deploy
- step: &deploy-bar
pipelines:
branches:
development:
- step:
<<: *configure-deployment
deployment: qa
- parallel:
name: Check for Changes
fail-fast: true
steps:
- step:
<<: *check-base-backend
environment: qa
- step:
<<: *check-backend
environment: qa
- step:
<<: *check-foo
environment: qa
- step:
<<: *check-bar
environment: qa
- parallel:
name: Build and Deploy Frontend/Images
fail-fast: true
steps:
- step:
<<: *build-backend
environment: qa
- step:
<<: *build-healthcheck
environment: qa
- step:
<<: *build-frontend
environment: qa
- parallel:
name: Upload Artifacts
fail-fast: true
steps:
- step:
<<: *app-upload
environment: qa
- step:
<<: *foo-upload
environment: qa
- parallel:
name: Deploy to Environments
fail-fast: false # Don't leave deployment in failed or unknown state
steps:
- step:
<<: *deploy-something-to-cf
environment: qa
- step:
<<: *app-deploy
environment: qa
- step:
<<: *foo-deploy
environment: qa
- step:
<<: *deploy-bar
environment: qa
release:
- step:
<<: *configure-deployment
deployment: staging
- parallel:
name: Check for Changes
fail-fast: true
steps:
- step:
<<: *check-base-backend
environment: staging
- step:
<<: *check-backend
environment: staging
- step:
<<: *check-foo
environment: staging
- step:
<<: *check-bar
environment: staging
- parallel:
name: Build and Deploy Images
fail-fast: true
steps:
- step:
<<: *build-backend
environment: staging
- step:
<<: *build-healthcheck
environment: staging
- step:
<<: *build-frontend
environment: staging
- parallel:
name: Upload Artifacts
fail-fast: true
steps:
- step:
<<: *app-upload
environment: staging
- step:
<<: *foo-upload
environment: staging
- parallel:
name: Deploy to Environments
fail-fast: false # Don't leave deployment in failed or unknown state
steps:
- step:
<<: *deploy-something-to-cf
environment: staging
- step:
<<: *app-deploy
environment: staging
- step:
<<: *foo-deploy
environment: staging
- step:
<<: *deploy-bar
environment: staging
image:
<<: *deploy-bar-image
name: <ECR URL>
aws:
<<: *deploy-bar-image-aws
oidc-role: <ARN>
main:
...