Understanding When to Use Contexts vs. Labels
Liquibase labels and contexts allow you to choose a subset of changesets to execute at runtime, enabling many different use cases. Where they differ is deciding who has the power to specify complex logic: the changeset author or the deployment manager.
Managing changesets that load test data is a common use case in Liquibase. You want changesets that load test data to run in your development and QA environments, but you don’t want them to run in production. Both labels and contexts will allow you to do this.
The following examples will only run the changeset when you are running in a test environment.
Loading test data changeset into a test environment using a context:
<changeSet id=”1” author=”example” context=”test”>
liquibase update --contexts=test
Loading test data changeset into a test environment using a label:
<changeSet id=”1” author=”example” labels=”test”>
liquibase update --labels=test
As you start getting into more complex use cases, you’ll be able to use context and labels a bit differently. The key difference between labels and contexts is who writes the expressions and where they are stored.
For example, you might want to use a combination of features (shopping_cart vs. account_mgmt), bundles (pro vs. basic), and customers (acme vs. bigco).
Contexts allow the changeset author to specify the expression in the changeset. Developers can create the changeset as
<changeSet id=”1” author=”example” context=”pro AND shopping_cart”> and the deployment manager simply “tags” the environment at runtime with
liquibase update --contexts=pro,shopping_cart,bigco.
Labels, on the other hand, limit the changeset author to simply “tagging” the changesets like
<changeSet id=”1” author=”example” labels=”pro, shipping_cart”> and gives the filtering power to the deployment manager running
liquibase update --labels=”pro and (shopping_cart or account_mgmt)”.
Using Contexts & Labels Together
You can use both contexts and labels. For example, depending on your team’s needs, you could use contexts for bundles (pro vs. basic) and labels for features (account_mgmt vs. shopping_cart) because the expression logic for the bundles is best handled by the changeset authors, but the deployment manager wants to control the feature deployment logic.
Whether you should use contexts or labels comes down to whether the changeset author/developer or the Liquibase executor (deployment manager) best understands and/or needs the most control over which changesets to execute.
- If you want to describe/tag the environment and have the changeset authors decide which environments they should run in, use contexts.
- If you want to describe/tag the changesets and have the deployment manager decide which changesets to run? If so, use labels.
Remember: you can use both.
While there are many use cases for contexts and labels, they should be used judiciously. The reason you use Liquibase in the first place is to ensure consistent deployment logic from development through production; Contexts and labels are inherently breaking that consistency, allowing some statements to run on some environments and not in others.
When you do find yourself looking to use labels or contexts first ask “is there a better way to do this?”
- If you are using contexts for feature selection, perhaps independent changelogs per feature would work better?
- If you are using labels for managing changes by version, perhaps a different version control or artifact management would work better?
The answer will often be “labels or contexts work best”, but always be aware of any conditional logic you are adding to your changelogs.