feat: Playnite library sync plugin + exporter
A two-part Punktfunk plugin that syncs the Playnite library into the host
game library as the `playnite` provider:
- exporter/ — a minimal C# Playnite GenericPlugin ("Punktfunk Sync") that
writes punktfunk-library.json on every library change. Reading Playnite's
live-locked LiteDB from outside isn't robust, so this adapter runs inside
Playnite. Builds net462 via reference assemblies; packaged as a .pext.
- src/ — the TS plugin (on @punktfunk/host, rom-manager shape): watches the
export, embeds covers as data URLs, reconciles via
PUT /library/provider/playnite, with a console-hosted web UI + standalone
fallback + CLI. Launch = playnite://playnite/start/<id>, run by the host
in the interactive session so Playnite performs the real launch.
Verified locally: backend tsc + 23 tests + biome clean, SPA build, C#
exporter build + .pext pack.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
# CI for @punktfunk/plugin-playnite (Gitea Actions).
|
||||
# build — the TS plugin + SPA: lint, typecheck, test, bundle (mirrors the rom-manager plugin CI).
|
||||
# exporter — the C# Playnite extension → a `.pext`, built net462 with the .NET SDK on Linux (no
|
||||
# Windows/MSBuild needed) and uploaded as a workflow artifact.
|
||||
# publish — npm publish to the Gitea registry on a `v*` tag.
|
||||
# Installs resolve @punktfunk/* from the Gitea registry via the bunfig scope map + REGISTRY_TOKEN;
|
||||
# everything else (effect, react, tailwind…) comes from npm.
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
tags: ['v*']
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-24.04
|
||||
container:
|
||||
image: oven/bun:1
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
# oven/bun's slim base ships neither git nor a CA bundle — actions/checkout's HTTPS fetch needs both.
|
||||
- name: Install git + CA certs
|
||||
run: apt-get update && apt-get install -y --no-install-recommends ca-certificates git nodejs
|
||||
- uses: actions/checkout@v4
|
||||
- name: Registry auth
|
||||
env:
|
||||
TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||
run: |
|
||||
test -n "$TOKEN" || { echo "REGISTRY_TOKEN secret is empty"; exit 1; }
|
||||
printf '//git.unom.io/api/packages/unom/npm/:_authToken=%s\n' "$TOKEN" > "$HOME/.npmrc"
|
||||
- name: Install
|
||||
run: bun install --frozen-lockfile
|
||||
- name: Lint & format
|
||||
run: bunx biome check
|
||||
- name: Typecheck (backend)
|
||||
run: bunx tsc --noEmit
|
||||
- name: Test (engine)
|
||||
run: bun test
|
||||
- name: Build backend + SPA
|
||||
run: bun run build:all
|
||||
- name: Typecheck (UI)
|
||||
working-directory: ui
|
||||
run: bunx tsc --noEmit
|
||||
- name: Sanity — plugin default export is a valid PluginDef
|
||||
run: |
|
||||
bun -e 'import p from "./dist/index.js"; const d = p.default; if (d?.name !== "playnite" || typeof d?.main !== "function") { console.error("bad default export", d); process.exit(1); } console.log("ok:", d.name)'
|
||||
|
||||
exporter:
|
||||
runs-on: ubuntu-24.04
|
||||
container:
|
||||
image: mcr.microsoft.com/dotnet/sdk:8.0
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
# The SDK image is Debian but ships neither git (for checkout) nor zip (for packaging).
|
||||
- name: Install git + zip
|
||||
run: apt-get update && apt-get install -y --no-install-recommends git zip ca-certificates nodejs
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build exporter (net462)
|
||||
run: dotnet build exporter/PunktfunkSync.csproj -c Release
|
||||
- name: Package .pext
|
||||
run: |
|
||||
mkdir -p "$GITHUB_WORKSPACE/out"
|
||||
cd exporter/bin/Release
|
||||
zip -j -X "$GITHUB_WORKSPACE/out/punktfunk-sync.pext" extension.yaml PunktfunkSync.dll
|
||||
unzip -l "$GITHUB_WORKSPACE/out/punktfunk-sync.pext"
|
||||
# v3: Gitea's API rejects upload-artifact@v4.
|
||||
- name: Upload .pext
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: punktfunk-sync-pext
|
||||
path: out/punktfunk-sync.pext
|
||||
|
||||
publish:
|
||||
needs: [build, exporter]
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
runs-on: ubuntu-24.04
|
||||
container:
|
||||
image: oven/bun:1
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Install git + CA certs
|
||||
run: apt-get update && apt-get install -y --no-install-recommends ca-certificates git nodejs
|
||||
- uses: actions/checkout@v4
|
||||
- name: Registry auth
|
||||
env:
|
||||
TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
||||
run: |
|
||||
test -n "$TOKEN" || { echo "REGISTRY_TOKEN secret is empty"; exit 1; }
|
||||
printf '//git.unom.io/api/packages/unom/npm/:_authToken=%s\n' "$TOKEN" > "$HOME/.npmrc"
|
||||
- name: Install
|
||||
run: bun install --frozen-lockfile
|
||||
- name: Tag matches package version
|
||||
run: |
|
||||
TAG="${GITHUB_REF_NAME#v}"
|
||||
PKG="$(node -p "require('./package.json').version")"
|
||||
test "$TAG" = "$PKG" || { echo "tag $GITHUB_REF_NAME != package version $PKG"; exit 1; }
|
||||
- name: Publish (prepublishOnly builds backend + SPA)
|
||||
run: bun publish
|
||||
Reference in New Issue
Block a user