Skip to content

feat: add support for snap core24#9517

Open
mmaietta wants to merge 6 commits into
masterfrom
snap-migration-core24
Open

feat: add support for snap core24#9517
mmaietta wants to merge 6 commits into
masterfrom
snap-migration-core24

Conversation

@mmaietta
Copy link
Copy Markdown
Collaborator

@mmaietta mmaietta commented Jan 18, 2026

Adds first-class core24 snap support through a new snapcraft config key, and restructures the snap target into per-core classes so each base gets its own code path.

The old snap key still works exactly as before — nothing breaks for existing users. The new snapcraft key gives you structured access to core18/20/22 (same behavior as before) and core24 (all-new).


New config shape

// electron-builder.json
{
  "snapcraft": {
    "base": "core24",
    "core24": {
      "useDestructiveMode": true,   // or useLXD / useMultipass / remoteBuild
      "extensions": ["gnome"],       // defaults to ["gnome"] unless destructive mode
      "stagePackages": ["default", "libdrm2"],
      "allowNativeWayland": true
    }
  }
}

For legacy bases:

{
  "snapcraft": {
    "base": "core22",
    "core22": {
      "confinement": "classic",
      "stagePackages": ["default", "libsecret-1-0"]
    }
  }
}

Pass-through mode for teams that manage their own snapcraft.yaml or via direct configuration (and verbatim usage by electron-builder):

{
  "snapcraft": {
    "base": "custom",
    "custom": { "yaml": "build/my-snapcraft.yaml" }
  }
}

core24 specifics

  • Default build uses the gnome extension (handles content snaps, GTK theming, GPU). Explicitly set extensions: [] to opt out.
  • gnome extension is incompatible with --destructive-mode. Setting useDestructiveMode: true while including gnome in extensions throws an InvalidConfigurationError with a clear message explaining why and what to do instead.
  • Wayland is enabled by default for core24. Set allowNativeWayland: false to disable (sets DISABLE_WAYLAND=1).
  • organize mappings are auto-generated at build time from the actual app directory, so helper binaries land under app/ inside the snap regardless of what Electron ships.
  • Remote build support (Launchpad) for multi-arch without native hardware.

Implementation changes

The old monolithic snap.ts (396 lines) is gone. In its place:

File Purpose
snap/SnapTarget.ts SnapTarget (the build entry point) + abstract SnapCore<T>
snap/coreLegacy.ts core18/20/22 — same behavior as the old snap.ts
snap/core24.ts core24 — new GNOME extension path, organize mapping, content snap plugs
snap/coreCustom.ts pass-through for custom snapcraft.yaml
snap/snapcraftBuilder.ts snapcraft CLI invocation (pack, remote-build, LXD, Multipass, destructive mode)
snap/snapcraft.d.ts TypeScript types for the snapcraft.yaml schema

LinuxTargetHelper.getSnapCore() reads snapcraft.base and returns the right implementation.


Tests

A new test-snap (core*) matrix job replaces the previous test-linux-native stub (which was if: false). It runs four parallel jobs, one per core:

  • core18, core20, core22 — Docker image built on ghcr.io/canonical/snapcraft:7_core22 (Snapcraft 7 / Jammy)
  • core24 — Docker image built on ghcr.io/canonical/snapcraft:8_core24 (Snapcraft 8 / Noble)

Both use --destructive-mode + SNAPCRAFT_BUILD_ENVIRONMENT=host so no LXD or Multipass daemon is required in CI.

The snapHeavyTest.ts suite also has install+launch tests (extract with unsquashfs, assert snap structure, run binary with --version) that run on native Linux CI runners with squashfs-tools available, skipped inside Docker.

The existing snapTest.ts unit tests still run and cover all the descriptor-level assertions (plugs, slots, extensions, compression, etc.) through snapshot testing.


Breaking changes

None for snap users. The snapcraft key is additive.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jan 18, 2026

🦋 Changeset detected

Latest commit: 2daad74

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 10 packages
Name Type
app-builder-lib Major
builder-util Major
dmg-builder Major
electron-builder-squirrel-windows Major
electron-builder Major
electron-forge-maker-appimage Major
electron-forge-maker-nsis-web Major
electron-forge-maker-nsis Major
electron-forge-maker-snap Major
electron-publish Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@socket-security
Copy link
Copy Markdown

socket-security Bot commented Jan 18, 2026

No dependency changes detected. Learn more about Socket for GitHub.

👍 No dependency changes detected in pull request

@kenvandine
Copy link
Copy Markdown

I am really happy to see this being worked on, thanks so much for this.

I would like to see it made clear that destructive mode should be discouraged, but available in cases where you can't use lxd or mulitpass. For example, destructive mode should never be used when building locally and in general it's difficult to trust the resulting build even in a docker container.

@mmaietta
Copy link
Copy Markdown
Collaborator Author

mmaietta commented May 9, 2026

@kenvandine Great callout. I wonder on what's the best way to approach this then.

Practically/ideally, we should have a destructive-mode available for the functional tests that can be run from other OS's => docker container. The e2e test is run on a native linux runner, so maybe we could test a configuration matrix?

destructive mode should never be used when building locally, and in general, it's difficult to trust the resulting build even in a docker container.

Definitely should call that out with the tsdoc guidance w.r.t. destructive mode though. That being said, we could also theoretically mark it as @private to prevent it from being documented or completely remove the field/property entirely - leaving behind a skeleton to still be able to run my test suite in the Docker container.

@kenvandine
Copy link
Copy Markdown

I think leaving the option is useful, just document is as not recommended. There are cases where people need it, but I think that's pretty rare.

@jnsgruk
Copy link
Copy Markdown

jnsgruk commented May 9, 2026

This is looking much better as a set of defaults.

…onfig key, and restructures the snap target into per-core classes so each base gets its own code path.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds first-class Snapcraft core24 support by introducing a new snapcraft configuration key and refactoring the snap target implementation into per-core builders (legacy core18/20/22, new core24, and custom pass-through).

Changes:

  • Introduces snapcraft config + new snap target architecture (SnapTarget + SnapCore* implementations) including a new core24 build path.
  • Adds/updates snap-related tests (unit + heavy integration) and a new CI matrix job to exercise core18/core20/core22/core24.
  • Extends schema/types/utilities to support the new configuration shape and Snapcraft YAML typing.

Reviewed changes

Copilot reviewed 28 out of 29 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
test/vitest-scripts/smart-config.ts Makes smart sharding skip list configurable via env and adjusts Linux skip settings.
test/src/linux/test-snap.sh Adds a script to run snap heavy tests in core-specific Docker images.
test/src/linux/snapTest.ts Updates snap unit tests to cover snapcraft config shape and core24 behaviors.
test/src/linux/snapHeavyTest.ts Expands heavy snap tests to run per-core (including install+launch checks).
test/src/linux/dockerfile-snapcraft-legacy Adds Docker image for legacy cores using Snapcraft 7.
test/src/linux/dockerfile-snapcraft Adds Docker image for core24 using Snapcraft 8.
test/src/helpers/launchAppCrossPlatform.ts Adds helper to launch an extracted snap binary under Xvfb for readiness checks.
test/snapshots/packageManagerTest.js.snap Updates snapshot outputs due to fixture/test changes.
test/snapshots/linux/snapTest.js.snap Updates/extends snapshots for new snapcraft/core24 behavior.
test/snapshots/linux/snapHeavyTest.js.snap Updates snapshots for new per-core heavy snap tests.
test/snapshots/globTest.js.snap Updates snapshot outputs due to fixture/test changes.
test/fixtures/test-app-one/index.js Adds SNAP_LAUNCH_TEST readiness output for integration tests.
scripts/fix-schema.js Adjusts schema post-processing for snap environment typing.
packages/builder-util/src/util.ts Adds utilities for array equality ignoring order and deep nullish removal.
packages/app-builder-lib/src/targets/snap/SnapTarget.ts New snap target entry point + SnapCore abstraction and publish config lookup.
packages/app-builder-lib/src/targets/snap/snapcraftBuilder.ts New Snapcraft CLI build orchestration (pack/prime+snap pack/remote-build/etc.).
packages/app-builder-lib/src/targets/snap/snapcraft.d.ts Adds TypeScript types for snapcraft.yaml (focused on core24).
packages/app-builder-lib/src/targets/snap/coreLegacy.ts Implements legacy core18/20/22 path (app-builder based).
packages/app-builder-lib/src/targets/snap/core24.ts Implements new core24 build path (GNOME extension, organize mapping, etc.).
packages/app-builder-lib/src/targets/snap/coreCustom.ts Implements pass-through mode for custom snapcraft.yaml.
packages/app-builder-lib/src/targets/snap.ts Removes the old monolithic snap target implementation.
packages/app-builder-lib/src/targets/LinuxTargetHelper.ts Adds getSnapCore() selection logic and Electron version gating per core.
packages/app-builder-lib/src/options/SnapOptions.ts Adds SnapcraftOptions + core24/custom option types; deprecates flat snap.
packages/app-builder-lib/src/linuxPackager.ts Updates snap target imports to new location.
packages/app-builder-lib/src/index.ts Exports SnapcraftOptions from the library entry point.
packages/app-builder-lib/src/configuration.ts Adds snapcraft top-level config key and deprecates snap.
packages/app-builder-lib/scheme.json Extends JSON schema with snapcraft/core24/custom and SnapcraftYAML definitions.
.github/workflows/test.yaml Replaces disabled native Linux stub with a snap core matrix + core24 native test.
.changeset/dark-moons-love.md Declares minor bumps for app-builder-lib and builder-util for new snapcraft support.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/app-builder-lib/src/targets/snap/coreLegacy.ts
Comment thread packages/app-builder-lib/src/targets/snap/snapcraftBuilder.ts Outdated
Comment thread packages/app-builder-lib/src/targets/snap/coreCustom.ts
Comment thread packages/app-builder-lib/src/targets/snap/core24.ts Outdated
Comment thread packages/app-builder-lib/src/targets/snap/core24.ts Outdated
Comment thread packages/app-builder-lib/scheme.json
Comment thread test/vitest-scripts/smart-config.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment