<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Snapcrafters on Jon Seager</title><link>https://jnsgr.uk/tags/snapcrafters/</link><description>Recent content in Snapcrafters on Jon Seager</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Mon, 18 Mar 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://jnsgr.uk/tags/snapcrafters/index.xml" rel="self" type="application/rss+xml"/><item><title>Simplifying Test &amp; Release of Snapped GUI Apps</title><link>https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/</link><pubDate>Mon, 18 Mar 2024 00:00:00 +0000</pubDate><guid>https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/</guid><description>&lt;h2 id="introduction" class="relative group"&gt;Introduction &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#introduction" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;For the past few months, I&amp;rsquo;ve been getting steadily more involved in &lt;a href="https://github.com/snapcrafters" target="_blank" rel="noreferrer"&gt;Snapcrafters&lt;/a&gt;. The Snapcrafters are a community dedicated to the creation and maintenance of ~100 snap packages. They&amp;rsquo;re currently maintaining snaps for applications like &lt;a href="https://snapcraft.io/signal-desktop" target="_blank" rel="noreferrer"&gt;Signal Desktop&lt;/a&gt;, &lt;a href="https://snapcraft.io/discord" target="_blank" rel="noreferrer"&gt;Discord&lt;/a&gt;, &lt;a href="https://snapcraft.io/gimp" target="_blank" rel="noreferrer"&gt;Gimp&lt;/a&gt;, &lt;a href="https://snapcraft.io/terraform" target="_blank" rel="noreferrer"&gt;Terraform&lt;/a&gt; and &lt;a href="https://snapcraft.io/search?q=publisher%3Asnapcrafters" target="_blank" rel="noreferrer"&gt;many more&lt;/a&gt;, some with &lt;em&gt;hundreds of thousands of weekly active users&lt;/em&gt;. As with any community organisation, maintainer participation can ebb and flow over time as people find themselves with competing priorities.&lt;/p&gt;
&lt;p&gt;One of my personal goals for participation in the Snapcrafters org was to help them build more automated, sustainable processes for bumping versions of snaps as the upstreams move forward, and find a more robust way to test GUI applications before they&amp;rsquo;re released to the masses.&lt;/p&gt;
&lt;p&gt;The snap store comes with a surprisingly rich delivery mechanism consisting of &lt;a href="https://snapcraft.io/docs/channels" target="_blank" rel="noreferrer"&gt;tracks, risks and branches&lt;/a&gt;. This means that (among other things) changes to applications can be tested by way of an incremental roll out by those willing to help out - by subscribing to the &lt;code&gt;edge&lt;/code&gt; or &lt;code&gt;candidate&lt;/code&gt; channels.&lt;/p&gt;
&lt;h2 id="the-problem" class="relative group"&gt;The Problem &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#the-problem" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;While bumping the versions of the applications in snap packages &lt;a href="https://github.com/snapcrafters/signal-desktop/blob/325c06602d6bbb976afbabe48e16c688f1d70c94/.github/workflows/sync-version-with-upstream.yml" target="_blank" rel="noreferrer"&gt;can be done trivially&lt;/a&gt;, testing that the new application can launch on the Linux desktop and function correctly is more difficult - especially given the &amp;ldquo;headless&amp;rdquo; nature of CI systems, and the inherent complexity of some of the applications involved.&lt;/p&gt;
&lt;p&gt;Electron has, in my opinion, been a huge net win for the Linux desktop. Performance and early Wayland compatibility aside, the selection of mainstream applications available to the Linux desktop user is certainly much greater as a result. One downside is that each app is essentially a browser with lots of complex moving parts which can be difficult to maintain for packagers over time - and particularly so for a team of volunteers who may not be experts in the applications they help to maintain.&lt;/p&gt;
&lt;p&gt;In a &lt;a href="https://jnsgr.uk/2024/02/nixos-vms-in-github-actions/" target="_blank" rel="noreferrer"&gt;previous post&lt;/a&gt; I wrote about how KVM-acceleration is now available on Github Actions runners. While it&amp;rsquo;s certainly possible to just pull in various pieces of the Linux desktop using &lt;code&gt;apt&lt;/code&gt; directly on a Github Actions runner, the resulting configuration normally involves convoluted setup with VNC or similar. Such setups are usually fragile, and can be more difficult to reproduce locally - making it slower to debug any issues that do arise.&lt;/p&gt;
&lt;h2 id="lxd-desktop-vms" class="relative group"&gt;LXD Desktop VMs &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#lxd-desktop-vms" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Before working at Canonical, I must confess to having paid &lt;em&gt;very little&lt;/em&gt; attention to &lt;a href="https://canonical.com/lxd" target="_blank" rel="noreferrer"&gt;LXD&lt;/a&gt;. Since joining, it&amp;rsquo;s become one of my most used tools in my daily workflow. I had some early experience with LXD a few years ago when it essentially &amp;ldquo;just&amp;rdquo; did Ubuntu containers, but it&amp;rsquo;s evolved into a very competent hypervisor in its own right, providing both container and virtual machine images for numerous different Linux distributions. In more recent history, desktop virtual machines were introduced which gives a very fast way to boot into a desktop across multiple distributions.&lt;/p&gt;
&lt;p&gt;To boot into a Ubuntu 22.04 LTS desktop virtual machine, for example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;lxc launch images:ubuntu/22.04/desktop ubuntu --vm --console&lt;span class="o"&gt;=&lt;/span&gt;vga
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;As a side note, last year Canonical &lt;a href="https://ubuntu.com/blog/lxd_ui" target="_blank" rel="noreferrer"&gt;announced&lt;/a&gt; the LXD UI, which is a beautiful web UI for managing clusters of LXD servers, and includes a graphical web console for virtual machines - which is incredibly useful for testing software across versions and desktops.&lt;/p&gt;
&lt;h2 id="wrapping-lxd" class="relative group"&gt;Wrapping LXD &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#wrapping-lxd" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;After playing with LXD a bunch locally, I confirmed that between &lt;code&gt;lxc exec&lt;/code&gt;, &lt;code&gt;lxc file pull&lt;/code&gt; I had all I need. The commands were all relatively simple, but I wanted to ensure that the Github Actions I wrote were as maintainable as possible, so I decided to write a small wrapper for LXD, which ended up being named &lt;code&gt;ghvmctl&lt;/code&gt; (Github Virtual Machine Control) because naming is…. hard!&lt;/p&gt;
&lt;p&gt;There is nothing special about &lt;code&gt;ghvmctl&lt;/code&gt;, it is just a &lt;code&gt;bash&lt;/code&gt; script. Perhaps one day I&amp;rsquo;ll implement it in something a little more… rigorous? That said, it&amp;rsquo;s wrapping relatively few shell commands, with very few variables, and it&amp;rsquo;s been solid for several months now. The sum of &lt;code&gt;ghvmctl&lt;/code&gt;&amp;rsquo;s capabilities can be summarised as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Launch Ubuntu desktop VMs&lt;/li&gt;
&lt;li&gt;Dismiss any initial setup wizards&lt;/li&gt;
&lt;li&gt;Ensure that &lt;code&gt;gnome-screenshot&lt;/code&gt; is installed&lt;/li&gt;
&lt;li&gt;Provide a simple way to install and run snaps&lt;/li&gt;
&lt;li&gt;Provide a simple way to screenshot the whole screen, and the active window&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The script is mostly contained in a &lt;a href="https://github.com/snapcrafters/ghvmctl/blob/1ac4a99dd1c6f78226b60eda205cd06c6ac20dfa/src/ghvmctl" target="_blank" rel="noreferrer"&gt;single file&lt;/a&gt;, apart from &lt;a href="https://github.com/snapcrafters/ghvmctl/blob/1ac4a99dd1c6f78226b60eda205cd06c6ac20dfa/src/ghvmctl-runner" target="_blank" rel="noreferrer"&gt;&lt;code&gt;ghvmctl-runner&lt;/code&gt;&lt;/a&gt; which is pushed automatically into any VMs started by &lt;code&gt;ghvmctl&lt;/code&gt;, and provides a way for applications to be run with all the appropriate environment variables such that graphical applications can run when the VM is being controlled headlessly (such as &lt;code&gt;DISPLAY&lt;/code&gt;, &lt;code&gt;WAYLAND_DISPLAY&lt;/code&gt;, &lt;code&gt;XDG_SESSION_TYPE&lt;/code&gt;, etc.).&lt;/p&gt;
&lt;p&gt;There are very few dependencies for the script, but I decided to &lt;a href="https://github.com/snapcrafters/ghvmctl/blob/1ac4a99dd1c6f78226b60eda205cd06c6ac20dfa/snap/snapcraft.yaml" target="_blank" rel="noreferrer"&gt;package it as a snap&lt;/a&gt; to simplify installing it on Github runners. The snap is simple, containing just the two scripts mentioned above, and the LXC client. This also means you can install and use the tool locally should you wish to experiment with it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Install ghvmctl&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo snap install ghvmctl
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Allow ghvmctl to access the LXD socket&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo snap connect ghvmctl:lxd lxd:lxd
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Launch a VM and prepare for testing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ghvmctl prepare
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Install a snap from the store&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ghvmctl snap-install signal-desktop
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Run the snap on the desktop&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ghvmctl snap-run signal-desktop
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Wait a few seconds for the app to start...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Take screenshots and pull them back to $HOME/ghvmctl-screenshots&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ghvmctl screenshot-full
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ghvmctl screenshot-window
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;To simplify the installation and setup of &lt;code&gt;ghvmctl&lt;/code&gt;, there is also a &lt;a href="https://github.com/snapcrafters/ci/tree/8eb0566a765cd0196d7223734dd4cc0f3eb4521f/setup-ghvmctl" target="_blank" rel="noreferrer"&gt;Github Action&lt;/a&gt; which takes care of enabling KVM on the runner, initialising LXD, installing &lt;code&gt;ghvmctl&lt;/code&gt; and ensuring it has access to the LXD socket.&lt;/p&gt;
&lt;h2 id="building-an-integrated-workflow" class="relative group"&gt;Building An Integrated Workflow &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#building-an-integrated-workflow" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;By now, the Snapcrafters have quite a &lt;a href="https://github.com/snapcrafters/ci" target="_blank" rel="noreferrer"&gt;sophisticated collection&lt;/a&gt; of Github Actions which are used for managing the release lifecycle of snaps, but for me it was this piece that tied it all together for GUI applications. The actions can be summarised as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Parsing &lt;code&gt;snapcraft.yaml&lt;/code&gt; files for details such as name, architectures, version&lt;/li&gt;
&lt;li&gt;Building snaps locally on Github Actions runners when Pull Requests are made&lt;/li&gt;
&lt;li&gt;Building snaps across architectures on the Launchpad build farm when changes are merged&lt;/li&gt;
&lt;li&gt;Create a &amp;ldquo;Call for Testing&amp;rdquo; Github Issue with details of the &lt;code&gt;candidate&lt;/code&gt; revisions&lt;/li&gt;
&lt;li&gt;Follow up on the issue with screenshots in a comment&lt;/li&gt;
&lt;li&gt;Promote the snap to &lt;code&gt;stable&lt;/code&gt; when a maintainer issues the command&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of these things are particularly hard in their own right, but they amount to some complicated juggling of Github Actions artefacts and tokens for various repositories and external services.&lt;/p&gt;
&lt;h2 id="building-a-screenshot-action" class="relative group"&gt;Building A Screenshot Action &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#building-a-screenshot-action" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;The Github Action &lt;a href="https://github.com/snapcrafters/ci/tree/8eb0566a765cd0196d7223734dd4cc0f3eb4521f/get-screenshots" target="_blank" rel="noreferrer"&gt;responsible for collecting screenshots&lt;/a&gt; is used across multiple snaps to give maintainers a bit more confidence when releasing changes into the &lt;code&gt;stable&lt;/code&gt; channels for their snaps.&lt;/p&gt;
&lt;p&gt;The action makes use of &lt;code&gt;ghvmctl&lt;/code&gt; to launch VMs, install the &lt;code&gt;candidate&lt;/code&gt; snaps and collect screenshots of them. This turned out to be simple with the introduction of &lt;code&gt;ghvmctl&lt;/code&gt; - the complicated part turned out to be where to store the screenshots such that they could be published in a comment! Github provides image/file hosting for comments on issue &lt;em&gt;when the comments are made through the web UI&lt;/em&gt;. As far as I can tell, there is no way to submit a comment with an embedded picture from the Github API (let me know!), and I wasn&amp;rsquo;t keen to rely on a third party service such as Imgur.&lt;/p&gt;
&lt;p&gt;The solution we settled on was to create a &lt;a href="https://github.com/snapcrafters/ci-screenshots" target="_blank" rel="noreferrer"&gt;&lt;code&gt;ci-screenshots&lt;/code&gt;&lt;/a&gt;, which could be published to by the workflows of each snap repository. We will, over time, clear out older screenshots.&lt;/p&gt;
&lt;h2 id="end-result" class="relative group"&gt;End Result &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#end-result" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;An example of the end result can be seen in &lt;a href="https://github.com/snapcrafters/signal-desktop/issues/267" target="_blank" rel="noreferrer"&gt;this Github Issue&lt;/a&gt;. Let&amp;rsquo;s break down what happened.&lt;/p&gt;
&lt;p&gt;First, once a change was merged into the Signal Desktop snap repository, and the resulting snap was built for each of its target architectures:&lt;/p&gt;
&lt;p&gt;&lt;a href="01.png"&gt;
&lt;figure&gt;
&lt;picture
class="mx-auto my-0 rounded-md"
&gt;
&lt;source
srcset="https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/01_hu_fafbb694af97bb75.webp 330w,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/01_hu_1ccda47c0fbc34a.webp 660w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/01_hu_2580f508fb236d67.webp 1024w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/01_hu_89c072b70232a46e.webp 1320w
"
sizes="100vw"
type="image/webp"
/&gt;
&lt;img
width="2238"
height="694"
class="mx-auto my-0 rounded-md"
alt="complete ci workflow on github actions"
loading="lazy" decoding="async"
src="https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/01_hu_37a169e3d17a36e1.png" srcset="https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/01_hu_dd4a9f7b594b9d4f.png 330w,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/01_hu_37a169e3d17a36e1.png 660w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/01_hu_de66138f407ef2a9.png 1024w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/01_hu_6f5bce1fb8f383af.png 1320w
"
sizes="100vw"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As part of this process an issue was automatically created containing information about the new &lt;code&gt;candidate&lt;/code&gt; versions:&lt;/p&gt;
&lt;p&gt;&lt;a href="02.png"&gt;
&lt;figure&gt;
&lt;picture
class="mx-auto my-0 rounded-md"
&gt;
&lt;source
srcset="https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/02_hu_d11ec7d0d05027c9.webp 330w,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/02_hu_9ec42ca1fc2f112e.webp 660w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/02_hu_21bad717e4953f76.webp 1024w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/02_hu_2a1e4b2bd386a874.webp 1249w
"
sizes="100vw"
type="image/webp"
/&gt;
&lt;img
width="1249"
height="1260"
class="mx-auto my-0 rounded-md"
alt="example call for testing post for Signal Desktop"
loading="lazy" decoding="async"
src="https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/02_hu_80067b83b7fe31e7.png" srcset="https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/02_hu_44490b647e67e3b3.png 330w,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/02_hu_80067b83b7fe31e7.png 660w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/02_hu_6330c88e415662a4.png 1024w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/02.png 1249w
"
sizes="100vw"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A couple of minutes later, the bot followed up with a comment containing screenshots of the application running on the desktop:&lt;/p&gt;
&lt;p&gt;&lt;a href="03.png"&gt;
&lt;figure&gt;
&lt;picture
class="mx-auto my-0 rounded-md"
&gt;
&lt;source
srcset="https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/03_hu_17944afe0d371816.webp 330w,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/03_hu_44dd85c8159616ed.webp 660w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/03_hu_b658abbdec44e80c.webp 946w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/03_hu_b658abbdec44e80c.webp 946w
"
sizes="100vw"
type="image/webp"
/&gt;
&lt;img
width="946"
height="1458"
class="mx-auto my-0 rounded-md"
alt="Github Issue comment containing screenshots from an automated test run"
loading="lazy" decoding="async"
src="https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/03_hu_72ccc750b515132e.png" srcset="https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/03_hu_94f7e00cd1c90f0c.png 330w,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/03_hu_72ccc750b515132e.png 660w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/03.png 946w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/03.png 946w
"
sizes="100vw"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once I was content that the snap was working correctly, and I&amp;rsquo;d tested the revision out locally, I then issued a command to promote the snap into the &lt;code&gt;stable&lt;/code&gt; channel, where it was slowly rolled out across the user base:&lt;/p&gt;
&lt;p&gt;&lt;a href="04.png"&gt;
&lt;figure&gt;
&lt;picture
class="mx-auto my-0 rounded-md"
&gt;
&lt;source
srcset="https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/04_hu_9c93800eb9b1f694.webp 330w,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/04_hu_7482b899ecead064.webp 660w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/04_hu_a34852695c1eb548.webp 939w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/04_hu_a34852695c1eb548.webp 939w
"
sizes="100vw"
type="image/webp"
/&gt;
&lt;img
width="939"
height="391"
class="mx-auto my-0 rounded-md"
alt="Github Issue comment showing revision promotion workflow"
loading="lazy" decoding="async"
src="https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/04_hu_ed2dc7c734c9f31d.png" srcset="https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/04_hu_62f7b81e9d05693c.png 330w,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/04_hu_ed2dc7c734c9f31d.png 660w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/04.png 939w
,https://jnsgr.uk/2024/03/simplifying-snap-gui-testing/04.png 939w
"
sizes="100vw"
/&gt;
&lt;/picture&gt;
&lt;/figure&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can see examples of this working across multiple snaps:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/snapcrafters/gimp/issues/260" target="_blank" rel="noreferrer"&gt;gimp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/snapcrafters/discord/issues/184" target="_blank" rel="noreferrer"&gt;discord&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/snapcrafters/sublime-text/issues/59" target="_blank" rel="noreferrer"&gt;sublime-text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/snapcrafters/sublime-merge/issues/31" target="_blank" rel="noreferrer"&gt;sublime-merge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/snapcrafters/mattermost-desktop/issues/100" target="_blank" rel="noreferrer"&gt;mattermost-desktop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="summary" class="relative group"&gt;Summary &lt;span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"&gt;&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style="text-decoration-line: none !important;" href="#summary" aria-label="Anchor"&gt;#&lt;/a&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;We&amp;rsquo;re still in the process of refining and rolling out this process, but I hope that it will help reduce burden on maintainers over time, and result in fresher and more reliable desktop snaps in the &lt;a href="https://snapcraft.io" target="_blank" rel="noreferrer"&gt;Snap Store&lt;/a&gt;. If you&amp;rsquo;d like to get involved in Snapcrafters, reach out to me, post on the &lt;a href="https://forum.snapcraft.io/t/snapcrafters-reboot/24625" target="_blank" rel="noreferrer"&gt;Snapcraft Discourse&lt;/a&gt; or join the &lt;a href="https://matrix.to/#/#snapcrafters:matrix.org" target="_blank" rel="noreferrer"&gt;Matrix room&lt;/a&gt;.&lt;/p&gt;</description></item></channel></rss>