Migrations that re-write edit version history

Hi,
We’ve written migrations that convert nested content to block list
We’ve written migrations to convert macros to rte blocks.

Both these migrations work by publishing a new version with the correct schema.
However, this does not affect version history, so roll-back now fails.

Is anyone aware of a tutorial or example code that demonstrates how version history can be altered?

Cheers.
Murray.

Hi there,

Could you share the code you are using to save. I can then compare to my migrations as I’ve not had this reported as an issue, but would be good for to check!

The issue might be that notifications are supressed during a migration. So anything that acts on notifications doesn’t run. For context, I have had an issue with uSync files not getting updated with things I do in a migration. Not sure it this is any help in your specific case, but I solved my issue by running a ‘post migration’:

INotificationAsyncHandler<MigrationPlansExecutedNotification>

And triggering the things that have changed.

Thanks this is useful, I had the same issue when running my custom migrations in a cloud site, not updating the uda. However I was just lazy and made sure to do an export each time - yours is more elegant!

	public async Task<ContentChanges> Convert(IContent content)
	{
		// prepare a delta of changes to apply (list of properties and the new values)
		var summary = _contentConverter.PrepareChanges(content);
		var fresh = _serviceContext.ContentService!.GetById(summary.ContentId)!;
		
		if (fresh.Trashed)
		{
			_logger.LogInformation("ERROR: Content is trashed, skipping conversion: {name} ({key})", fresh.Name, fresh.Key);
			summary.Error = "Content is trashed, skipping conversion.";
			return summary;
		}

		// apply delta of changes.
		foreach (var property in summary.Properties.Where(x => x.Value != null))
		{
			fresh.SetValue(property.Alias, property.Value?.ToString());
		}

		if(fresh.IsDirty() == false)
		{
			summary.Status = "No changes needed";
			return summary;
		}

		try
		{
			_serviceContext.ContentService!.Save(fresh);
			if (fresh.Published) // if there are pending edits publish anyway.
			{
				_serviceContext.ContentService!.Publish(fresh, ["*"]); // publish all cultures
			}
			_logger.LogInformation("Updated Macro->Block on page: {name} ({key})", fresh.Name, fresh.Key);
		}
		catch (Exception e)
		{
			_logger.LogError(e, "FAILED to update Macros->Block on page: {name} ({key}) published:{published}", fresh.Name, fresh.Key, fresh.Published);
			summary.Error = e.Message;
		}
		return summary;
	}

I think I may need to clarify, the rollback mechanism works fine, however the content revision you roll back to is in the old format <?UMBRACO_MACRO … >. The macro content in the newly rolled-back version is not understood by Umbraco 17, so it is not rendered.

I believe that the Umbraco Core team writes migrations that rewrite the entire history, and I’m wondering how to do the same.

e.g., when TinyMCE changed to TipTap, the core migrations rewrite edit history so that you can roll back to a version that used to be TinyMCE, but it has already been converted to the TipTap format.

I believe that the Umbraco Core team writes migrations that rewrite the entire history,

Not that I’m aware of, that would also be wildly inefficient for people who have not done any revision cleanup.

e.g., when TinyMCE changed to TipTap, the core migrations rewrite edit history so that you can roll back to a version that used to be TinyMCE, but it has already been converted to the TipTap format.

No, TipTap can understand the existing Tiny markup just fine, so the property editor is just switched out on the doctype and that’s it.

1 Like