Skip to content

gradle-flatpak-sources

CI API docs Gradle Plugin Portal License: GPL-3.0-or-later CLA assistant Revved up by Develocity

A Gradle plugin that generates Flathub-compliant offline dependency manifests (flatpak-sources.json) for Flatpak builds.

Quick Start

Apply the settings plugin in settings.gradle.kts — it captures every dependency download from the very start of the build, with zero additional configuration:

// settings.gradle.kts
plugins {
    id("org.meshtastic.flatpak.sources.settings") version "0.2.1"
}

Then generate the manifest against an empty Gradle User Home, so every artifact is actually downloaded and therefore captured:

GRADLE_HOME=$(mktemp -d)
./gradlew --no-build-cache \
    -Dgradle.user.home="$GRADLE_HOME" \
    :app:assemble :captureFlatpakSources

The empty home is what forces the downloads — capture works by observing them, so anything already in caches/modules-2 is never fetched and never lands in the manifest. A fixed path like /tmp/flatpak-gradle-home is only empty the first time; reusing it silently produces a short manifest. --refresh-dependencies is not a substitute: it re-checks metadata and skips artifacts whose checksums still match.

--no-build-cache is about task outputs, not downloads. Neither flag concerns the configuration cache, which is supported from 0.2.1 on.

The output is written to build/flatpak-sources.json by default.

How It Works

  1. Settings plugin attaches a BuildService listener via BuildEventListenerRegistryInternal.onOperationCompletion before any dependency resolution occurs — the same pattern as gradle/github-dependency-graph-gradle-plugin. It also back-fills URLs for artifacts resolved during pluginManagement {} (before the listener attached) by inspecting the already-resolved settings classpath.

  2. captureFlatpakSources task reads the captured URL set, locates each artifact in caches/modules-2/files-2.1, computes its SHA-256, and emits the manifest. If an artifact is not in the local cache it falls back to downloading and hashing it.

  3. Output follows the Flatpak external data format: type: file, url, sha256, dest, dest-filename, plus Maven Central mirror URLs for redundancy.

Included Builds (build-logic/)

If your project uses an included build for convention plugins, apply the settings plugin there too — the plugin detects a pre-registered URL set and reuses it without creating a duplicate listener:

// build-logic/settings.gradle.kts
plugins {
    id("org.meshtastic.flatpak.sources.settings") version "0.2.1"
}

Use in Your Flatpak Manifest

# org.example.myapp.yaml
modules:
  - name: dependencies
    buildsystem: simple
    build-commands: ['true']
    sources:
      - flatpak-sources.json

Configuration

flatpakSources {
    // Output file (default: build/flatpak-sources.json)
    outputFile.set(layout.buildDirectory.file("flatpak-sources.json"))

    // Destination prefix in Flatpak sandbox (default: "offline-repository")
    destPrefix.set("offline-repository")

    // Task paths that must complete before capture runs
    mustRunAfterTasks.set(listOf(":app:assemble"))

    // Generate Maven Central mirror URLs (default: true)
    generateMirrors.set(true)

    // URL suffixes to exclude (default: sources + javadoc jars)
    excludeSuffixes.set(setOf("-sources.jar", "-javadoc.jar"))

    // Force-resolve platform-specific native artifacts not resolved on the generation host.
    // Use when generating a Linux Flatpak manifest on macOS or Windows.
    targetPlatforms.set(setOf("linux-x64", "linux-arm64"))

    // Maven coordinate templates for each platform target ({platform} is substituted).
    // Resolved transitively, so name only the artifacts you depend on directly — their own
    // platform-specific natives (skiko under compose-desktop, for instance) come along.
    platformDependencies.set(setOf(
        "org.jetbrains.compose.desktop:desktop-jvm-{platform}:1.11.0",
    ))
}

Cross-Platform Artifact Resolution

When building on macOS but targeting Linux Flatpak, platform-specific natives (Skiko renderers, Compose Desktop JARs, etc.) won't be resolved by Gradle's normal variant selection. targetPlatforms + platformDependencies forces them to download into the Gradle cache so they appear in the manifest:

flatpakSources {
    targetPlatforms.set(setOf("linux-x64", "linux-arm64"))
    platformDependencies.set(setOf(
        "org.jetbrains.compose.desktop:desktop-jvm-{platform}:1.11.0",
    ))
}

Each coordinate is resolved transitively, so you only name what your build depends on directly. A platform artifact's own natives are platform-specific too — and just as absent from the generation host's resolution — so they are pulled in for you: desktop-jvm-<platform> brings skiko-awt-runtime-<platform>, and maplibre-compose's desktop runtime brings both the maplibre-native-ffi and LWJGL natives. Copying those out of POMs you don't own is not required, and was a standing source of drift.

Each coordinate also resolves in its own configuration, so one entry that cannot be resolved does not cost the others; the warning names the coordinate that failed.

Requirements

  • Gradle 9.0+
  • JDK 17+

The configuration cache is supported from 0.2.1 on. Earlier versions required --no-configuration-cache: the capture task's action closed over the live URL set the build-operation listener writes to, so Gradle serialized a collection another thread was still mutating. Gradle 9.6.x wins that race often enough that it usually looked fine; 9.7.x does not, and fails the build outright.

On 0.2.0 specifically, pass --no-configuration-cache — that release also drops every captured URL on a reused configuration cache entry, emitting an empty manifest rather than failing. Both are fixed in 0.2.1 (#45).

Internal APIs

This plugin uses Gradle internal APIs (same trade-off as flatpak-gradle-generator):

  • org.gradle.internal.operations.BuildOperationListener
  • org.gradle.internal.resource.ExternalResourceReadBuildOperationType
  • org.gradle.internal.build.event.BuildEventListenerRegistryInternal

These APIs have been stable across Gradle 7–9.

License

Copyright (c) 2026 Meshtastic LLC. Licensed under GPL-3.0-or-later.

Contributing

See CONTRIBUTING.md for development setup, code style, and PR guidelines.

About

Gradle plugin for generating Flathub-compliant offline dependency manifests (flatpak-sources.json)

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages