How to release breaking changes to the "latest" track?

I’m trying to work out how best to achieve what I need with the snap versioning & release system. I feel like this is a scenario that many software maintainers are likely to hit (and so may already be covered somewhere).

I’ve been releasing documentation-builder using the channels, without worrying about tracks so far. So currently, latest/stable carries revision 37, version 1.6.0 (latest being the default track).

I’d like to release version 2.0.0, which will include a significant breaking change for the user - now the user will have to provide a template, where previously the template was included. This will be the official new version of documentation-builder, and I won’t be actively maintaining 1.x any more.

I don’t think it’s a good idea to automatically upgrade any users to 2.0.0, it should only be something they do deliberately, as they now need to actively provide a template. I’d also like to reserve the option to automatically push e.g. 1.6.1 to those with 1.6.0 at some point if needed.

I could open a new track, e.g. the 2.x track or something, but the problem with that is that the latest track would continue to exist just for 1.x versions, and would be quite misleading.

Is there any way to leave existing users on a 1.x track, but reclaim the latest track for my new 2.x set of releases?

A model that could allow me to solve this problem quite elegantly might be:

  • If the default track was called something else (e.g. default)
  • Tracks could be renamed
  • latest could be a pointer, or a label, for a track, which could be moved between tracks

Then I could:

  • Rename the default track to 1.x
  • Create a 2.x track
  • Label 2.x as the latest track

Thinking about where the snap system appears to be at this point, my problem could be initially solved if it were only possible to rename tracks. That would then allow me to rename latest to 1.x, and create a new latest, or 2.x, or stable track.

You can have a 1.x track, and a 2.x track, and release the same revision to 1.x and to latest until the 2.x is considered the “safe” one, at which point as long as config etc is compatible you just release the 2.x revisions to latest.

We have talked about having a “default” track that is a movable pointer, but that isn’t yet in our near-term roadmap.

In the interim, @chipaca’s solution is likely what you want to do, just give users of latest ample time to move to the 1.x track.

It will never be “safe” to automatically update systems running 1.6.0 to 2.0.0. This won’t change over time.

As soon as 2.0.0 is released, it will be stable and the latest version, which all new users should install. At the same time, systems which use 1.6.0 should continue to work until they are deliberately upgraded.

And the reason I think this is an important use-case for snap to have a solution for is because I suspect this is how most new projects will go - initially they’ll use the default track (currently latest) and then they’ll get to a point where they need to introduce a breaking change and avoid automatically upgrading their existing users, who will be on latest.

This is important because documentation-builder is used in CI and other build systems. It wouldn’t matter so much for completely user-facing software. But I believe that system-level software (that is likely to be used as a part in a stack, with a reliable API) forms a significant percentage of the software that snap hopes to support.

The default movable pointer would only help if the initial default track was no longer named latest. I’m not sure what name would make sense for a track that is currently default but later may not be. I can’t see a way to elegantly solve this without allowing tracks to be renamed. Or to give them completely meaningless names and instead have human-readable pointers (which is basically the same thing).

1 Like

I suggest using Epochs to update the latest track with a breaking version. Hopefully this can help:

1 Like

That’s exactly what I need! Thanks @anthonydillon

Hope it’s ok to revive this, as I have pretty much exactly the same use case as what @nottrobin described.

A slight difference is that our snap in question is mostly running on IoT devices that we’ve deployed ourselves - rather than being something that end users install. Either way, we are going to be introducing some breaking changes. Those will impair the functionality of many of the existing devices, so we would like to keep all of them on a hypothetical 1.0 track (currently only a latest track exists). We would like to release 2.0 as the default version for installation on new devices. Over time we may want to also manually switch some of the existing 1.0 devices to 2.0.

So overall a pretty straightforward use case for tracks. Except that it’s not clear to me how to tell all existing devices that they should stick to 1.0, and stop them from switching to the new default/latest track. @nottrobin mentioned the possibility of renaming tracks, but I guess that’s not actually an option?

I also looked at epochs as a potential solution. Indeed, continuing to release on the latest channel but with an incremental epoch should solve the immediate use case of preventing 1.0 devices from upgrading to 2.0. Though I can’t yet see how that translates into a longer-term deployment/version management strategy. By design, at least, epochs appear to primarily make it easier to manage upgrade paths, especially where migration of local data is concerned. And tracks appear to be the right tool for actually managing the availability/deployment of multiple versions.

I just wanted to see whether there is, after all, a way to do this using tracks. Or whether we should just use epochs to tackle the immediate issue, and figure out how to potentially switch to tracks later.