Split release publishing into a separate public distribution repo
Build Check / build (push) Successful in 21s
Release Plugin / release (push) Failing after 18s

Gitea has no per-release visibility override -- a repo is public or
private for everything (raw files, releases, API), confirmed against
Gitea's own docs/issue tracker. So manifest.json and release zips now
publish to a dedicated public repo (JellyfinSyncPlus-repo) via Gitea's
Contents API, while this source repo stays private. The v0.2.0.0 release
already pushed under the old (source-repo-only) version of this pipeline
is now stale; the next tag will publish correctly under the new split.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-09 17:21:04 +02:00
co-authored by Claude Sonnet 5
parent 6eb63449a9
commit 1d2246c5e2
5 changed files with 159 additions and 72 deletions
+49 -7
View File
@@ -149,13 +149,55 @@ Two different loops -- do not conflate them:
briefly interrupts the live, shared Jellyfin instance -- **do not do this
routinely; only for actual multi-friend sync test sessions, and confirm
with the user first.**
3. **Release distribution (later, once stable):** package as a versioned zip
+ `meta.json`, host a plugin-repository manifest via Gitea (raw file URLs
or release attachments both work, Jellyfin just needs HTTP(S) access to
the manifest + zip), add the repo URL in Jellyfin's dashboard. Mirrors
MR-Discord's tag -> Gitea Actions -> build pipeline, just producing a
plugin zip instead of a Docker image. Slow iteration loop -- not for
development, only for shipping tested versions.
3. **Release distribution -- DONE (Phase 5, built 2026-07-09).** Package as a
versioned zip + `manifest.json`, host via Gitea, add the repo URL in
Jellyfin's dashboard. Mirrors MR-Discord's tag -> Gitea Actions -> build
pipeline, just producing a plugin zip instead of a Docker image.
- **Source repo (`JellyfinSyncPlus`) stays private; a separate public repo
(`JellyfinSyncPlus-repo`) holds only `manifest.json` and release zips.**
Confirmed via Gitea's own docs/issue tracker: there's no way to make
individual release assets public while the repo itself stays private --
repo visibility is all-or-nothing, covering raw files, releases, and API
access alike. So the two are fully decoupled: CI builds from the private
source repo (has the checkout + build context) but publishes the
release and updates the manifest on the separate public repo, using the
same `RELEASE_TOKEN` (Gitea personal access tokens are user-scoped, not
repo-scoped, so one token works against both repos as long as the
owning account has write access to each).
- `dev/package-release.sh` -- builds Release config, zips the DLL,
computes its MD5 checksum, derives the release download URL (pointing
at the *public* repo). Live-tested locally twice (once before, once
after the public/private split) -- produces a real, valid zip + a
`manifest.json` schema-verified against a real published Jellyfin
plugin repo's actual file, not just assumed from memory.
- `dev/publish-manifest.sh` -- fetches the public repo's current
`manifest.json` via Gitea's Contents API (or starts fresh on the very
first release), merges in this version via `dev/update_manifest.py`,
and pushes it back via the same API. No git clone of the public repo
needed.
- `.github/workflows/release.yml` -- on a `v*` tag push: builds
(including `dev/extract-private-refs.sh`'s CI equivalent, pulling the
two private SDK assemblies straight from the pinned
`linuxserver/jellyfin:10.11.6` image via `docker cp`), packages,
creates a Gitea release + uploads the zip on the *public* repo, then
publishes the manifest there too.
- `.github/workflows/build.yml` -- plain build-check on every push/PR to
`master`, mirroring MR-Discord's `build.yml` pattern.
- **Live-verified 2026-07-09, partially**: tagged and pushed `v0.2.0.0`
against the *first* version of this pipeline (before the public/private
split existed) -- confirmed the workflow actually ran, created a real
Gitea release with the zip attached, and committed a real
`manifest.json`. That run published to the private source repo itself,
which is exactly the mistake the public/private split above exists to
fix; the updated, split version hasn't had a live tag-triggered CI run
yet as of this note -- the local packaging half is tested, the
`publish-manifest.sh` Contents API calls are syntax/logic-checked but
not yet exercised against a real Gitea instance.
- Once a plugin is actually installed from this repo, Jellyfin has no
hot-reload -- same as local dev, a server restart is required. On the
real k8s deployment that's the "confirm with the user first" milestone
action from the "Dev / test / iterate workflow" section above, not a
routine step.
## Known friction / risks (flagged going in, not discovered later)