Problem
App icons and metadata (name, description, summary, ui, required) live in a centralized release/ repo:
release/index-v2 — JSON catalog of every app
release/images/<app>-128.png — icons
Adding or updating an app requires a manual commit to release/. Apps cannot ship metadata changes alongside their own code — they're decoupled from their own description and icon.
Proposal
Each app pushes its own icon and metadata during its existing promote step. Drop the central release/ catalog.
Who reads release/ today
| Component |
What it reads |
store cache (storage/cache.go:192) |
releases/<channel>/index-v2 every 60 min |
store icon proxy (api/icon_proxy.go:23) |
releases/stable/images/<app>-128.png |
platform image proxy (backend/rest/proxy.go:39) |
releases/<channel>/images/<app>-128.png |
platform snap metadata (backend/snap/model/snap.go:36) |
builds /rest/proxy/image?... URLs from snapd /v2/find responses |
snapd is not in the loop. It's a passthrough — it returns whatever media[].url and description the backing store API hands it.
Today's app promote step
Each app's .drone.jsonnet (e.g. bitwarden/.drone.jsonnet) on the stable branch runs:
release publish — uploads snap binary + version files to S3
release promote -n <app> -a <arch> — copies releases/rc/<app>.<arch>.version to releases/stable/
Neither step pushes icon or metadata.
Migration shape
App side — extend syncloud-release promote (or add a subcommand) to also upload <app>-128.png and metadata.json (name, description, summary, ui, required) to s3://apps.syncloud.org/apps/<app>/metadata/. The icon can come from the snap's own snap/meta/gui/icon.png — no new file in the app repo. Each app's drone pipeline already calls release promote on stable, so no new CI step is needed; just a richer payload.
Store side (syncloud/store):
storage/cache.go:192 — switch from a single index-v2 fetch to per-app metadata.json fetches
api/icon_proxy.go:23 — redirect to the per-app path instead of releases/stable/images/
- Open question: how to know which apps exist without
index-v2. Options:
- S3 prefix listing
promote rewrites a small apps.json index
- keep a minimal ID list in
release/ (degenerate case of option 2)
Platform side (this repo):
backend/rest/proxy.go:39 — rewrite proxy target to the new per-app path
backend/snap/model/snap.go:36 — unchanged; still builds /rest/proxy/image?app=... URLs, only the upstream target moves
snapd — no changes.
Scope
Two files in store/, one file in platform/, one new upload command in store/cmd/release/. The hardest decision is the app-list mechanism, not the wiring.
Related repos
- syncloud/store
- syncloud/release (to be retired)
- syncloud/snapd (no change expected)
Problem
App icons and metadata (name, description, summary, ui, required) live in a centralized
release/repo:release/index-v2— JSON catalog of every apprelease/images/<app>-128.png— iconsAdding or updating an app requires a manual commit to
release/. Apps cannot ship metadata changes alongside their own code — they're decoupled from their own description and icon.Proposal
Each app pushes its own icon and metadata during its existing
promotestep. Drop the centralrelease/catalog.Who reads
release/todaystorecache (storage/cache.go:192)releases/<channel>/index-v2every 60 minstoreicon proxy (api/icon_proxy.go:23)releases/stable/images/<app>-128.pngplatformimage proxy (backend/rest/proxy.go:39)releases/<channel>/images/<app>-128.pngplatformsnap metadata (backend/snap/model/snap.go:36)/rest/proxy/image?...URLs from snapd/v2/findresponsessnapd is not in the loop. It's a passthrough — it returns whatever
media[].urlanddescriptionthe backing store API hands it.Today's app promote step
Each app's
.drone.jsonnet(e.g.bitwarden/.drone.jsonnet) on thestablebranch runs:release publish— uploads snap binary + version files to S3release promote -n <app> -a <arch>— copiesreleases/rc/<app>.<arch>.versiontoreleases/stable/Neither step pushes icon or metadata.
Migration shape
App side — extend
syncloud-release promote(or add a subcommand) to also upload<app>-128.pngandmetadata.json(name, description, summary, ui, required) tos3://apps.syncloud.org/apps/<app>/metadata/. The icon can come from the snap's ownsnap/meta/gui/icon.png— no new file in the app repo. Each app's drone pipeline already callsrelease promoteon stable, so no new CI step is needed; just a richer payload.Store side (
syncloud/store):storage/cache.go:192— switch from a singleindex-v2fetch to per-appmetadata.jsonfetchesapi/icon_proxy.go:23— redirect to the per-app path instead ofreleases/stable/images/index-v2. Options:promoterewrites a smallapps.jsonindexrelease/(degenerate case of option 2)Platform side (this repo):
backend/rest/proxy.go:39— rewrite proxy target to the new per-app pathbackend/snap/model/snap.go:36— unchanged; still builds/rest/proxy/image?app=...URLs, only the upstream target movessnapd — no changes.
Scope
Two files in
store/, one file inplatform/, one new upload command instore/cmd/release/. The hardest decision is the app-list mechanism, not the wiring.Related repos