DEV Community

Cover image for Unlock Efficient CI/CD: How YAML Anchors Transform Your Bitrise Setup
Daniel Tavares
Daniel Tavares

Posted on

Unlock Efficient CI/CD: How YAML Anchors Transform Your Bitrise Setup

In the fast-paced world of software development, efficiency is king. Whether you're building mobile apps or managing backend services, streamlining your processes can dramatically improve your productivity and reduce time-to-market. This is where YAML, a straightforward yet powerful configuration language, comes into play, especially when used in conjunction with Bitrise, a leading Continuous Integration and Continuous Deployment (CI/CD) platform designed specifically for mobile app development.

YAML's simplicity and human-readable format make it an ideal choice for configuring complex workflows. When paired with Bitrise, it enables developers to create reusable, easy-to-understand pipelines that automate the build, test, and deployment processes. This synergy not only simplifies the initial setup but also enhances ongoing workflow management, ensuring that updates, adjustments, and scaling are just as efficient as initial configurations.

In this blog post, we'll dive deep into the world of YAML and explore how using anchoring and other advanced features can transform your Bitrise workflows. By the end of this post, you'll understand how to leverage YAML to optimize your mobile development processes, making them more efficient and error-free. Let's get started on maximizing your productivity with Bitrise and YAML.

*Sample Workflow (Unoptimised) *

---
format_version: '8'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git

project_type: ios
workflows:
  primary:
    steps:
      - activate-ssh-key@4:
          run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'

      - git-clone@6: {}

      - cache-pull@2: {}

      - certificate-and-profile-installer@1: {}

      - xcode-test@3:
          inputs:
            - project_path: "$BITRISE_PROJECT_PATH"
            - scheme: "$BITRISE_SCHEME"
            - simulator_os_version: "latest"
            - simulator_device: iPhone 11 Pro Max

      - xcode-build-for-simulator@0:
          inputs:
            - project_path: "$BITRISE_PROJECT_PATH"
            - scheme: "$BITRISE_SCHEME"
            - simulator_device: iPhone 11 Pro Max

      - cache-push@2:
          inputs:
            - cache_paths: |-
                ./Pods -> ./Podfile.lock
                ./Carthage -> ./Cartfile.resolved

      - slack@3:
          inputs:
            - webhook_url: "$SLACK_WEBHOOK_URL"
            - channel: "#builds"
            - message: "Build finished successfully!"
Enter fullscreen mode Exit fullscreen mode

As you can see there are a few steps in this primary workflow. The more workflows you have with similar steps the bigger your yaml will get.

Anchoring in YAML

YAML, or "YAML Ain't Markup Language", is a human-readable data serialization format. It is commonly used for configuration files and in applications where data is being stored or transmitted. One of the most powerful features of YAML is its support for anchors and aliases, which allow for the reuse of defined content across multiple parts of the document, significantly reducing repetition and making maintenance easier.

Defining Anchors and Aliases

Anchors in YAML are defined by using the & symbol followed by a name, and they mark a section of the document for future reference. Aliases, on the other hand, are references to these anchors, made using the * symbol followed by the name of the anchor they refer to.

How Anchors and Aliases Help

Anchors and aliases are particularly useful in large configuration files with repeated structures or values. They not only keep the YAML file DRY (Don't Repeat Yourself), but they also simplify updates: change the value at the anchor, and all associated aliases automatically get updated. This is invaluable in environments like CI/CD workflows where multiple, slightly different configurations might be used repeatedly.

Simple Examples of YAML Anchors and Aliases

Here’s a simple example to illustrate how anchors and aliases work in YAML:


# Define an anchor for a reusable component
reusable_settings: &default_settings
  check_interval: 60
  start_on_boot: true
  retry_limit: 5

# Using alias to reuse the settings
service_one:
  <<: *default_settings
  name: "Service One"

service_two:
  <<: *default_settings
  name: "Service Two"
  check_interval: 90  # Override the check_interval for this service only
Enter fullscreen mode Exit fullscreen mode

In this example, reusable_settings is defined with an anchor &default_settings. It is then used in the configurations for service_one and service_two using the alias **default_settings. The <<: *default_settings* syntax is a special merge key indicating that the elements defined in the anchor should be merged into the current map.

For service_two, you can see how easy it is to override a specific setting (check_interval) that was included via an alias, demonstrating how flexible this feature can be.

Applying Anchors and Aliases in Bitrise YAML Configurations

When applied to Bitrise YAML configurations, anchors and aliases can manage repeated patterns like environment variables, build settings, or even entire workflows efficiently. This allows developers to simplify complex CI/CD configurations and ensure consistency across different stages of the development and deployment process.

Using anchors and aliases effectively can lead to cleaner, more manageable, and less error-prone configuration files, making it a best practice worth adopting in your Bitrise YAML configurations.

Here is a revised version of our bitrise yaml using 2 workflows.

format_version: '8'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git

steps:
  - step: &xcode-test
      xcode-test@3:
          inputs:
            - project_path: "$BITRISE_PROJECT_PATH"
            - scheme: "$BITRISE_SCHEME"
            - simulator_os_version: "latest"
            - simulator_device: iPhone 11 Pro Max
  - step: &xcode-build-for-sim
      xcode-build-for-simulator@0:
          inputs:
            - project_path: "$BITRISE_PROJECT_PATH"
            - scheme: "$BITRISE_SCHEME"
            - simulator_device: iPhone 11 Pro Max
  - step: &cache-push
      cache-push@2:
          inputs:
            - cache_paths: |-
                ./Pods -> ./Podfile.lock
                ./Carthage -> ./Cartfile.resolved
  - step: &slack-message
      slack@3:
          inputs:
            - webhook_url: "$SLACK_WEBHOOK_URL"
            - channel: "#builds"
            - message: "Build finished successfully!"


project_type: ios
workflows:
  primary:
    steps:
      - activate-ssh-key@4:
          run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
      - git-clone@6: {}
      - cache-pull@2: {}
      - certificate-and-profile-installer@1: {}
      - *xcode-test
      - *xcode-build-for-sim
      - *cache-push
      - *slack-message
  secondary:
    steps:
      - activate-ssh-key@4:
          run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
      - git-clone@6: {}
      - cache-pull@2: {}
      - certificate-and-profile-installer@1: {}
      - *xcode-test
      - *xcode-build-for-sim
      - *cache-push
      - *slack-message
Enter fullscreen mode Exit fullscreen mode

The use of YAML in conjunction with Bitrise offers a robust framework for automating and optimizing CI/CD pipelines, especially for mobile app development. By incorporating YAML's anchoring and aliasing features, developers can greatly reduce redundancy within their configuration files, leading to cleaner, more manageable, and more reliable setups.

We encourage you to experiment with these YAML techniques in your projects. Start small by refactoring a single workflow, see the benefits, and gradually expand your use of these features. As you become more comfortable with YAML's capabilities, you'll find that many aspects of your CI/CD process can be optimized, not just by automating tasks, but by organizing them more effectively as well.

Happy coding, and may your builds always be successful!

Top comments (0)