Back to all Blog

Manage Development Workflows with ‘Branches’

If you have worked with Git, Mercurial or other software with version or source control capabilities, you’re familiar with the concept of branching. Branches allow you to create copies of content-type structures (schemas) to make changes and iterate without the risk of affecting what’s live on the production server. Working with branches makes life extremely easy for developers.

To that end, we are excited to announce that Contentstack now offers branches.

Branching capabilities support roles and workflows for better collaboration between developers and business users. Branches make it easier for developers to work concurrently on multiple releases without affecting content creation. Branches are covered by your plan’s production SLAs, allowing you to test the effectiveness of experience variations against live audience segments. Let’s look at how this feature works and the benefits it offers.

How Branches Work in Contentstack

If you have used any CMS as a developer, you know how risky it is to make changes to the content type or structure of a page that’s already live. Any unintentional error may cause data loss or even take your application down.

Thankfully, you now have branches in Contentstack. If you want to change an existing content type, you can create a new branch, even on the production server. Adding a branch creates a copy of all the current content types, entries, assets, languages, extensions and releases of the source branch. Any subsequent changes that you make to the content of this new branch will have no impact on the content of the source branch (or any other branch that your production server uses). It will start an independent line of development and content changes.

Diagram of Branches content structure

You can try new changes, iterate and publish in a testing environment with this new branch. Branches can have separate tokens, webhooks and audit logs, so developers can try out changes and track all activities. It’s like having a separate space for your development work.

Each branch has a dedicated publish queue, content trash and workflows, enabling cross-functional collaboration with content managers who are modifying content.

Once you are sure that changes are correct, you can make this new branch your main branch for an environment.

In a multi-environment setting, changing the main branch often would mean making frequent changes to the branch configuration in your front-end code. To make mapping in multi-environments easier, we have aliases.

What Are Aliases?

An alias acts as a pointer to a particular branch. You need to use the alias ID in your front-end code. Once changes in your branch are ready to go, you can set that branch as the target branch for an alias. You are not required to make changes to your code every time. In other words, when you point a branch to an alias, that branch acts as the main branch for the corresponding environment. You can read our documentation on aliases to learn more about them.

Why Do You Need Branches?

Here are some reasons why branches are helpful to you and your company:

  • Branches allow you to easily manage your “in-progress” work, which can be separate from your live and stable work in the production environment.
  • For companies targeting higher release velocity, branches allow teams to work in parallel instead of one after the other.
  • With separate roles and workflows set up for each branch, development teams can work together with business and marketing in a more collaborative, organized and structured manner.
  • Should something go wrong, branches make rolling back changes incredibly easy.

Breaking Changes to Keep in Mind

This feature release will introduce a change in the API responses returned for several Content Delivery API (CDA) / CDN and Content Management API (CMA) requests. To ensure a smooth transition when you start using branches, we have listed below a few breaking changes in the API that you might need to update within your back-end code.

[Breaking] Additional "branch" Key in Webhook-related API Responses

If the "Branches'' feature is part of your plan, all webhook-related API requests that hit the Content Management API (CMA) will return the branch key in the response body. This key specifies the unique ID of the branch on which the concerned webhook was triggered.

Here's a sample of the webhook data with the branch key:

{
   "module":"entry",
   "api_key":"blt38776c9acaae33b3",
   "event":"update",
   "triggered_at":"2020-10-14T14:40:54.157Z",
   "data":{
      "entry":{
         "uid":"blt36952eb1aa651010",
         "title":"Sample Entry",
         "locale":"en-us",
         "_version":7
      },
      "content_type":{
         "uid":"footer",
         "title":"Footer"
      },
      "branch":{
         "uid":"main"
      }
   }
}

Additional "branches" and "branch_aliases" Keys to Specify Branch/Alias Scope in Responses

If the Branches feature is part of your plan, you will see additional keys named branches and branch_aliases in the API responses in some of the Contentstack modules (listed below). These keys specify the unique IDs of the branches and aliases selected within the scope for the concerned modules.

  • Webhooks, Workflows and Publish Rules-related API requests that hit the Content Management API (CMA) will return a top-level branches key in the response body. This key specifies the unique IDs of the branches to which these modules are applicable. For instance, here’s the response that you will get for the get all webhooks API request:
{
   "webhooks":[
      {
         "uid":"blt789920f4d2650336",
         "branches":[
            "main"
         ],
         "channels":[
            "content_types.update"
         ],
         "disabled":false,
         "concise_payload":true,
         "Name":"Sample Webhook",
         "destinations":[
            {
               "target_url":"https://example-site.com",
               "http_basic_auth":"",
               "http_basic_password":"",
               "custom_header":[
                  {
                     "value":"",
                     "header_name":""
                  }
               ]
            }
         ],
         "retry_policy":"manual",
         "org_uid":"bltd1cd127c7b51f410",
         "updated_by":"blt1fd0057b90905592",
         "created_by":"blt1fd0057b90905592",
         "created_at":"2021-08-26T19:38:29.596Z",
         "updated_at":"2021-08-26T19:38:29.596Z"
      }
   ]
}

  • Delivery Token and Management Token-related API requests that hit the Content Management API (CMA) will return the branches and branch_aliases keys under the scope section in the response body. These keys specify the unique IDs of the branches and branch aliases for which a delivery or management token is applicable. For instance, here’s the response that you will get for the get all delivery tokens API request:
{
    "tokens": [
        {
            "description": "Sample token to fetch content.",
            "name": "Sample Delivery Token",
            "scope": [
                {
                    "environments": [
                        ...
                    ],
                    "module": "environment",
                    "acl": {
                        "read": true
                    },
                    "_metadata": {
                        "uid": "cs48231eccb8125898"
                    }
                },
                {
                    "module": "branch",
                    "acl": {
                        "read": true
                    },
                    "branches": [
                        "main",
                        "development"
                    ],
                    "_metadata": {
                        "uid": "cs81f7766198897700"
                    }
                },
                {
                    "module": "branch_alias",
                    "acl": {
                        "read": true
                    },
                    "branch_aliases": [
                        "demo",
                        "release"
                    ],
                    "_metadata": {
                        "uid": "cs7e7ee9b555e9f021"
                    }
                }
            ],
            ...
            }
        }
    ]
}

  • Organization User-related API requests that hit the Content Management API (CMA) will return the branches and branch_aliases keys under the rules section in the response body. These keys specify the unique IDs of the branches and branch aliases of which a particular user role can access data. If a user has access to the content present in all the stack branches, then the branches or branch_aliases keys return the $all value. For instance, here’s how the "rules" section would look in the response for the get user API request:
{
   "uid":"blt969408c7c448a4d5",
   "name":"Content Manager",
   "description":"Content Manager Role.",
   "users":[
      "blt1fd0057b90905592"
   ],
   "roles":[

   ],
   "created_at":"2021-07-26T10:04:20.765Z",
   "updated_at":"2021-07-27T07:22:08.875Z",
   "api_key":"bltadd6b6032484ce86",
   "rules":[
      {
         "module":"branch",
         "branches":[
            "main"
         ]
      },
      {
         "module":"branch_alias",
         "branch_aliases":[
            "$all"
         ]
      },
      {
         "module":"locale",
         "locales":[
            "$all"
         ]
      },
      {
         "module":"environment",
         "environments":[
            "$all"
         ]
      },
      {
         "module":"asset",
         "assets":[
            "$all"
         ],
         "acl":{
            ...
         }
      }
   ]
}

[Breaking] Updated Asset Download URL Format as per Branch

If the Branches feature is part of your plan, you will see an updated download URL format for all assets part of any branch, except the default main branch. The branch={branch_UID} query parameter is attached to the download URL.

For instance, if you upload an asset to the development branch, Contentstack generates the following asset download URL:

https://assets.contentstack.com/v3/assets/blt252b550c5ccdae26/bltc56f275260214c0b/61280d9625aca65092ce7f15/Sample_Image.jpg?branch=development

For any asset that you upload to the main branch, Contentstack will continue to generate asset download URLs in the earlier format:

https://assets.contentstack.com/v3/assets/blt252b550c5ccdae26/bltc56f275260214c0b/61280d9625aca65092ce7f15/Sample_Image.jpg

Support "include_branch" as Query Parameter in CMA and CDA API Requests

If the Branches feature is part of your plan, you can pass the include_branch query parameter while running Content Delivery API (CDA) / CDN and Content Management API (CMA) requests. Set the include_branch key to true to allow the API to return the _branch key in the response. This key specifies the unique ID of the branch and helps identify where the concerned Contentstack module resides.

Here’s the list of the components that support the include_branch query parameter:

  • Content Types [CDA / CMA]
  • Global fields [CDA / CMA]
  • Assets [CDA / CMA]
  • Entries [CDA / CMA]
  • Extensions
  • Languages
  • Releases
  • Audit Log
  • Publish Queue
  • Workflows
  • Publish Rules
  • Webhooks

Let’s look at an example of how the response would look when you pass the include_branch query parameter. Here’s the response you will get for the get all content types API request:

{
    "content_types": [
        {
            ...,
            "schema": [
                {
                    "display_name": "Title",
                    ...
                },
                {
                    "display_name": "URL",
                    ...
                },
            ],
            "last_activity": {},
            "maintain_revisions": true,
            "description": "",
            "DEFAULT_ACL": {
                "others": {
                    "read": false,
                    "create": false
                },
                "users": [
                    {
                        "read": true,
                        "sub_acl": {
                            "read": true
                        },
                        "uid": "blt690a3fed2a593445"
                    }
                ],
                "management_token": {
                    "read": true
                }
            },
            "SYS_ACL": {
                "roles": [
                    {
                        "uid": "bltdc9d89cd41565777",
                        "read": true,
                        "sub_acl": {
                            ...
                        },
                        "update": true,
                        "delete": true
                    },
                    {
                        ... 
                        }
                    },
                    {
                        ...
                        },
                        ...
                    }
                ],
                "others": {
                    ...
                    }
                }
            },
            "_branch": "development",
            "options": {
                "title": "title",
                "publishable": true,
                "is_page": true,
                "singleton": false,
                "sub_title": [
                    "url"
                ],
                "url_pattern": "/:title",
                "url_prefix": "/"
            },
            "abilities": {
                "get_one_object": true,
                "get_all_objects": true,
                "create_object": true,
                "update_object": true,
                "delete_object": true,
                "delete_all_objects": true
            }
        }
    ]
}

Get Started With Branches

The Branches feature will be rolled out to all customers gradually over the next few weeks. It is available in Contentstack only for the new interface. All the stacks in your organization will now have a “default” branch, and you can create more branches from there. The number of branches available depends on your plan. You can read our documentation on branches to learn more or reach out to support@contentstack.com