Labels
--label-filter
attribute in the CLI. You can specify a
Labels work best when the changeset author can simply enumerate or describe what a changeset is used for, such as a particular feature or version. There may be greater complexity at runtime to determine what label expression should be used to perform the deployment, but that control is left to the deployment manager or person executing the changesets. Labels are similar to Contexts, which you can to specify other tags, such as development environments.
In Liquibase Pro 4.23.1+, you can easily set
Uses
You can typically use labels to:
- Manage and track your deployments.
- Apply complex logic to filter the changesets eligible for deployment.
- Mark changesets based on features and then selectively apply those features at the execution time instead of using version control branches.
- Use different languages for marking changesets. For example, you can mark your changesets both with Spanish and English.
- Assign ticket numbers to particular changesets to track and identify their purpose, such as JIRA ticket numbers
label-filter runtime syntax
In Liquibase 4.23.0+, you can specify a label using @
in addition to AND
, OR
, !
, and parentheses in the changesets. The @
is used for labels only at run time and forces any specific labeled changeset to execute.
Example: If a changeset is labeled as labels=test
, only this changeset will be forced to execute if at runtime we specify --label-filter=@test
.
Note: If you have a changeset marked with a label that starts with @
and you run Liquibase without specifying the --label-filter
attribute, the changeset will not be executed. If label filters (--label-filter=
) are specified as @test
at runtime as described in the example above, no changeset will be executed if there are not any labels titled test
.
Label filters can be specified using @
, AND
, OR
, !
, and ()
(parentheses that are used for grouping). For example:
--label-filter="@test"
--label-filter="!v.0.1"
--label-filter="v.1.0 and v.1.1"
--label-filter="v.1.0 or v.1.1"
--label-filter="!v.1.0 and !v.1.1"
Using ","
to separate labels works like an OR
operation (a comma is an alias for OR
). For example:
--label-filter="v.1.0, v.1.1"
is the same as--label-filter="v.1.0 OR v.1.1"
--label-filter="v.0.1, v.1.0 and v.1.1"
is the same as--label-filter="(v.0.1) OR (v.1.0 and v.1.1)"
You can run the --label-filter
attribute to determine which changesets in the changelog to evaluate based on its label. Learn more about the labelFilter logic at this blog post.
- In your changelog, you can specify only a simple list of labels to apply to the changeset. For example,
labels="v.0.1, v.1.0"
. - At runtime, you can specify a complex expression with the labels that you want to execute. For example,
--label-filter="!v.0.1"
or--label-filter="v.1.0 or (v.1.1 and v.1.2)"
.
Note: Prior to version 4.16.0, the CLI argument was --labels
rather than --label-filter
. In 4.16.0 and beyond, --labels
is a supported alias for --label-filter
.
Usage
It is best practice to enumerate your changesets or describe what a changeset is used for. An example of labels indicating the version or a specific feature can be "1.0"
or "shopping_cart"
. In this case, labels will allow you to run changes with:
--label-filter=1.0
to deploy the 1.0 changesets or--label-filter=shopping_cart
to deploy the changesets related to the shopping cart.--label-filter="1.0 or (1.1 and shopping_cart)"
to deploy the 1.0 changesets and only the 1.1 features related to the shopping cart.--label-filter="1.0 or (1.1 and !shopping_cart)"
to deploy the 1.0 changesets and the 1.1 features that are not related to the shopping cart.
You can see an example of running the update
command with complex --label-filter
statements:
liquibase --output-file=update.txt update --changelog-file=changelog.xml --label-filter="1.0 or (1.1 and !shopping_cart)"
If a changeset doesn't have a label, it will always run. If you make a deployment without specifying any labels in the label filter, all changesets will run.
Example: If you run the liquibase update --label-filter=1.0
command, it will deploy all changesets with the label 1.0
and all changesets without any label. If you run liquibase update
, it will deploy all changesets, whether they have labels or not.
--liquibase formatted sql
--changeset your.name:1 labels:1.0,prod,shopping_cart
CREATE TABLE person (firstname VARCHAR(255) NULL);
--changeset your.name:2 labels:2.0,test
ALTER TABLE person ADD address VARCHAR(255) NULL;
--changeset your.name:3 labels:shopping_cart
ALTER TABLE person ADD favorite_color VARCHAR(255) NULL;
--changeset your.name:4
CREATE TABLE no_label (no_label_col VARCHAR(255) NULL);
{
"databaseChangeLog": [
{
"changeSet": {
"id": "1",
"author": "your.name",
"labels": "1.0,prod,shopping_cart",
"changes": [
{
"createTable": {
"tableName": "person",
"columns": [
{
"column": {
"name": "firstname",
"type": "varchar(255)"
}
}
]
}
}
]
}
},
{
"changeSet": {
"id": "2",
"author": "your.name",
"labels": "2.0,test",
"changes": [
{
"createTable": {
"tableName": "person",
"columns": [
{
"column": {
"name": "address",
"type": "varchar(255)"
}
}
]
}
}
]
}
},
{
"changeSet": {
"id": "3",
"author": "your.name",
"labels": "shopping_cart",
"changes": [
{
"createTable": {
"tableName": "person",
"columns": [
{
"column": {
"name": "favorite_color",
"type": "varchar(255)"
}
}
]
}
}
]
}
},
{
"changeSet": {
"id": "4",
"author": "your.name",
"changes": [
{
"createTable": {
"tableName": "no_label",
"columns": [
{
"column": {
"name": "no_label_col",
"type": "varchar(255)"
}
}
]
}
}
]
}
}
]
}
databaseChangeLog:
- changeSet:
id: '1'
author: your.name
labels: '1.0,prod,shopping_cart'
changes:
- createTable:
tableName: person
columns:
- column:
name: firstname
type: varchar(255)
- changeSet:
id: '2'
author: your.name
labels: '2.0,test'
changes:
- addColumn:
tableName: person
columns:
- column:
name: address
type: varchar(255)
- changeSet:
id: '3'
author: your.name
labels: 'shopping_cart'
changes:
- addColumn:
tableName: person
columns:
- column:
name: favorite_color
type: varchar(255)
- changeSet:
id: '4'
author: your.name
changes:
- createTable:
tableName: no_label
columns:
- column:
name: no_label_col
type: varchar(255)
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd
http://www.liquibase.org/xml/ns/pro
http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd">
<changeSet author="your.name" id="1" labels="1.0,prod,shopping_cart">
<createTable tableName="person">
<column name="firstname" type="VARCHAR(255)"/>
</createTable>
</changeSet>
<changeSet author="your.name" id="2" labels="2.0,test">
<addColumn tableName="person">
<column name="address" type="VARCHAR(255)"/>
</addColumn>
</changeSet>
<changeSet author="your.name" id="3" labels="shopping_cart">
<addColumn tableName="person">
<column name="favorite_color" type="VARCHAR(255)"/>
</addColumn>
</changeSet>
<changeSet author="your.name" id="4">
<createTable tableName="no_label">
<column name="no_label_col" type="VARCHAR(255)"/>
</createTable>
</changeSet>
</databaseChangeLog>
include
and includeAll
labels
You can specify the labels
attribute in include
and includeAll
tags. If specified, the given label is added to all changesets in the included file(s).