From d9f73926e4af264f02fff5a0897fd014dd63f6be Mon Sep 17 00:00:00 2001 From: Josh Knapp Date: Wed, 9 Sep 2026 16:50:44 -0700 Subject: [PATCH] feat(release): publish releases directly, and fix the install path in the notes Releases were created as drafts for one stated reason: nobody had run the plugin in the OBS GUI on any platform, so a human had to look before anything became visible. The first confirmed GUI load (Windows, OBS 32.2.2 on Windows 11, 2026-09-09) retired that gate, so `publish-release.sh` now posts `"draft": False` and the workflow no longer needs a human click. The caveats did not go away, they moved: the generated release notes now lead with what is actually confirmed (module loads and registers its source type, Windows only) and what is not (video rendering, A/V sync, latency, mid-show publisher restart, Linux and macOS in the GUI at all), and the per-platform table carries the rest. Also fixes the third and last copy of the wrong Windows install path. The release notes template told every downloader to extract into `%APPDATA%\obs-studio\plugins\`, which on Windows is OBS's config directory and is never scanned for plugins -- that is what stopped a director's correctly-shaped install from loading. The notes now carry a per-platform table (`C:\ProgramData\obs-studio\plugins\` on Windows), the exact finished path, a warning about Explorer's "Extract All..." wrapper folder, and how to confirm the load in the OBS log. Both failure modes are silent, which is precisely why they belong in the notes. Note the tradeoff now that nothing is held back: assets upload after the release row is created, so a release is briefly visible with no files attached. Called out in the script header. Verified by rendering the heredoc with a stub tag: backslash escaping survives into correct markdown, and the YAML parses. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01AzGnvQ6wfD7bw7PZN35ft9 --- .gitea/scripts/publish-release.sh | 62 +++++++++++++++++++++---------- .gitea/workflows/release.yml | 16 ++++---- README.md | 8 ++-- 3 files changed, 57 insertions(+), 29 deletions(-) diff --git a/.gitea/scripts/publish-release.sh b/.gitea/scripts/publish-release.sh index 7063492..0940b66 100755 --- a/.gitea/scripts/publish-release.sh +++ b/.gitea/scripts/publish-release.sh @@ -1,9 +1,15 @@ #!/usr/bin/env bash -# Creates a (draft) Gitea Release for the tag that triggered +# Creates a published Gitea Release for the tag that triggered # .gitea/workflows/release.yml, and uploads every archive in $DIST_DIR as a -# release asset. Draft because nobody has run this plugin in the OBS GUI on -# any platform yet -- a human still opens it and clicks Publish once that's -# no longer true (or once they're satisfied regardless). +# release asset. +# +# This used to create a DRAFT, on the grounds that nobody had run the plugin +# in the OBS GUI on any platform. That stopped being true on 2026-09-09, when +# the v0.1.0 Windows artifact loaded into OBS 32.2.2 on Windows 11 -- so the +# release publishes directly and the per-platform table below carries the +# remaining caveats instead. Assets upload AFTER the release row is created +# either way, so a release is briefly visible with no files attached; that is +# the tradeoff for not needing a human click. # # Required env: GITEA_TOKEN, SERVER, OWNER, REPO, TAG, SHA, DIST_DIR # Optional env: MACOS_BUNDLE_FOUND ("true"/"false", default "false") @@ -30,26 +36,44 @@ cat > "${NOTES_FILE}" < \`+\` -> +Extract the archive into your OBS plugins folder. **The directory is not the +same shape on every platform, and picking the wrong one fails silently -- OBS +logs nothing at all for a plugin it never finds:** + +| Platform | Extract into | +|---|---| +| Windows | \`C:\\ProgramData\\obs-studio\\plugins\\\` -- **not** \`%APPDATA%\\obs-studio\\\`, which is where OBS keeps its config and is never scanned for plugins | +| macOS | \`~/Library/Application Support/obs-studio/plugins/\` | +| Linux | \`~/.config/obs-studio/plugins/\` | + +Each archive's top-level folder already matches the shape OBS expects, so +extracting is the whole install step -- but check the result is exactly one +folder deep. Windows Explorer's "Extract All..." adds a folder named after the +zip unless you clear it from the destination box, which nests it one level too +far and is equally silent. On Windows the finished path must be: + +\`\`\` +C:\\ProgramData\\obs-studio\\plugins\\streamer-tools-camera\\bin\\64bit\\streamer-tools-camera.dll +\`\`\` + +To confirm it loaded, restart OBS and check Help -> Log Files -> View Current +Log for \`streamer-tools-camera\` under "Loaded Modules". Then in OBS: Sources -> \`+\` -> "streamer-tools Camera" -> fill in the server URL, room slug and read key from the room's settings page -> "Refresh camera list" -> pick a camera. @@ -73,7 +97,7 @@ print(json.dumps({ "tag_name": tag, "name": tag, "body": notes, - "draft": True, + "draft": False, "prerelease": False, })) PYEOF @@ -87,7 +111,7 @@ RESP="$(curl -sS -f -X POST \ "${SERVER}/api/v1/repos/${OWNER}/${REPO}/releases")" RELEASE_ID="$(python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])' <<<"${RESP}")" -echo "Created release id ${RELEASE_ID} (draft)." +echo "Created release id ${RELEASE_ID} (published; assets upload next)." shopt -s nullglob ASSETS=("${DIST_DIR}"/*) @@ -106,4 +130,4 @@ for f in "${ASSETS[@]}"; do > /dev/null done -echo "Done. Draft release: ${SERVER}/${OWNER}/${REPO}/releases/${RELEASE_ID}" +echo "Done. Release: ${SERVER}/${OWNER}/${REPO}/releases/${RELEASE_ID}" diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index e5bda7d..0ac86d6 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -1,14 +1,16 @@ name: Release # Packages a build of each platform into a downloadable archive and creates -# a (draft) Gitea Release for it, so the project owner and other directors +# a published Gitea Release for it, so the project owner and other directors # can grab a ready-to-use build instead of compiling from source. # # Runs only on a pushed version tag (see `on.push.tags` below) -- never on an -# ordinary push or PR, unlike build.yml. The release it creates is a DRAFT: -# it stays invisible to anyone without write access until a human explicitly -# opens it and clicks Publish, since nobody has run this plugin in the OBS -# GUI on any platform yet. +# ordinary push or PR, unlike build.yml. The release it creates is PUBLISHED +# immediately. It used to be a draft, gated on a human clicking Publish +# because nobody had run the plugin in the OBS GUI on any platform; the first +# confirmed GUI load (Windows, 2026-09-09) retired that. The caveats that +# remain live in the generated release notes, not in the draft flag -- see +# .gitea/scripts/publish-release.sh. # # The actual per-platform build commands live in .gitea/scripts/ and are the # same scripts .gitea/workflows/build.yml uses, so this workflow can't drift @@ -183,7 +185,7 @@ jobs: path: dist release: - name: Create Gitea Release (draft) + name: Create Gitea Release needs: [linux, macos, windows] runs-on: ubuntu-24.04 permissions: @@ -214,7 +216,7 @@ jobs: name: release-archive-windows-x64 path: dist - - name: Create draft release and upload assets + - name: Create release and upload assets run: .gitea/scripts/publish-release.sh env: GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} diff --git a/README.md b/README.md index 6f0a80e..916bb39 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,10 @@ match the vendored LiveKit binaries, which are also Apache-2.0 — see `.gitea/workflows/build.yml` builds, tests, and uploads CI-internal build artifacts on every push. `.gitea/workflows/release.yml` packages a tagged -build (`v*`) into a **draft** Gitea Release; a human still needs to open it -and click Publish. +build (`v*`) into a **published** Gitea Release. It created drafts until +2026-09-09, gated on a human clicking Publish because nobody had run the +plugin in the OBS GUI; the first confirmed GUI load retired that gate, and the +remaining caveats live in the generated release notes instead. The plugin is **functionally complete on Linux and verified end to end there** (module loads into real libobs, connects to a real LiveKit server through the @@ -78,7 +80,7 @@ scripts/livekit-dev-room.py - mints tokens for the integration test third_party/livekit/ - redistribution notices for the LiveKit binaries .gitea/scripts/ - the actual per-platform build commands, shared by build.yml and release.yml .gitea/workflows/build.yml - 3-platform CI matrix (every push/PR; never publishes) -.gitea/workflows/release.yml - packages + creates a draft Gitea Release (only on a `v*` tag push; see Status above) +.gitea/workflows/release.yml - packages + publishes a Gitea Release (only on a `v*` tag push; see Status above) ``` ## How it works -- 2.52.0