# Distribution channel inventory (the "visibility matrix"). # # One entry per place users can obtain LibreDB Studio. Human-maintained: # scripts/distribution-check.mjs READS this file and reports drift against # package.json - it never writes version numbers into it. Schema, tier and # SLA definitions, and maintenance rules (including when to update # last_bump_pr) live in docs/DISTRIBUTION.md ("Channel inventory and drift # check"). # # Field summary: # id/name/status/tier identity; status: live | pending | deprecated # kind the technical shape of the artefact (what it # literally is), independent of category (the audience-facing # bucket several kinds can share): one of release-assets | # container-image | package-registry | helm-chart | # package-manager | os-package | one-click-template | # paas-template | deploy-button | operator-catalog | # partner-catalog | curated-catalog | marketplace # category business bucket for docs/CHANNELS.md: # registries-releases | containers | kubernetes-operators | # package-managers | os-desktop | paas-catalogs | # deploy-recipes | cloud-marketplaces # platforms REQUIRED, non-empty list. Rendered and counted in # this canonical order in docs/CHANNELS.md: # linux | macos | windows | container | kubernetes | cloud # runtime REQUIRED. Who provides the Node.js the server runs # on, which is what decides whether raising # `engines.node` is a breaking change for this # channel's users (issue #326): # user_supplied - the user's own `node` executes # the payload, so the floor is theirs to meet. # channel_supplied - the channel provides it: # bundled in the artefact (image, snap, deb/rpm, # Windows zip, Flatpak, Tauri sidecar), inherited # from an image a template deploys, or installed as # a declared dependency (Homebrew node@24). # Not derivable from `kind`: deb/rpm are os-package # and bundle a private Node, npm is package-registry # and does not. # short_name optional; the display name docs/CHANNELS.md uses when # `name` is too long to scan. Falls back to `name`. # update.method ci_publish | commit | upstream_pr | manual_ui # update.sla every_release | minor_plus | major_only | on_demand # update.ci_enabled REQUIRED on, and allowed ONLY on, the switchable # channels (docker-hub-mirror, homebrew, snap, # winget, chocolatey): may release CI publish this # channel? The release workflow reads it, so turning # a channel off here is the whole switch - no secret # to delete, no workflow edit. The core release path # (github-release, docker-ghcr, npm, helm) and the # required release assets have no flag on purpose. # links tracking_issue / first_pr / last_bump_pr (nullable # until the first post-listing bump) / catalog / # upstream_repo / docs / get (user-facing "where do I # get it"; docs/CHANNELS.md resolves it as # get > catalog > upstream_repo, except a deprecated # channel renders no link at all, whatever these # fields hold) # pin.strategy local_file | remote_file | probe | none # pin.probe required when strategy == probe; one of the probe ids # defined in scripts/distribution-check.mjs # pin.urls required when strategy == probe; URL template(s) the # probe uses (see the probe's requiredUrls) # pin.architectures required for the snap-store-channel probe; list of # architectures to measure independently # pin.extract regex with ONE capture group; required for # local_file / remote_file; all matches in a source # must agree (ambiguity is reported, never resolved # to the first hit) channels: # ---- Tier 0: core registries, published directly by release CI ---------- - id: github-release name: GitHub Releases (standalone tarballs, deb/rpm, snap assets) short_name: GitHub Releases status: live category: registries-releases platforms: [linux, macos, windows] runtime: user_supplied tier: 0 kind: release-assets update: method: ci_publish sla: every_release links: catalog: https://github.com/libredb/libredb-studio/releases docs: docs/DISTRIBUTION.md pin: strategy: remote_file url: https://api.github.com/repos/libredb/libredb-studio/releases/latest extract: '"tag_name":\s*"(\d+\.\d+\.\d+)"' note: Probes the latest-release API; confirms the draft-first publish actually landed. - id: docker-ghcr name: Docker image (GHCR, canonical) short_name: Docker image (GHCR) status: live category: containers platforms: [container] runtime: channel_supplied tier: 0 kind: container-image update: method: ci_publish sla: every_release links: catalog: https://github.com/libredb/libredb-studio/pkgs/container/libredb-studio pin: strategy: probe probe: ghcr-tag-digest urls: token: https://ghcr.io/token?service=ghcr.io&scope=repository:libredb/libredb-studio:pull manifest: https://ghcr.io/v2/libredb/libredb-studio/manifests/{ref} note: Compares the image :latest resolves to against the released version tag. Anonymous pull token, no secret, so the probe also works from a fork. - id: docker-hub-mirror name: Docker Hub mirror (discoverability only) short_name: Docker Hub mirror status: live category: containers platforms: [container] runtime: channel_supplied tier: 0 kind: container-image update: method: ci_publish sla: every_release ci_enabled: true links: catalog: https://hub.docker.com/r/libredb/libredb-studio pin: strategy: probe probe: dockerhub-tag-digest urls: tag: https://hub.docker.com/v2/repositories/libredb/libredb-studio/tags/{ref} note: Mirror of GHCR; immutable-tag rules must stay semver-only. The push is secret-gated and skips silently, so an absent version tag here is how an expired DOCKER_HUB_TOKEN becomes visible. - id: npm name: npm package @libredb/studio (library + npx launcher) short_name: npm @libredb/studio status: live category: registries-releases platforms: [linux, macos, windows] runtime: user_supplied tier: 0 kind: package-registry update: method: ci_publish sla: every_release links: tracking_issue: https://github.com/libredb/libredb-studio/issues/110 first_pr: https://github.com/libredb/libredb-studio/pull/122 catalog: https://www.npmjs.com/package/@libredb/studio pin: strategy: remote_file url: https://registry.npmjs.org/-/package/@libredb/studio/dist-tags extract: '"latest":\s*"(\d+\.\d+\.\d+)"' note: Probes the npm dist-tags endpoint; confirms npm-publish.yml actually landed. # ---- Tier 1: packaged formats owned by this repo, CI-published ---------- - id: helm name: Helm chart (libredb.org repo + GHCR OCI + ArtifactHub) short_name: Helm chart status: live category: kubernetes-operators platforms: [kubernetes] runtime: channel_supplied tier: 1 kind: helm-chart update: method: ci_publish sla: every_release links: tracking_issue: https://github.com/libredb/libredb-studio/issues/138 first_pr: https://github.com/libredb/libredb-studio/pull/44 catalog: https://artifacthub.io/packages/helm/libredb-studio/libredb-studio docs: docs/HELM_CHART.md pin: strategy: local_file files: - charts/libredb-studio/Chart.yaml extract: 'appVersion: "(\d+\.\d+\.\d+)"' note: Enforcement lives in the required chart:check CI gate (#138); this row is visibility. - id: homebrew name: Homebrew tap (libredb/tap/libredb-studio) short_name: Homebrew tap status: live category: package-managers platforms: [macos, linux] runtime: channel_supplied tier: 1 kind: package-manager update: method: ci_publish sla: every_release ci_enabled: true links: tracking_issue: https://github.com/libredb/libredb-studio/issues/111 first_pr: https://github.com/libredb/libredb-studio/pull/122 upstream_repo: https://github.com/libredb/homebrew-tap pin: strategy: remote_file url: https://raw.githubusercontent.com/libredb/homebrew-tap/main/Formula/libredb-studio.rb extract: 'version "(\d+\.\d+\.\d+)"' note: Confirms the release-CI tap push actually landed. - id: snap name: Snap Store (stable channel, amd64+arm64) short_name: Snap Store status: live category: package-managers platforms: [linux] runtime: channel_supplied tier: 1 kind: package-manager update: method: ci_publish sla: every_release ci_enabled: true links: tracking_issue: https://github.com/libredb/libredb-studio/issues/113 first_pr: https://github.com/libredb/libredb-studio/pull/177 catalog: https://snapcraft.io/libredb-studio pin: strategy: probe probe: snap-store-channel architectures: - amd64 - arm64 urls: info: https://api.snapcraft.io/v2/snaps/info/libredb-studio note: Reads the stable channel of each architecture separately, so one lagging build is drift rather than a pass. Edge may legitimately differ from stable and is ignored. - id: linux-deb-rpm name: Linux .deb / .rpm packages (release assets) short_name: Linux .deb / .rpm status: live category: os-desktop platforms: [linux] runtime: channel_supplied tier: 1 kind: os-package update: method: ci_publish sla: every_release links: tracking_issue: https://github.com/libredb/libredb-studio/issues/112 first_pr: https://github.com/libredb/libredb-studio/pull/122 get: https://github.com/libredb/libredb-studio/releases/latest pin: strategy: none note: Built by nfpm from the tag in release-artifacts.yml; nothing to drift. - id: appimage # Quoted: an unquoted scalar containing ": " is a YAML mapping, not a string. name: "Desktop app (release assets: AppImage and GUI .deb, x64 + arm64)" short_name: Desktop app (AppImage, .deb) status: live category: os-desktop platforms: [linux] runtime: channel_supplied tier: 1 kind: release-assets update: method: ci_publish sla: every_release links: tracking_issue: https://github.com/libredb/libredb-studio/issues/232 first_pr: https://github.com/libredb/libredb-studio/pull/235 get: https://github.com/libredb/libredb-studio/releases/latest docs: desktop/README.md pin: strategy: none note: Both artifacts come per arch out of the one desktop-appimage job and are required by publish-release, so they cannot drift from the tag - hence no pin. The AppImage has shipped since 0.9.60 and the GUI .deb since 0.9.62. The AppImage is also what the in-repo Flatpak manifest repacks in flatpak-smoke.yml (packaging/flatpak, dormant - see the flathub channel); the GUI .deb (libredb-studio-desktop__.deb, distinct from the headless server package) is what FlatPark pins as extra-data. # ---- Tier 2: LibreDB-owned copies and listings, bumped by hand ---------- - id: railway-template name: Railway one-click template status: live category: paas-catalogs platforms: [cloud] runtime: channel_supplied tier: 2 kind: paas-template update: method: manual_ui sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/174 first_pr: https://github.com/libredb/libredb-studio/pull/67 catalog: https://railway.com/deploy/libredb-studio docs: deploy/railway/PUBLISH.md pin: strategy: local_file files: - deploy/railway/template.json - deploy/railway/README.md - deploy/railway/PUBLISH.md extract: 'libredb-studio:(\d+\.\d+\.\d+)' note: The published template is edited in the Railway dashboard; these three files must move together. - id: koyeb-deploy-button name: Koyeb deploy button (repo README) short_name: Koyeb deploy button status: live category: deploy-recipes platforms: [cloud] runtime: channel_supplied tier: 2 kind: deploy-button update: method: commit sla: on_demand links: get: https://github.com/libredb/libredb-studio/tree/main/deploy/koyeb docs: deploy/koyeb/README.md pin: strategy: none note: The button deploys ghcr.io latest by design; there is no version pin. - id: fly-io name: Fly.io launch config (repo fly.toml) short_name: Fly.io launch config status: live category: deploy-recipes platforms: [cloud] runtime: channel_supplied tier: 2 kind: paas-template update: method: commit sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/218 first_pr: https://github.com/libredb/libredb-studio/pull/219 get: https://github.com/libredb/libredb-studio/blob/main/fly.toml docs: docs/FLY.md pin: strategy: local_file files: - fly.toml extract: 'libredb-studio:(\d+\.\d+\.\d+)' note: Users deploy straight from the repo file; bump the tag here on release when convenient. - id: render name: Render Blueprint (repo render.yaml) short_name: Render Blueprint status: live category: deploy-recipes platforms: [cloud] runtime: channel_supplied tier: 2 kind: paas-template update: method: commit sla: on_demand links: get: https://github.com/libredb/libredb-studio/blob/main/render.yaml docs: docs/DISTRIBUTION.md pin: strategy: none note: Render builds from the repo Dockerfile (render.yaml dockerfilePath) on push, so there is no image tag to pin - the deployed version tracks whatever main builds. Like fly.toml, render.yaml is auto-detected at the repo root, so users deploy straight from the repo Blueprint. - id: unraid-ca name: Unraid Community Applications (libredb/unraid-templates) short_name: Unraid Community Apps status: live category: paas-catalogs platforms: [container] runtime: channel_supplied tier: 2 kind: one-click-template update: method: commit sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/283 catalog: https://ca.unraid.net/apps/libredb-studio-0a5x41a1cy1kay upstream_repo: https://github.com/libredb/unraid-templates docs: docs/DISTRIBUTION.md pin: strategy: remote_file url: https://raw.githubusercontent.com/libredb/unraid-templates/main/templates/libredb-studio.xml extract: 'libredb-studio:(\d+\.\d+\.\d+)' note: The container template is LibreDB-owned (libredb/unraid-templates), so a version bump is a commit in THAT repo - not a PR here and not an upstream PR - which is why this is tier 2 with a remote_file pin rather than local_file. Community Applications only serves what its own periodic catalog build picked up, so a bump reaches users one CA build after the commit. Submitted via ca.unraid.net/submit on 2026-08-04 and auto-approved (a non-duplicate Docker app with no plugin needs no human review). The `container` platform is deliberate and not a stand-in for cloud - the user installs a Docker container on their own Unraid server. # ---- Tier 3: upstream community catalogs, bumped via PR ----------------- - id: caprover-official name: CapRover official one-click apps short_name: CapRover official status: live category: paas-catalogs platforms: [cloud] runtime: channel_supplied tier: 3 kind: one-click-template update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/56 first_pr: https://github.com/caprover/one-click-apps/pull/1303 last_bump_pr: https://github.com/caprover/one-click-apps/pull/1315 upstream_repo: https://github.com/caprover/one-click-apps docs: deploy/caprover/README.md pin: strategy: remote_file url: https://raw.githubusercontent.com/caprover/one-click-apps/master/public/v4/apps/libredb-studio.yml extract: "defaultValue: '(\\d+\\.\\d+\\.\\d+)'" note: The single CapRover row. A LibreDB-owned 3rd-party repo (libredb/caprover-one-click-apps) served the app while this submission was in review and was retired once it merged; it had its own inventory entry until that duplicated CapRover in the coverage matrix as one live and one dead route to the same platform, with the dead one's URL no longer published. Its record lives in deploy/caprover/README.md, which is where a maintainer bumping the template already looks. Users install from the official catalog only - no third-party repo to add. - id: dokploy name: Dokploy template catalog status: live category: paas-catalogs platforms: [cloud] runtime: channel_supplied tier: 3 kind: paas-template update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/171 first_pr: https://github.com/Dokploy/templates/pull/931 last_bump_pr: https://github.com/Dokploy/templates/pull/1039 catalog: https://templates.dokploy.com upstream_repo: https://github.com/Dokploy/templates docs: deploy/dokploy/README.md pin: strategy: remote_file url: https://raw.githubusercontent.com/Dokploy/templates/canary/blueprints/libredb-studio/docker-compose.yml extract: 'libredb-studio:(\d+\.\d+\.\d+)' note: The blueprint serves 0.9.59, bumped there by Dokploy/templates#1039 (merged 2026-08-03). Every bump is an upstream pull request a maintainer has to merge, so this pin drifts behind the release by design and the drift row is the reminder to open the next one. That repo's default branch is `canary`, not main, and both of the pull requests merged there for this app (931 and 1039) targeted it, so the pin URL and any bump PR must use `canary`. This URL read `main` until now, which happened to report the same version and so hid the mistake. - id: cosmos name: Cosmos servapp marketplace status: live category: paas-catalogs platforms: [cloud] runtime: channel_supplied tier: 3 kind: one-click-template update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/172 first_pr: https://github.com/azukaar/cosmos-servapps-official/pull/218 upstream_repo: https://github.com/azukaar/cosmos-servapps-official docs: deploy/cosmos/README.md pin: strategy: remote_file url: https://raw.githubusercontent.com/azukaar/cosmos-servapps-official/master/servapps/LibreDB-Studio/cosmos-compose.json extract: 'libredb-studio:(\d+\.\d+\.\d+)' - id: kubero name: Kubero template catalog status: live category: paas-catalogs platforms: [cloud] runtime: channel_supplied tier: 3 kind: paas-template update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/173 first_pr: https://github.com/kubero-dev/kubero/pull/754 catalog: https://www.kubero.dev/templates upstream_repo: https://github.com/kubero-dev/kubero docs: deploy/kubero/README.md pin: strategy: remote_file url: https://raw.githubusercontent.com/kubero-dev/kubero/main/services/libredb-studio/app.yaml extract: 'ghcr\.io/libredb/libredb-studio\s+tag:\s*(\d+\.\d+\.\d+)' - id: sealos name: Sealos App Store template status: live category: paas-catalogs platforms: [cloud] runtime: channel_supplied tier: 3 kind: one-click-template update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/276 first_pr: https://github.com/labring-actions/templates/pull/739 catalog: https://sealos.io/products/app-store/libredb-studio upstream_repo: https://github.com/labring-actions/templates docs: docs/DISTRIBUTION.md pin: strategy: remote_file url: https://raw.githubusercontent.com/labring-actions/templates/kb-0.9/template/libredb-studio/index.yaml extract: 'libredb-studio:(\d+\.\d+\.\d+)' note: Sealos app-store templates live in labring-actions/templates (labring is the company behind Sealos) and go in as a direct template PR - no upstream issue first. That repo's default branch is `kb-0.9`, NOT main or master, so both the pin URL above and any bump PR must target it; a raw.githubusercontent URL on `main` 404s, and `master` carries a copy that can lag. The template pins the image in TWO places - the StatefulSet's `originImageName` annotation and the container `image` - so the shared all-matches-must-agree rule is what catches a half-finished bump here. Deploys SQLite on a 1 GiB PVC by default, with KubeBlocks-managed PostgreSQL as an opt-in storage backend, and ships AUTH_BOOTSTRAP=off so the deployment starts in strict mode. - id: truenas-scale name: TrueNAS SCALE community apps catalog short_name: TrueNAS SCALE apps status: live category: paas-catalogs platforms: [container] runtime: channel_supplied tier: 3 kind: one-click-template update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/278 first_pr: https://github.com/truenas/apps/pull/5501 catalog: https://apps.truenas.com/catalog/libredb-studio_community/ upstream_repo: https://github.com/truenas/apps docs: docs/DISTRIBUTION.md pin: strategy: remote_file url: https://raw.githubusercontent.com/truenas/apps/master/ix-dev/community/libredb-studio/ix_values.yaml extract: 'ghcr\.io/libredb/libredb-studio\s+tag:\s*(\d+\.\d+\.\d+)' note: Merged in truenas/apps#5501 (14 Aug 2026); live in the TrueNAS SCALE community catalog. The pin reads the ghcr repo and tag in ix-dev/community/libredb-studio/ix_values.yaml (the maintainer-edited source a bump PR touches) - the container_utils_image tag is a different repository and must not be matched. The built catalog also renders under trains/community/libredb-studio//. The user installs on their own TrueNAS box, so the platform is container, not cloud. - id: casaos name: CasaOS App Store status: live category: paas-catalogs platforms: [container] runtime: channel_supplied tier: 3 kind: one-click-template update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/277 first_pr: https://github.com/IceWhaleTech/CasaOS-AppStore/pull/992 upstream_repo: https://github.com/IceWhaleTech/CasaOS-AppStore docs: docs/DISTRIBUTION.md pin: strategy: remote_file url: https://raw.githubusercontent.com/IceWhaleTech/CasaOS-AppStore/main/Apps/LibreDBStudio/docker-compose.yml extract: 'libredb-studio:(\d+\.\d+\.\d+)' note: Merged in IceWhaleTech/CasaOS-AppStore#992 (7 Sep 2026); live in the CasaOS App Store. The pin reads the image tag in Apps/LibreDBStudio/docker-compose.yml, the file a bump PR touches. Installs a Docker container on the user's own device, so the platform is container. - id: okxlin-appstore name: 1Panel community app store (okxlin/appstore) short_name: 1Panel community store status: live category: paas-catalogs platforms: [container] runtime: channel_supplied tier: 3 kind: one-click-template update: method: upstream_pr sla: on_demand links: first_pr: https://github.com/okxlin/appstore/pull/6552 last_bump_pr: https://github.com/okxlin/appstore/pull/6938 catalog: https://github.com/okxlin/appstore/tree/localApps/apps/libredb-studio upstream_repo: https://github.com/okxlin/appstore docs: docs/DISTRIBUTION.md pin: strategy: probe probe: github-dir-max-version urls: catalog: https://api.github.com/repos/okxlin/appstore/contents/apps/libredb-studio note: The community-maintained app store for 1Panel, merged in okxlin/appstore#6552 (normalized by okxlin/appstore#6591) and bumped by the store's own Renovate, which carried it to 0.16.0 in okxlin/appstore#6938. The OFFICIAL 1Panel store declined us in 1Panel-dev/appstore#9398 - the maintainer keeps that catalog to projects above 10,000 stars and pointed at this one - so this row is the whole 1Panel presence, not a staging step. Measured as a directory listing rather than as a file, because the store publishes one directory per version under apps/libredb-studio and a fixed file URL would keep reporting a superseded version forever. - id: umbrel name: Umbrel App Store status: pending category: paas-catalogs platforms: [container] runtime: channel_supplied tier: 3 kind: one-click-template update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/214 first_pr: https://github.com/getumbrel/umbrel-apps/pull/5847 upstream_repo: https://github.com/getumbrel/umbrel-apps docs: docs/DISTRIBUTION.md pin: strategy: none note: PR getumbrel/umbrel-apps#5847 is open, so nothing is listed yet. On merge, flip to live and add a remote_file pin on https://raw.githubusercontent.com/getumbrel/umbrel-apps/master/libredb-studio/docker-compose.yml with extract 'libredb-studio:(\d+\.\d+\.\d+)' - the image is digest-pinned (tag@sha256) and the regex captures the semver and stops before the @. umbrelOS installs on the user's own device, so the platform is container. - id: easypanel name: Easypanel template catalog status: pending category: paas-catalogs platforms: [cloud] runtime: channel_supplied tier: 3 kind: paas-template update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/212 first_pr: https://github.com/easypanel-io/templates/pull/1446 catalog: https://easypanel.io/templates upstream_repo: https://github.com/easypanel-io/templates docs: docs/DISTRIBUTION.md pin: strategy: none note: PR easypanel-io/templates#1446 is open, so nothing is listed yet. On merge, flip to live and add a remote_file pin on https://raw.githubusercontent.com/easypanel-io/templates/main/templates/libredb-studio/meta.yaml with extract 'libredb-studio:(\d+\.\d+\.\d+)' - the version lives in meta.yaml's appServiceImage.default, not index.ts (which parameterises the image). Same PaaS-template shape as dokploy, so the platform is cloud. - id: portainer name: Portainer app templates status: pending category: paas-catalogs platforms: [container] runtime: channel_supplied tier: 3 kind: one-click-template update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/213 first_pr: https://github.com/portainer/templates/pull/262 upstream_repo: https://github.com/portainer/templates docs: docs/DISTRIBUTION.md pin: strategy: none note: PR portainer/templates#262 is open against the v3 branch (Portainer's current template format, NOT master), so nothing is listed yet. On merge, flip to live and add a remote_file pin on https://raw.githubusercontent.com/portainer/templates/v3/templates.json with extract 'libredb-studio:(\d+\.\d+\.\d+)'; both the pin URL and any bump PR must target v3. Deploys a container to the user's Docker host, so the platform is container. - id: operatorhub-community name: OperatorHub / OpenShift community operator catalogs short_name: OperatorHub / OpenShift status: live category: kubernetes-operators platforms: [kubernetes] runtime: channel_supplied tier: 3 kind: operator-catalog update: method: upstream_pr sla: every_release # Submission is automated from operator-release.yml (#656). The switch is # here because the submission can be legitimately impossible: the first # listing in a catalog is manual, an earlier submission may still be # unmerged, and OPERATOR_CATALOG_TOKEN may be absent - none of which is a # broken release. ci_enabled: true links: tracking_issue: https://github.com/libredb/libredb-studio/issues/152 first_pr: https://github.com/redhat-openshift-ecosystem/community-operators-prod/pull/10497 catalog: https://operatorhub.io/operator/libredb-studio-operator upstream_repo: https://github.com/redhat-openshift-ecosystem/community-operators-prod docs: docs/DISTRIBUTION.md pin: strategy: probe probe: github-dir-max-version urls: operatorhub-io: https://api.github.com/repos/k8s-operatorhub/community-operators/contents/operators/libredb-studio-operator openshift-console: https://api.github.com/repos/redhat-openshift-ecosystem/community-operators-prod/contents/operators/libredb-studio-operator note: Submitted automatically by the submit-catalogs job in operator-release.yml (#656); ci_enabled above is its switch. Both catalogs are listed - OpenShift console since 0.9.59 (bundle community-operators-prod#10497 merged 2026-07-27, FBC catalogs community-operators-prod#10581), operatorhub.io since k8s-operatorhub/community-operators#8794 merged 2026-09-08. These are the COMMUNITY catalogs, not the Red Hat certified one, so the OpenShift console lists the operator under Community with its unsupported-operator warning. Measured as two directory listings rather than one local file, because the committed bundle is only the submission source - a local pin would have read 0.14.1 while both catalogs still served 0.9.59. Each catalog is bumped by its own upstream PR and the two merge on different days, so a lagging one has to surface as its own disagreeing source. Catalog submissions start once the operator controller image is public on GHCR; community-operators-prod is contributed in FBC mode (fbc.enabled plus per-OCP-version catalog_mapping in ci.yaml). An FBC release is two upstream PRs - bundle first, then the rendered catalogs - and that second PR is only bot-created when the bundle version directory ships a release-config.yaml, which submit-catalogs writes. - id: yunohost name: YunoHost app catalog short_name: YunoHost status: live category: paas-catalogs platforms: [linux] runtime: channel_supplied tier: 3 kind: one-click-template update: method: upstream_pr sla: on_demand links: first_pr: https://github.com/YunoHost/apps/pull/3618 catalog: https://apps.yunohost.org/app/libredb_studio upstream_repo: https://github.com/YunoHost-Apps/libredb_studio_ynh docs: docs/DISTRIBUTION.md pin: strategy: remote_file url: https://raw.githubusercontent.com/YunoHost-Apps/libredb_studio_ynh/master/manifest.toml extract: 'version = "(\d+\.\d+\.\d+)~ynh\d+"' note: Listed by YunoHost/apps#3618, merged 2026-09-20. Unlike the other self-hosting catalogs here, the package installs no container; it unpacks the standalone Linux tarball under systemd and fetches its own Node 24 through YunoHost's `n`, which is why platforms is linux and the runtime is channel_supplied. The catalog entry points at a repository in the YunoHost-Apps organization - the package was written for this release, opened under libredb, and transferred on the maintainer's invitation, which is the route that repository's CI and packagers come with. A bump is therefore a pull request against THAT repository, and their autoupdate cron opens one when a release asset matching the manifest pattern appears. The pin reads past the `~ynh` packaging suffix and captures the application version, so a packaging-only change does not read as drift. apps.yunohost.org serves what its own periodic catalog build picked up, so the catalog link lags a merge by up to one build. # ---- Tier 4: partner and curated catalogs (not self-serve) -------------- - id: rancher-partner name: Rancher Partner Charts status: live category: kubernetes-operators platforms: [kubernetes] runtime: channel_supplied tier: 4 kind: partner-catalog update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/166 first_pr: https://github.com/rancher/partner-charts/pull/1158 catalog: https://www.suse.com/pcsc/viewVersionPage?versionID=26969 upstream_repo: https://github.com/rancher/partner-charts pin: strategy: none note: Merged in rancher/partner-charts#1158 (17 Aug 2026); live in Rancher Partner Charts and listed in the SUSE Solutions Catalog. Chart versions need no submission of ours - partner-charts runs partner-charts-ci update nightly against https://libredb.org/libredb-studio/ and has carried our releases since the listing without a pull request, taking the newest chart version at each run. So upstream_pr here is a copy change to the app-readme overlay (rancher/partner-charts#1168), not a version bump. Strategy stays none because the catalog names one directory per CHART version and the app version each ships is only inside its Chart.yaml, so a directory listing cannot measure it - unlike the two operator catalogs, whose directories are named for the app version. - id: koyeb-catalog name: Koyeb One-Click Apps catalog (curated by Koyeb) short_name: Koyeb One-Click Apps catalog status: pending category: cloud-marketplaces platforms: [cloud] runtime: channel_supplied tier: 4 kind: curated-catalog update: method: manual_ui sla: on_demand links: catalog: https://www.koyeb.com/deploy docs: deploy/koyeb/CATALOG_SUBMISSION.md pin: strategy: none - id: digitalocean name: DigitalOcean Marketplace status: live category: cloud-marketplaces platforms: [cloud] runtime: channel_supplied tier: 4 kind: marketplace update: method: manual_ui sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/72 first_pr: https://github.com/libredb/libredb-studio/pull/210 catalog: https://marketplace.digitalocean.com/apps/libredb-studio docs: deploy/digitalocean/README.md pin: strategy: remote_file url: https://marketplace.digitalocean.com/apps/libredb-studio # The listing's custom_data.version is serialized with escaped quotes in # Next.js flight data; also accept unescaped JSON, never generic page versions. extract: 'custom_data(?:\\)?"\s*:\s*\{\s*(?:\\)?"version(?:\\)?"\s*:\s*(?:\\)?"(\d+\.\d+\.\d+)(?:\\)?"' note: Measures the published Marketplace image, not the local Packer input. Builds and Vendor Portal submissions remain manual; each release summary carries the handoff checklist. - id: gcp-marketplace name: Google Cloud Marketplace short_name: Google Cloud Marketplace status: live category: cloud-marketplaces platforms: [kubernetes, cloud] runtime: channel_supplied tier: 4 kind: marketplace update: # Producer Portal, not a pull request: the listing, its version and its # Terraform module are submitted through Google's console and each change # goes through Google's own review, so nothing here can be CI-driven. method: manual_ui sla: on_demand links: catalog: https://console.cloud.google.com/marketplace/product/libredb-public/libredb-studio docs: docs/DISTRIBUTION.md pin: # The listed version is held in Google's Producer Portal and the artifacts # live in a private Artifact Registry, so there is no public file to read a # version out of. It is checked by hand against the portal. strategy: none - id: azure-marketplace name: Microsoft Azure Marketplace short_name: Azure Marketplace status: live category: cloud-marketplaces platforms: [cloud] runtime: channel_supplied tier: 4 kind: marketplace update: method: manual_ui sla: on_demand links: catalog: https://marketplace.microsoft.com/en-us/product/libredb.libredb-studio docs: deploy/azure/README.md pin: strategy: none note: Published 7 Sep 2026 as a free ("Get It Now") Azure Application solution template. The package version is recorded once, in deploy/azure/package-version.txt; naming it here as well is what let the two drift apart. There is no pin to add, because the listed version lives in Partner Center the way Google's lives in the Producer Portal. - id: aws-marketplace name: AWS Marketplace (free AMI product) short_name: AWS Marketplace status: live category: cloud-marketplaces platforms: [cloud] runtime: channel_supplied tier: 4 kind: marketplace update: # The AMI and every listing field are submitted through the AWS Marketplace # Management Portal, and a visibility change is reviewed by hand by Seller # Operations, so nothing here can be CI-driven. method: manual_ui sla: on_demand links: catalog: https://aws.amazon.com/marketplace/pp/prodview-tsahkrgdqpnws docs: deploy/aws/README.md pin: strategy: none note: Published 7 Sep 2026 as a free AMI product (0.14.1, ami-08263251d25dc8ced). This status is load-bearing rather than documentation - .github/workflows/aws-ami-build.yml reads it and stands down on every machine-triggered path while it is not live. Live opens that workflow's own release trigger, which fires only for a draft published by hand; no other workflow dispatches it, so an ordinary release still builds no AMI. There is no pin to read, because the listed version lives in the AWS Marketplace Management Portal the way Azure's lives in Partner Center; it is checked by hand against the portal. - id: civo-marketplace name: Civo Kubernetes Marketplace status: pending category: cloud-marketplaces platforms: [kubernetes] runtime: channel_supplied tier: 3 kind: marketplace update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/975 first_pr: https://github.com/civo/kubernetes-marketplace/pull/1076 upstream_repo: https://github.com/civo/kubernetes-marketplace pin: strategy: none note: The version lives in `libredb-studio/manifest.yaml` in the upstream repository, so there is nothing to pin here. The row flips to `live` when civo/kubernetes-marketplace#1076 merges. - id: winget name: winget community repository (LibreDB.Studio) short_name: winget status: live category: package-managers platforms: [windows] runtime: channel_supplied tier: 4 kind: package-manager update: method: ci_publish sla: every_release # The first listing merged 2026-07-31, so wingetcreate update now has a # manifest to carry forward and every release submits an update PR. ci_enabled: true links: tracking_issue: https://github.com/libredb/libredb-studio/issues/114 first_pr: https://github.com/microsoft/winget-pkgs/pull/402985 catalog: https://github.com/microsoft/winget-pkgs/tree/master/manifests/l/LibreDB/Studio upstream_repo: https://github.com/microsoft/winget-pkgs docs: docs/DISTRIBUTION.md pin: strategy: probe probe: github-dir-max-version urls: catalog: https://api.github.com/repos/microsoft/winget-pkgs/contents/manifests/l/LibreDB/Studio note: Listed since 0.9.59 (winget install LibreDB.Studio). winget publishes no floating "latest" document - the contents listing enumerates every published version - so the highest version it enumerates is the served state. A regex pin cannot express that (all matches in a source must agree), which is why this is a probe. The release job's own pre-check (package listed / version already merged / update PR already open) remains the publish-time guard. - id: chocolatey name: Chocolatey community repository (libredb-studio) short_name: Chocolatey status: live category: package-managers platforms: [windows] runtime: channel_supplied tier: 4 kind: package-manager update: method: ci_publish sla: every_release # Enabled on 2026-08-24, when the first submission (0.9.59) was approved by # moderator flcdrg. Until then push.chocolatey.org answered 403 for EVERY # version while an account's first submission is unapproved, which failed # the 0.9.60 and 0.9.61 release runs after the releases themselves had # published fine. The push step is non-blocking now (a 403 for a deep # moderation queue reports as a warning), so this flag no longer needs to # carry that job alone. ci_enabled: true links: tracking_issue: https://github.com/libredb/libredb-studio/issues/114 catalog: https://community.chocolatey.org/packages/libredb-studio docs: docs/DISTRIBUTION.md pin: strategy: remote_file url: https://community.chocolatey.org/api/v2/Packages()?%24filter=Id%20eq%20%27libredb-studio%27%20and%20IsLatestVersion extract: '(\d+\.\d+\.\d+)' note: Listed since 0.9.59 (choco install libredb-studio), approved 2026-08-24. The community feed publishes no floating "latest" document, so the pin filters the OData package list to IsLatestVersion - one document, one match, whatever the published version count. It sat at 0.9.59 while the job was disabled and has moved with every release since; it reads 0.13.6 today, one behind, which is moderation lag and not a broken pin. The feed lists APPROVED versions only, so a drift row here means the version is waiting on human moderation rather than that the push failed; the release run's job summary reports the push outcome and that version's PackageStatus. Trusted status is what removes the wait - docs/BACKLOG.md REL3. - id: flathub name: Flathub community catalog (org.libredb.Studio) short_name: Flathub status: deprecated category: package-managers platforms: [linux] runtime: channel_supplied tier: 4 kind: package-manager update: method: upstream_pr sla: on_demand links: tracking_issue: https://github.com/libredb/libredb-studio/issues/232 upstream_repo: https://github.com/flathub/flathub first_pr: https://github.com/flathub/flathub/pull/9538 docs: packaging/flatpak/README.md pin: strategy: none note: Not shipped, and not being pursued. The submission (flathub/flathub#9538) was declined on 2026-07-30 under Flathub's generative AI policy - the reviewer's position was that developing with an AI assistant disqualifies the app, and the PR carries their AI Slop label. We closed it ourselves rather than argue the point; the closing comment, which leaves the verifiable maintenance record on the thread, is at https://github.com/flathub/flathub/pull/9538#issuecomment-5136879185. Linux desktop users get the same app id from the flatpark channel, which is live - route every Flatpak instruction there. packaging/flatpak stays in the tree because the manifest still renders and flatpak-smoke.yml still builds it, but a resubmission would additionally have to be built from source (the AppImage repack is a second, independent blocker), so treat this as dormant rather than as work in progress. - id: flatpark name: FlatPark signed Flatpak remote (org.libredb.Studio) short_name: FlatPark (Flatpak) status: live category: package-managers platforms: [linux] runtime: channel_supplied tier: 4 kind: package-manager update: method: upstream_pr sla: every_release links: tracking_issue: https://github.com/libredb/libredb-studio/issues/241 upstream_repo: https://github.com/flatpark/flatpark first_pr: https://github.com/flatpark/flatpark/pull/158 catalog: https://flatpark.org/ docs: packaging/flatpark/README.md pin: strategy: none note: Repackages the GUI .deb as Flatpak extra-data - the artifact is fetched on the user's machine at install time, not built by FlatPark, and AppImages are not accepted there. The descriptor set is staged in packaging/flatpark and copied into a flatpark/flatpark fork as registry/org.libredb.Studio. Live since 0.9.62 (flatpark/flatpark#158 merged 2026-07-30), carrying the developer-approved flag - LibreDB packages its own app. FlatPark's bot now re-pins every release from resolve-update.sh, so the staged copy drifts by design and must stay out of release gates; a released version reaching the catalog is their CI's job, not ours, which is why there is no pin here. Sequencing question settled 2026-07-30 - FlatPark asks that an app not already be on Flathub, and the Flathub submission was declined, so this is now the only Flatpak channel and there is nothing to revisit. - id: appimagehub name: AppImageHub catalog (appimage.github.io) short_name: AppImageHub status: live category: os-desktop platforms: [linux] runtime: channel_supplied tier: 4 kind: curated-catalog update: method: upstream_pr sla: on_demand links: first_pr: https://github.com/AppImage/appimage.github.io/pull/3861 catalog: https://appimage.github.io/LibreDB_Studio/ get: https://github.com/libredb/libredb-studio/releases/latest docs: desktop/README.md pin: strategy: none note: Live since 2026-08-30 - AppImage/appimage.github.io#3861 merged and the listing serves at https://appimage.github.io/LibreDB_Studio/, linking the releases page rather than a frozen asset URL. One line in the catalog's data/LibreDB_Studio names this repository - their worker reads the releases API, takes the first AppImage asset matching x64 and re-reads it on every catalog rebuild, so no release bumps anything here and there is no served version to pin. What the listing depends on instead is the x64 AppImage staying startable for someone other than its builder - the review CI runs it under firejail --appimage on ubuntu-22.04 and fails the submission when no window appears, which is exactly what caught the 0770 AppRun.wrapped mode and the GLIBC_2.38 floor that 0.13.2 and 0.13.3 fixed. Both are now gated in the build (tests/unit/desktop-appimage-portability.test.ts, scripts/check-appimage-perms.mjs). The catalog is what appimagehub.com and the stores consuming its feed read - AppImage Pool, Zap. The repository URL is the form their README asks for, and measured over a 200-entry sample of their data/ directory it is what two thirds of the GitHub-hosted entries use (99 repository roots, 51 direct AppImage URLs, 50 non-GitHub hosts). It is also the only form that stays current - worker.sh resolves the releases API only when the URL has no "download" in it, so a direct asset URL freezes the listing at the version it names, which 47 of those 51 do (the Arduino IDE entry still points at 2.0.0-rc6). One consequence of the resolving form to keep in mind - the worker takes the newest release carrying a matching AppImage asset, prereleases included, so a prerelease with a desktop asset would become the listed download. Drafts cannot - their token has no read on this repository. Chart releases are skipped because they carry no AppImage, and linux-arm64 matches none of the asset patterns.