Branches are an under-used but important feature of the Snap Store publishing capabilities. Indeed as I’m writing this post, I’ve never had a need to use the feature, and I’ve been publishing snaps for four and a half years. Let’s fix that!

Start with acorns

The rationale for branches is simple. Each snap in the Snap Store has a default track called ‘latest’ in which there are four channels named ‘stable’, ‘beta’, ‘candidate’ and ‘edge’. These are all typical buckets in which snaps are published for an extended period, perhaps months or maybe even years. Branches on the other hand are short-lived silos for publishing snaps. 

As a developer you may have a published application which has bugs users experience but you cannot reproduce. A temporary branch can be used to hold a test build of the application you’re working on to solve a bug.

If you’re tracking and fixing multiple bugs in parallel, each can have their own separate branch under the same snap name in the Snap Store. Branches are ‘hidden’, so unless someone guesses the name of it, users aren’t going to stumble upon potentially broken bug-fix builds of your application. 

Branches only live for 30 days, after which they’re deleted, and any user with the snap will be moved to the latest track for the channel. So a user who tested the branch latest/stable/fix-bug-12 and didn’t switch to another channel within 30 days, will be moved to the latest/stable channel on their next refresh.

Germinate

Let’s take an example. A user filed an issue on the Atom snap under the snapcrafters GitHub and provided a pull request. We can grab the pull request, build the snap with their fixes, test and publish to the store in a branch so they can try it out.

This could be automated with tools like GitHub Actions, but in lieu of that setup, let’s explain it with the manual steps.

$ git clone https://github.com/aminya/atom-2.git
$ cd atom-2
$ git checkout -b aminya-libstdc++6 master
$ git pull https://github.com/aminya/atom-2.git libstdc++6
$ snapcraft --use-lxd
?
Building atom
Building launcher
Staging atom
Staging launcher
Priming atom
Priming launcher
Snapping
Snapped atom_1.53.0_amd64.snap

Install the application locally to make sure we didn’t completely break it.

$ snap install atom_1.53.0_amd64.snap --dangerous

Upload to the Snap Store and release it to a branch. I selected the latest track as it’s the only track this snap uses. Other snaps may use different tracks for each supported release (e.g. node) or have separate tracks for stable and insider builds (e.g. Skype). We’re fixing the stable release, so I’m using a branch off the stable channel.

$ snapcraft upload atom*.snap --release=latest/stable/fix-65
Preparing to upload 'atom_1.53.0_amd64.snap'.
After uploading, the resulting snap revision will be released to 'latest/stable/fix-65' when it passes the Snap Store review.
Install the review-tools from the Snap Store for enhanced checks before uploading this snap.
Pushing 'atom_1.53.0_amd64.snap' [============================] 100%
released
Revision 269 of 'atom' created.
Track Arch Channel Version Revision Expires at
latest amd64 stable 1.53.0 265
candidate ? ?
beta ? ?
edge 1.53.0 268
stable/fix-65 1.53.0 269 2021-02-05T10:34:51Z

We can already see the branch exists under the latest track, stable branch, but we may want to confirm this – especially if the upload happened in GitHub Actions, a CI or other remote system where we can’t easily see the above output.

$ snapcraft status atom
Track Arch Channel Version Revision Expires at
latest amd64 stable 1.53.0 265
candidate ? ?
beta ? ?
edge 1.53.0 268
stable/fix-65 1.53.0 269 2021-02-05T10:34:51Z

Note, as mentioned earlier, only we as publishers can see the new branch. If a non-publisher looked at the channel map they wouldn’t see it. Non-publishers don’t have access to the snapcraft status command for this snap, and snap info just doesn’t show branches.

$ snap info atom 
?
channels:
latest/stable: 1.53.0 2020-11-10 (265) 242MB classic
latest/candidate: ?
latest/beta: ?
latest/edge: 1.53.0 2020-12-09 (268) 224MB classic
installed: 1.53.0 (x2) 224MB classic

I’m still currently tracking the build I “side loaded” onto my machine, which you can see with the “x” prefixed revision on the last line. We can refresh to the branch hosted in the store. Note that we can optionally omit the ‘latest’ track name, because it’s the default (and only) track. This also allows us to test the instructions we can provide to the author of the pull request.

$ snap refresh atom --amend --channel stable/fix-65
atom (stable/fix-65) 1.53.0 from Snapcrafters refreshed

Note: The --amend option is only required for us because we’re switching from a locally installed revision to one from the store. Users who only installed from the store won’t need that.

Now we have the fix published, we can let the contributor know via a comment on the pull request. Something like this will do nicely:

“Thanks very much for the pull request. I don’t have the ability to reproduce the issue right now. I have published a build of the snap incorporating your fix in a branch. Please could you install the build on a clean system, or if you have the snap already installed, refresh to this branch, and test it?

snap install atom –channel stable/fix-65
or:
snap refresh atom –channel stable/fix-65

If you’re happy with the fix, I’ll land this PR.
Thanks again!”

Once the user replies that this fixes their issue, we can land the PR and roll this into the next stable release. If it doesn’t, well, that’s more software engineering on the to-do list!

Get planting

Of course it’s not just bug fixes which can use branches. Perhaps you have a new feature to soft-launch in the application, or design changes you’d like to experiment with. Having a short-lived branch which is only known by a limited set of testers can be advantageous.

Branches are one of those features that sets the Snap Store apart from some other distribution methods for Linux. It’s not something most publishers will use, but once you know it’s there, it can be quite handy with only a small learning curve.

Join us over on the snapcraft forums if you’d like to discuss this or other features of snapcraft.

Photo by Colin Watts on Unsplash