Controlling snap releases with channels, tracks and branches – Part 1

By Daniel Manrique, Engineering Manager at Canonical, Online Services

Ever since snaps were introduced, a crucial part of their feature set has been the ability to release a snap on a particular “channel” indicating how stable or production-ready it is. The well-known channel names stable, candidate, beta and edge indicate a snap’s stability, according to the developer, and users are then empowered to choose the level of risk they are prepared to accept when installing a snap.

From a developer’s point of view, it makes sense to release new changes on edge, which will presumably have a small number of users willing to accept some instability in exchange for bleeding-edge features (but also, tacitly, a disposition to report problems), and as any rough edges are taken care of, release the updated snap to beta, candidate and finally to stable once it’s deemed adequate for anyone to use.

Finding and following channels

The typical means for discovering snaps (the “snap find” command) reveals only snaps in the stable channel. Snaps can be installed from other channels by simply using a command-line parameter (snap install --channel=candidate, for example), but those releases will not appear in search results. Developers are encouraged to publicize releases to the riskier channels via blog posts, tweets or direct communications with users and only make their snap discoverable by any user when it’s considered stable enough.

These four channel names are always available for users to subscribe to, but a developer doesn’t necessarily have to release explicitly to every channel, thanks to a behavior known as “following”. If there is no revision currently released in a channel, it is in a “closed” state and the store will offer whichever revision of the snap is in the next most stable channel.

So if a developer does:

$ snapcraft release my-snap 37 stable
Track   Arch   Channel    Version  Revision
latest  amd64  stable     37       37
               candidate  ^        ^
               beta       ^        ^   
               edge       ^        ^

Then a user subscribing to the candidate channel via:

snap install my-snap --channel=candidate

Will still get revision 37 of my-snap.

As the developer releases subsequent revisions to stable, any users who installed from candidate will be updated to those revisions.

Channels are more useful, clearly, when the developer releases something different to each of them. So for instance, when a new candidate version (revision 50) is ready, the developer can do:

$ snapcraft release my-snap 50 candidate
Track   Arch   Channel    Version  Revision
latest  amd64  stable     37       37
               candidate  50       50
               beta       ^        ^
               edge       ^        ^

The ‘candidate’ channel is now open.

When a snap is explicitly released into a channel, the channel ceases to follow the previous one and is now “open”. The developer can then release a newer revision into stable:

$ snapcraft release my-snap 51 stable
Track   Arch   Channel    Version  Revision
latest  amd64  stable     51       51
               candidate  50       50
               beta       ^        ^
               edge       ^        ^

At this point, people installing or refreshing from candidate will still get the explicitly-released revision 50.

Does this mean that once a snap is released into a channel, the developer must manually keep the channel up to date? No! The “following” behavior can be restored by “closing” the channel, which means it will fall back to offering the same revision as the immediately-more-stable channel.

$ snapcraft close my-snap candidate
Track   Arch   Channel    Version  Revision
latest  amd64  stable     51       51
               candidate  ^        ^
               beta       ^        ^
               edge       ^        ^

The candidate channel is now closed.

In our example, people who had installed from candidate will now refresh to revision 51, and start getting subsequent updates released to stable.

In addition to the stability progression, the well-known channel names have one special behavior to help ensure that software isn’t released to a channel it’s not suitable for: Snaps with grade: devel or confinement: devmode can only be released to edge and beta channels (here are some pages with more information about grade and confinement options).

Anatomy of a channel

These four “channels” have always been a well-known component of the snap experience. But now, a revelation: did you know those names are actually called “risks” and are only one component of an actual channel name? Full channel names have three parts: track, risk and branch, and they give developers powerful mechanisms with which to control the delivery of software to users. A full channel name looks like this, with slashes delimiting the components:

track/risk/branch

Only the risk component (what we had been calling “channel” until now) is mandatory (and is the only one restricted to a set of options, namely the four well-known stable, candidate, beta and edge risks). All snaps have an implicit latest track (which is why things worked when we didn’t specify a track), and the “branch” component is optional. So when you say stable, it actually means latest/stable; beta is latest/beta and so on.

In part two, we’ll look in detail at tracks and branches. Tracks can be used to have multiple “stable” versions, so users can choose to either follow the latest “stable” or use an older major version, usually for compatibility reasons. Branches are custom “temporary” channels to which a snap can be released and are useful for releasing “hot fixes” and code changes that apply to limited audiences.

More information

The reference documentation on channels is here. Please find us on the forum if you have any questions about leveraging channels for your project.

Posted in: