Scrolling through the build log to find what caused your CI pipeline to fail isn’t fun. Or even spending hours inventing custom logic to automate workflows based on who triggered a build or what files changed? There might be a better solution.
Enhanced Environment Variables have recently arrived – a suite of new variables designed to give you better control over Bitrise CI.
Unlocking new workflows with enhanced environment variables
Here's a summary of all the new environment variables available in Bitrise:
Sometimes your CI workflows require more intelligent automation and better debugging capabilities. These nifty additions to Bitrise give mobile development and DevOps teams the contextual information needed to create more thoughtful, efficient workflows. Let’s dive into each of these and see some real-world examples of where they can be used.
👩🚒 Build failure diagnostics
When a build fails, the traditional approach involves combing through verbose logs to pinpoint exactly what went wrong. The new failure diagnostics variables can speed this up a little bit.
Example 1: Smart Slack notifications
Instead of generic "build failed" notifications, send Slack messages with precise information about what went wrong. Notice the usage of new variables in the Slack message step:
1workflows:
2 run_tests:
3 steps:
4 - git-clone@8: {}
5 - xcode-test@6:
6 inputs:
7 - project_path: "$BITRISE_PROJECT_PATH"
8 - scheme: "$BITRISE_SCHEME"
9 - destination: platform=iOS Simulator,name=Bitrise iOS default,OS=9.1
10 - deploy-to-bitrise-io@2: {}
11 - slack@4:
12 run_if: "{{.IsBuildFailed}}"
13 inputs:
14 - workspace_slack_integration_id: "$SLACK_INTEGRATION_ID"
15 - text: |-
16 Failing step: $BITRISE_FAILED_STEP_TITLE
17 Error: $BITRISE_FAILED_STEP_ERROR_MESSAGE
Below is the Slack message when the above build fails:

Example 2: Team-specific failure routing
Different failures might require attention from different teams. Route notifications based on which step failed: In this example, the workflow notifies iOS devs about Xcode test failures and platform engineers about other build failures. Notice the run_if
conditions in the Slack message steps.
1workflows:
2 run_tests:
3 steps:
4 - git-clone@8: {}
5 - xcode-test@6:
6 inputs:
7 - project_path: "$BITRISE_PROJECT_PATH"
8 - scheme: "$BITRISE_SCHEME"
9 - destination: platform=iOS Simulator,name=Bitrise iOS default,OS=9.1
10 - deploy-to-bitrise-io@2: {}
11 - slack@4:
12 run_if: "{{enveq \"BITRISE_FAILED_STEP_TITLE\" \"Xcode Test for iOS\"}}"
13 inputs:
14 - workspace_slack_integration_id: "$IOS_DEVS_SLACK_INTEGRATION_ID"
15 - text: |-
16 Xcode Test for iOS has failed with error:
17 $BITRISE_FAILED_STEP_ERROR_MESSAGE
18 - slack@4:
19 run_if: "{{enveq \"BITRISE_FAILED_STEP_TITLE\" \"Xcode Test for iOS\" | not}}"
20 inputs:
21 - workspace_slack_integration_id: "$PLATFROM_ENGINEERS_SLACK_INTEGRATION_ID"
22 - text: |-
23 $BITRISE_FAILED_STEP_TITLE has failed with error:
24 $BITRISE_FAILED_STEP_ERROR_MESSAGE
Xcode test failure Slack message (sent to $IOS_DEVS_SLACK_INTEGRATION_ID
):


🚀 Build trigger information
Build trigger variables help you understand the origin of each build, enabling you to create trigger-aware workflows:
Example 1 - Elevated security for third-party contributors
This workflow runs extensive security scans for external contributors and standard scans for internal team members based on the email domain in BITRISE_TRIGGER_BY
.
1workflows:
2 primary:
3 steps:
4 - git-clone@8: {}
5 - script@1:
6 inputs:
7 - content: |-
8 #!/bin/bash
9 # Run extended security scans for external contributors
10 if [[ "$BITRISE_TRIGGER_BY" != *"@yourcompany.com"* ]]; then
11 envman add --key SECURITY_SCAN_LEVEL --value "extensive"
12 else
13 envman add --key SECURITY_SCAN_LEVEL --value "standard"
14 fi
15 - dependency-security-scan@0:
16 inputs:
17 - scan_level: "$SECURITY_SCAN_LEVEL"
Example 2 - Audit trail for production deployments
This workflow deploys an app to the App Store while maintaining an audit trail of who triggered the deployment and when, storing these records in Google Cloud Storage.
1workflows:
2 production_deploy:
3 steps:
4 - git-clone@8: {}
5 - script@1:
6 inputs:
7 - content: |-
8 #!/bin/bash
9 echo "Production deployment triggered by: $BITRISE_TRIGGER_BY at $(date)" >> deployment_audit.log
10 echo "Trigger method: $BITRISE_TRIGGER_METHOD" >> deployment_audit.log
11 - google-cloud-storage-upload@1:
12 inputs:
13 - source_path: "deployment_audit.log"
14 - bucket_url: "gs://your-company-audit-logs/"
15 - deploy-to-itunesconnect-application-loader@1: {}
Example 3 - Leaner scheduled builds
Conserve resources during automated scheduled builds by skipping resource-intensive steps:
1workflows:
2 nightly_build:
3 steps:
4 - git-clone@8: {}
5 - script@1:
6 inputs:
7 - content: |-
8 #!/bin/bash
9 if [[ "$BITRISE_TRIGGER_METHOD" == "schedule" ]]; then
10 # Skip resource-intensive UI tests on scheduled builds
11 envman add --key SKIP_UI_TESTS --value "true"
12 # Use lower simulator spec for overnight builds
13 envman add --key SIMULATOR_DEVICE --value "iPhone 8"
14 else
15 envman add --key SKIP_UI_TESTS --value "false"
16 envman add --key SIMULATOR_DEVICE --value "iPhone 14 Pro"
17 fi
18 - xcode-test@6:
19 run_if: "{{enveq \"SKIP_UI_TESTS\" \"false\"}}"
20 inputs:
21 - destination: "platform=iOS Simulator,name=$SIMULATOR_DEVICE"
Example 4 - Intelligent notification routing
Send notifications to different channels based on who triggered the build:
1workflows:
2 release_build:
3 steps:
4 - git-clone@8: {}
5 - xcode-archive@4: {}
6 - script@1:
7 inputs:
8 - content: |-
9 #!/bin/bash
10 # Determine who should receive notifications
11 if [[ "$BITRISE_TRIGGER_BY" == "jenkins-automation" ]]; then
12 # CI system triggered this build
13 envman add --key NOTIFY_CHANNEL --value "ci-automation"
14 elif [[ "$BITRISE_TRIGGER_BY" == *"product-manager"* ]]; then
15 # PM triggered this build
16 envman add --key NOTIFY_CHANNEL --value "product-releases"
17 else
18 # Developer triggered this build
19 envman add --key NOTIFY_CHANNEL --value "engineering"
20 fi
21 - slack@4:
22 inputs:
23 - channel: "$NOTIFY_CHANNEL"
24 - text: "Build completed for version $BITRISE_GIT_TAG"
Keep Slack channels focused.
✅ Pull request intelligence
Pull request variables give you insight into PR comments and labels, enabling comment-driven workflows and label-based automation.
Example 1 - Automated PR comment responses
The below example replies to the original PR comment with the results from the build.
1format_version: 11
2default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
3
4workflows:
5 comment_driven_actions:
6 steps:
7 - git-clone@8: {}
8
9 - script@1:
10 title: Process PR Comment Commands
11 inputs:
12 - content: |
13 #!/bin/bash
14 set -e
15
16 echo "PR Comment: $BITRISE_GIT_PULL_REQUEST_COMMENT"
17 echo "Comment ID: $BITRISE_GIT_PULL_REQUEST_COMMENT_ID"
18
19 # Set default action flags
20 RUN_SCREENSHOT_TESTS="false"
21 DEPLOY_TO_TESTFLIGHT="false"
22
23 # Check for specific commands in the comment
24 if [[ "$BITRISE_GIT_PULL_REQUEST_COMMENT" == *"/test-screenshots"* ]]; then
25 echo "Screenshot test command detected"
26 RUN_SCREENSHOT_TESTS="true"
27 fi
28
29 if [[ "$BITRISE_GIT_PULL_REQUEST_COMMENT" == *"/deploy-testflight"* ]]; then
30 echo "TestFlight deployment command detected"
31 DEPLOY_TO_TESTFLIGHT="true"
32 fi
33
34 # Save the comment ID to reply to it later
35 envman add --key REPLY_TO_COMMENT_ID --value "$BITRISE_GIT_PULL_REQUEST_COMMENT_ID"
36 envman add --key RUN_SCREENSHOT_TESTS --value "$RUN_SCREENSHOT_TESTS"
37 envman add --key DEPLOY_TO_TESTFLIGHT --value "$DEPLOY_TO_TESTFLIGHT"
38
39 - script@1:
40 title: Run Screenshot Tests
41 run_if: '{{enveq "RUN_SCREENSHOT_TESTS" "true"}}'
42 inputs:
43 - content: |
44 #!/bin/bash
45 echo "Running screenshot comparison tests..."
46 # Commands to run screenshot tests
47 mkdir -p screenshots
48 echo "Screenshot results would be generated here" > screenshots/results.txt
49
50 # Create flag file to indicate test was run
51 echo "true" > screenshots_run.txt
52
53 - xcode-archive@4:
54 title: Build for TestFlight
55 run_if: '{{enveq "DEPLOY_TO_TESTFLIGHT" "true"}}'
56 inputs:
57 - export_method: app-store
58
59 - deploy-to-itunesconnect-deliver@2:
60 title: Deploy to TestFlight
61 run_if: '{{enveq "DEPLOY_TO_TESTFLIGHT" "true"}}'
62 inputs:
63 - itunescon_user: "$ITUNES_CONNECT_USER"
64 - password: "$ITUNES_CONNECT_PASSWORD"
65 - app_id: "$IOS_APP_ID"
66 - submit_for_beta_review: "no"
67 - skip_metadata: "yes"
68 - skip_screenshots: "yes"
69
70 - github-status@2:
71 title: Report Status Back to PR
72 inputs:
73 - auth_token: "$GITHUB_TOKEN"
74 - status_identifier: "bitrise-ci"
75 - repository_url: "$GIT_REPOSITORY_URL"
76 - commit_hash: "$GIT_CLONE_COMMIT_HASH"
77
78 - script@1:
79 title: Reply to PR Comment
80 run_if: '{{ne (getenv "REPLY_TO_COMMENT_ID") ""}}'
81 inputs:
82 - content: |
83 #!/bin/bash
84 if [ -n "$GITHUB_TOKEN" ] && [ -n "$REPLY_TO_COMMENT_ID" ]; then
85 # Extract repo info from repository URL (assuming GitHub)
86 REPO_URL=$(echo "$GIT_REPOSITORY_URL" | sed 's/.*github.com[\/:]//g' | sed 's/\.git$//g')
87
88 # Prepare the response message
89 MESSAGE="✅ Command processed!"
90
91 if [ "$RUN_SCREENSHOT_TESTS" == "true" ] && [ -f "screenshots_run.txt" ]; then
92 MESSAGE="$MESSAGE\n\n📸 Screenshot tests completed."
93 fi
94
95 if [ "$DEPLOY_TO_TESTFLIGHT" == "true" ]; then
96 MESSAGE="$MESSAGE\n\n🚀 Deployed to TestFlight."
97 fi
98
99 # Post reply comment via GitHub API
100 curl -X POST \
101 -H "Authorization: token $GITHUB_TOKEN" \
102 -H "Content-Type: application/json" \
103 -d "{\"body\": \"$MESSAGE\"}" \
104 "https://api.github.com/repos/$REPO_URL/issues/comments/$REPLY_TO_COMMENT_ID/replies" || \
105 echo "Unable to post reply comment. This might be because the API doesn't support comment replies or due to permissions."
106 else
107 echo "Missing GitHub token or comment ID, cannot reply to PR comment"
108 fi
How to use the above example:
Comment on your PR with these commands:
/test-screenshots
: Triggers screenshot comparison tests/deploy-testflight
: Builds and deploys the app to TestFlight
The workflow will process these commands and reply to the original comment with the results of the requested actions.
👩🏽💻 Code change awareness
Example 1 - Conditional test execution
Only run certain tests when relevant files change:
1workflows:
2 primary:
3 steps:
4 - git-clone@8: {}
5 - script@1:
6 inputs:
7 - content: |-
8 #!/bin/bash
9 if [[ "$BITRISE_GIT_CHANGED_FILES" == *"/ui/"* ]]; then
10 envman add --key RUN_UI_TESTS --value "true"
11 fi
12 if [[ "$BITRISE_GIT_CHANGED_FILES" == *"/database/"* ]]; then
13 envman add --key RUN_DB_TESTS --value "true"
14 fi
15 - xcode-test@6:
16 run_if: "{{enveq \"RUN_UI_TESTS\" \"true\"}}"
17 inputs:
18 - test_plan: UITests
19 - xcode-test@6:
20 run_if: "{{enveq \"RUN_DB_TESTS\" \"true\"}}"
21 inputs:
22 - test_plan: DatabaseTests
Example 2 - Deploy based on commit messages or labels
Deploy to production only when commit messages or PR labels indicate a release:
1workflows:
2 deploy:
3 steps:
4 - git-clone@8: {}
5 - script@1:
6 inputs:
7 - content: |-
8 #!/bin/bash
9 if [[ "$BITRISE_GIT_COMMIT_MESSAGES" == *"[deploy-prod]"* ]] || [[ "$BITRISE_GIT_PULL_REQUEST_LABELS" == *"production-ready"* ]]; then
10 envman add --key DEPLOY_TARGET --value "production"
11 else
12 envman add --key DEPLOY_TARGET --value "staging"
13 fi
14 - deploy-to-bitrise-io@2: {}
15 - firebase-app-distribution@0:
16 inputs:
17 - app: "$FIREBASE_APP_ID_$DEPLOY_TARGET"
18 - groups: "$FIREBASE_GROUPS_$DEPLOY_TARGET"
Example 3 - Trigger security scans for sensitive changes
Run security scans only when critical files change:
1workflows:
2 build:
3 steps:
4 - git-clone@8: {}
5 - script@1:
6 inputs:
7 - content: |-
8 #!/bin/bash
9 if [[ "$BITRISE_GIT_CHANGED_FILES" == *"Podfile"* ]] || [[ "$BITRISE_GIT_CHANGED_FILES" == *"Gemfile"* ]]; then
10 envman add --key RUN_SECURITY_SCAN --value "true"
11 fi
12 - dependency-security-scan@0:
13 run_if: "{{enveq \"RUN_SECURITY_SCAN\" \"true\"}}"
Level up your Bitrise CI
These new environment variables are another step on the journey to making Bitrise unrivalled as the most intelligent, innovative, and developer-friendly mobile CI/CD platform. By providing rich contextual information about builds, failures, triggers, and code changes, you can create more efficient, targeted, and automated workflows.
We're excited to see how you'll use these new variables to streamline your mobile CI/CD workflows. Questions or creative use cases? Reach out to our support team or drop a message on our socials!
Happy building!