Problem with rollback strategy

Hi all, my first message here.

I’m not sure how to implement rollback in my cicd pipeline using liquibase.

I have my application code and liquibase changsets in my git repository. When we release a new version the CICD software deploys the new version of the application and executes the changesets in the appropriate environment. Executing the changesets consists of calling ‘update’ and then ‘tag’ with the new version number of the application, for example 1.2.

My problem occurs when a new version of the application only involves a code change and there is no new changeset to run. The CICD pipeline executes the ‘update’ and the ‘tag’ and overwrites the new tag in the DATABASECHANGELOG table (to 1.3 for example). These types of changes are common and the version number can be updated several times without new liquibase changesets. Let’s assume that we have updated to version 1.7.

If after this we want to rollback to version 1.2 liquibase will tell me that the label does not exist. I don’t know if I’m following the right approach. From my point of view, the ideal is that all the tags that are applied to the liquibase changesets will be preserved, even if there are no changes in the database.

Maybe there is a better way to do it but I don’t know.

Thanks in advance.

Running the “tag” command does write the tag label to the most recent row in the databasechangelog table, and it will override the existing tag label on that row, if one exists. Someone from liquibase will need to address whether that is the intended behavior or not.

I’d recommend using the “tagDatabase” change-type inside of your changelogs. This will insert a new row into the databasechangelog table, and not overwrite the most recent tag label.

<changeSet id="tag_database_v0.2" author="BOB">
  <tagDatabase tag="v0.2"/>
</changeSet> 

This change-type can be used in xml, yaml, or json changesets.

Hi daryldoak

Thank you very much for your suggestion. I didn’t know the “tagDatabase” command. I have to do some research and do some testing to see if it can be useful in my use case.
I will write soon with the results.
Thank you so much.

You’re Welcome.

Just to clarify, “tagDatabase” is not a Liquibase command, it’s a change-type.

You are right. I still don’t know some of the liquibase concepts well.

1 Like

No problem, just wanted to make sure it was clear.

Hi again

After doing some tests I have not been able to get ‘tagDatabase’ to work.

My xml changeset works but when I add ‘tagDatabase’ it shows this error:

cvc-complex-type.2.4.a: Invalid content was found starting with element ‘{“Liquibase | Liquibase XML Schema Definitions”:createTable}’. One of ‘{“Liquibase | Liquibase XML Schema Definitions”:modifySql}’ is expected

I´m working with Liquibase 4.23. My changeset is:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="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 http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
	<changeSet author="isolation" id="1">	
		<tagDatabase tag="version_1.0"/>
		<createTable tableName="COMPANY_0">
			<column name="NOMBRE" type="NUMBER(10, 0)"/>
		</createTable>
		<rollback>
			<dropTable tableName="COMPANY_0"/>
		</rollback>
	</changeSet>
</databaseChangeLog>

Anyway, even if I get it to work I think there is another problem.

What I’m trying to do is go back to an old version of the application using a pipeline to deploy. All code and changesets are in version control. If I checkout an old version, It may not have all the changeset files that have been applied to the data schema, so Liquibase will not be able to rollback these changes. I think the only solution is to do the rollback manually.

Thank you. Greetings.

The tagDatabase needs to be in it’s own changeset. And you do not need to define a custom rollback when using the createTable change-type, it uses auto-rollback.

<changeSet author="isolation" id="0">	
	<tagDatabase tag="version_1.0"/>
</changeSet>
<changeSet author="isolation" id="1">	
	<createTable tableName="COMPANY_0">
		<column name="NOMBRE" type="NUMBER(10, 0)"/>
	</createTable>
</changeSet>

You always need to rollback using the exact same changelogs that applied the changes to the database, otherwise how would the correct rollback sql get applied? Once the rollback has completed you can modify the changelogs as necessary,

I tried again using own changeset for tagDatabase and it worked.

I understand that the changelogs are necessary so that Liquibase knows how to do the rollback. Maybe saving the changelogs in the database would allow the rollback to be done without the files, but surely there is a design reason for the current behavior.

It is possible that I am taking the wrong path in CICD to rollback a new version into a staging environment.

Thanks. Greetings.

1 Like