Dynamic step conditions
Dynamic Step Conditions allow steps to be skipped automatically based on variable values at runtime. When a condition evaluates to false, the step is marked as skipped (not failed), and the pipeline continues. This is the primary mechanism for skipping unnecessary work — particularly in monorepos where only changed services need to be built and tested.
構文
- step:
name: My Step
condition:
changesets:
includePaths:
- "path/to/watch/**"Or using variable-based state expressions:
- step:
name: My Step
condition:
state: VARIABLE_NAME == expected_valueCondition Types
1. Variable State Conditions
Evaluate a boolean expression against pipeline output variables using condition: state::
- step:
name: Deploy to Production
condition:
state: DEPLOY_ENABLED == true
script:
- ./deploy.sh productionVariable names in condition: state: are referenced without the $ prefix and values are not quoted -- use DEPLOY_ENABLED == true, not $DEPLOY_ENABLED == "true".
Supported Operators
演算子 | 例 | 説明 |
|---|---|---|
|
| Equality check |
|
| Inequality check |
|
| 指定の値より大きい |
|
| 未満 |
|
| Greater or equal |
|
| Less or equal |
|
| Logical AND |
|
| Logical OR |
|
| Pattern match |
Parentheses for Grouping
condition:
state: (A == true || B == true) && ENABLED == falseComparing to Empty/Unset
condition:
state: SERVICE_CHANGED != "" # Run if variable is set and non-empty
condition:
state: SKIP_TESTS != true # Run unless explicitly skipped2. Changeset Conditions
Run a step only when specific files have changed in the triggering commit:
- step:
name: Test Payment API
condition:
changesets:
includePaths:
- "services/payment-api/**"
script:
- cd services/payment-api && npm testincludePaths Glob Patterns
condition:
changesets:
includePaths:
- "src/**" # Any file under src/
- "package.json" # Specific file
- "**/*.ts" # All TypeScript files anywhere
- "services/api/**" # Subtree of a directoryGlob patterns follow standard gitignore-style matching. Use ** to match any number of path segments.
Multiple Paths (OR logic)
Including multiple paths means the step runs if any of the paths have changed:
condition:
changesets:
includePaths:
- "src/**"
- "package.json"
- "package-lock.json"Combining Variable and Changeset Conditions
Variable expressions and changeset conditions can be combined in a single condition block. When both are present, the step only runs if both conditions are met:
# Step only runs if API files changed AND deploy is enabled
- step:
name: Deploy API
condition:
changesets:
includePaths:
- "services/api/**"
state: DEPLOY_ENABLED == true
script:
- ./deploy.sh apiYou can also use variable-based conditions alone when you need complex logic:
# Pattern: Use change detection step to set variables, then use variable conditions
- step:
name: Detect Changes
script:
- |
if git diff --name-only HEAD~1 | grep -q "^services/api/"; then
echo "API_CHANGED=true" >> $BITBUCKET_PIPELINES_VARIABLES_PATH
fi
output-variables:
- API_CHANGED
- step:
name: Test API
condition:
state: API_CHANGED == true
script:
- cd services/api && npm testStep Behavior When Condition Is False
動作 | 説明 |
|---|---|
Step status | Skipped (shown in UI, not failed) |
Pipeline continues | ✅ Yes — subsequent steps still run |
アーティファクト | Not produced (step didn't run) |
ビルド時間 (分) | Not consumed |
| Not set (consuming steps get empty values) |
If a later step depends on variables set by a conditionally-skipped step, those variables will be empty. Handle this in consuming steps with a fallback check.
Common Patterns
Monorepo Service Isolation
pipelines:
default:
- step:
name: Detect Changed Services
script:
- |
if git diff --name-only HEAD~1 | grep -q "^services/payment/"; then
echo "PAYMENT_CHANGED=true" >> $BITBUCKET_PIPELINES_VARIABLES_PATH
fi
if git diff --name-only HEAD~1 | grep -q "^services/email/"; then
echo "EMAIL_CHANGED=true" >> $BITBUCKET_PIPELINES_VARIABLES_PATH
fi
output-variables:
- PAYMENT_CHANGED
- EMAIL_CHANGED
- parallel:
- step:
name: Build Payment Service
condition:
state: PAYMENT_CHANGED == true
script:
- cd services/payment && npm run build
- step:
name: Build Email Service
condition:
state: EMAIL_CHANGED == true
script:
- cd services/email && npm run buildFeature Flag Gates
- step:
name: Run E2E Tests
condition:
state: RUN_E2E == true
script:
- npm run test:e2eSet RUN_E2E=true as a repository variable when you want E2E tests enabled.
Branch-Based Conditions
- step:
name: Deploy to Production
condition:
state: BITBUCKET_BRANCH == main
deployment: production
script:
- ./deploy.sh productionSecurity Scan Toggle
- step:
name: Security Scan
condition:
state: SKIP_SECURITY_SCAN != true # Run unless explicitly disabled
script:
- npm auditChangeset Conditions on Pull Requests
For pull request pipelines, changeset conditions compare against the target branch (not HEAD~1):
pipelines:
pull-requests:
'**':
- step:
name: Test Changed Services
condition:
changesets:
includePaths:
- "src/**"
script:
- npm testThe step runs only if files under src/ were changed in the PR.
Constraints
制約 | 値 |
|---|---|
Condition expression max length | 2,048 characters |
| 50 paths per condition |
Glob pattern depth | 無制限 |
Changeset detection on first commit | Compares against empty tree (all files match) |
トラブルシューティング
Step always runs despite condition:
Confirm variable is set and has the expected value using
echo $VAR_NAMEin a previous stepCheck for trailing whitespace in variable values
Variable comparisons are string-based:
"true"≠"True"
Step always skips despite changed files:
Verify the glob pattern matches your file paths exactly
Test the pattern with
git diff --name-only HEAD~1locallyOn the first commit to a repo, all files are considered changed
Parallel steps all skip unexpectedly:
If a previous step that sets variables was skipped, its
output-variablesare emptyEnsure the variable-setting step itself has no condition, or its condition will always be met
Related
Variable sharing reference — Pass variables between steps for condition logic
Tutorial 8: Conditional Execution — Hands-on guide
Dynamic pipelines reference — Generate pipelines programmatically when conditions are insufficient
この内容はお役に立ちましたか?