My original mental model of Liquibase had tags going at the end of groups of changes.
For example, I would expect a list of changes for release 1.0.0 to end with a tag called 1.0.0. I would also expect a list of changes for release 1.1.0 to end with a tag called 1.1.0. This particular example uses changesets to do tagging rather than the tag command, and I’m also confused about the differences between those two methods of tagging.
If I deployed the 1.0.0 changes followed by the 1.1.0 changes, I would expect to see a changelog table like the following:
liquibase_testing=# select id, filename, orderexecuted, tag,liquibase from databasechangelog order by orderexecuted desc;
id | filename | orderexecuted | tag | liquibase
-----------±--------------------------------±--------------±------±----------
tag 1.1.0 | changes/db.changelog-master.xml | 6 | 1.1.0 | 3.8.9
change 4 | changes/db.changelog-master.xml | 5 | | 3.8.9
change 3 | changes/db.changelog-master.xml | 4 | | 3.8.9
tag 1.0.0 | changes/db.changelog-master.xml | 3 | 1.0.0 | 3.8.9
change 2 | changes/db.changelog-master.xml | 2 | | 3.8.9
change 1 | changes/db.changelog-master.xml | 1 | | 3.8.9
(6 rows)
Then if I wanted to roll back all the changes for version 1.1.0, I would tell Liquibase to rollback to tag 1.0.0. I would expect for all of the 1.1.0 changes to be removed, leaving all of the 1.0.0 changes (including the 1.0.0 tag), as follows:
liquibase_testing=# select id, filename, orderexecuted, tag,liquibase from databasechangelog order by orderexecuted desc;
id | filename | orderexecuted | tag | liquibase
-----------±--------------------------------±--------------±------±----------
tag 1.0.0 | changes/db.changelog-master.xml | 3 | 1.0.0 | 3.8.9
change 2 | changes/db.changelog-master.xml | 2 | | 3.8.9
change 1 | changes/db.changelog-master.xml | 1 | | 3.8.9
(3 rows)
Instead, the changeset with the 1.0.0 tag gets removed as well!
liquibase_testing=# select id, filename, orderexecuted, tag,liquibase from databasechangelog order by orderexecuted desc;
id | filename | orderexecuted | tag | liquibase
----------±--------------------------------±--------------±----±----------
change 2 | changes/db.changelog-master.xml | 2 | | 3.8.9
change 1 | changes/db.changelog-master.xml | 1 | | 3.8.9
(2 rows)
It looks like the tag command updates the tag column of the latest row in the database change log table, so if I had used that instead of tag changesets, I would also lose “change 2”, which is definitely not what I want.
What’s wrong with my mental model of how Liquibase tags work?
I can work around the mismatch by putting tag changesets at the beginning of each series of changes, but I am still very puzzled as to why this is how Liquibase behaves.