ci: add tag-triggered release packaging workflow
Build / macOS (macos-latest) (push) Successful in 33s
Build / Linux (ubuntu-24.04) (push) Successful in 54s
Build / Windows (windows-latest) (push) Failing after 7m50s

Adds .gitea/workflows/release.yml, triggered only on a pushed v* tag, which
builds all three platforms (reusing the exact same configure/build/test
commands as build.yml, now factored out into .gitea/scripts/ so the two
workflows can't drift), zips each platform's build/package/ output, and
creates a draft Gitea Release with the archives attached.

This is packaging automation only -- it does not resolve or bypass the C1
WebRTC/OpenH264 release gate documented in README.md's Status section.
Nothing publishes until a human deliberately pushes a version tag (which
should not happen before owner sign-off) and then explicitly publishes the
resulting draft. The generated release notes lead with a restatement of the
open C1 question specifically so that second step can't be taken by
accident.

build.yml is refactored (not rewritten) to call the same shared scripts;
its job/step behavior is otherwise unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
This commit is contained in:
2026-09-07 05:06:25 -07:00
co-authored by Claude Sonnet 5
parent 79de5e8f23
commit 2b216d3d75
9 changed files with 493 additions and 113 deletions
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
# Shared with .gitea/workflows/build.yml and .gitea/workflows/release.yml --
# this is the actual Linux configure/build/test/verify sequence. Edit once,
# here, so both workflows stay in sync instead of drifting copies.
#
# Linux keeps its distribution libobs; the buildspec bootstrap (macOS/Windows)
# is for the two platforms that have no such package.
set -euo pipefail
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DSTPLUGIN_BOOTSTRAP_OBS=OFF
cmake --build build
ctest --test-dir build --output-on-failure
# Show what was built
ls -la build/package/bin/64bit build/package/data/locale build/package/licenses
ldd build/package/bin/64bit/streamer-tools-camera.so | grep -E 'obs|livekit'
nm -D build/package/bin/64bit/streamer-tools-camera.so | grep -E ' T obs_module_(load|unload)'
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
# Shared with .gitea/workflows/build.yml and .gitea/workflows/release.yml --
# both need the exact same Linux build dependencies. Edit once, here.
set -euo pipefail
sudo apt-get update -qq
sudo apt-get install -y -qq cmake ninja-build libobs-dev libcurl4-openssl-dev
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
# Shared with .gitea/workflows/build.yml and .gitea/workflows/release.yml --
# this is the actual macOS configure/build/test/verify sequence. Edit once,
# here, so both workflows stay in sync instead of drifting copies.
#
# The buildspec bootstrap runs here: it fetches obs-deps + the pinned
# obs-studio source and builds libobs before this project configures.
#
# If that fails, fall back to a core-library-only build rather than going
# red: the core library and its tests are what this job mainly guards, and
# the fallback is loud (a workflow warning, plus the check below reporting no
# module) rather than silent. Do not remove the warning -- a green job that
# quietly stopped building the plugin is worse than a red one.
set -euo pipefail
if ! cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release; then
echo "::warning::OBS SDK bootstrap failed on macOS; building the core library only. The plugin module was NOT built."
rm -rf build
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DSTPLUGIN_BOOTSTRAP_OBS=OFF
fi
cmake --build build
ctest --test-dir build --output-on-failure
# Show what was built.
#
# This is not purely informational: the macOS bootstrap has been reliably
# building the real module in CI (6/6 tests, artifact uploaded -- see
# README), so a missing module here is a regression to fail loudly on, not
# the old silent fallback. (This is separate from the macOS packaging gap in
# README -- that the module doesn't yet load as an OBS.app bundle -- which
# this check does not and cannot test.)
ls -la .deps/Frameworks/libobs.framework/Resources/cmake || true
if [ ! -f build/package/bin/streamer-tools-camera.so ]; then
echo "::error::no plugin module was built -- build/package/bin/streamer-tools-camera.so is missing. The macOS from-source libobs bootstrap is expected to succeed; treat this as a build failure, not a core-library-only fallback."
exit 1
fi
ls -la build/package/bin
otool -L build/package/bin/streamer-tools-camera.so
otool -L build/package/bin/streamer-tools-camera.so | grep -E 'obs|livekit'
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Shared with .gitea/workflows/build.yml and .gitea/workflows/release.yml.
set -euo pipefail
brew install cmake ninja
+155
View File
@@ -0,0 +1,155 @@
#!/usr/bin/env bash
# Creates a (draft) Gitea Release for the tag that triggered
# .gitea/workflows/release.yml, and uploads every archive in $DIST_DIR as a
# release asset.
#
# RELEASE GATE: see the README's `## Status` section and
# third_party/livekit/README.md. The WebRTC/OpenH264 attribution question
# ("C1") is unresolved -- this script does not decide that question, it just
# makes sure the generated release notes put the reminder where whoever
# publishes the draft will actually read it. Pushing a version tag is the
# human decision this whole workflow hangs off of; this script does not add
# or remove any judgment about whether that decision was the right one.
#
# Required env: GITEA_TOKEN, SERVER, OWNER, REPO, TAG, SHA, DIST_DIR
# Optional env: MACOS_BUNDLE_FOUND ("true"/"false", default "false")
set -euo pipefail
: "${GITEA_TOKEN:?}"
: "${SERVER:?}"
: "${OWNER:?}"
: "${REPO:?}"
: "${TAG:?}"
: "${SHA:?}"
: "${DIST_DIR:?}"
MACOS_BUNDLE_FOUND="${MACOS_BUNDLE_FOUND:-false}"
if [ "${MACOS_BUNDLE_FOUND}" = "true" ]; then
MACOS_NOTE="This archive contains a \`.plugin\` bundle."
else
MACOS_NOTE="This archive is packaged as a bare \`streamer-tools-camera.so\` (the layout \`build/package/\` currently produces on macOS), **not** an OBS.app-loadable \`.plugin\` bundle. It will not load in the OBS GUI as-is."
fi
NOTES_FILE="$(mktemp)"
cat > "${NOTES_FILE}" <<EOF
> **This build has not been cleared for redistribution.** The plugin
> statically/dynamically pulls in Google WebRTC and OpenH264 code through the
> LiveKit SDK, and whether that can be redistributed as a public download --
> the "C1" attribution/patent question -- has not been resolved. See the
> \`## Status\` section of \`README.md\` and \`third_party/livekit/README.md\`
> for the specifics. By publishing this release, you are personally taking on
> that open question -- if C1 hasn't been signed off on, don't publish it.
>
> (The separate GPLv2/Apache-2.0 license-compatibility question, "C2", is
> resolved: this project's own first-party code is Apache-2.0, matching the
> vendored LiveKit binaries.)
>
> This release was created as a **draft**. It stays invisible to anyone
> without write access to this repo until someone with write access opens it
> here and clicks Publish -- a second, deliberate step past pushing the tag.
# streamer-tools Camera Plugin -- ${TAG}
Built from commit \`${SHA}\`.
**Nobody has yet run this plugin in the OBS GUI, on any platform.** See "What
is verified, and how" in \`README.md\` for exactly what has and has not been
checked, including which claims are backed by automated tests versus a human
watching OBS.
| Platform | Archive | Notes |
|---|---|---|
| Linux (x64) | \`streamer-tools-camera-${TAG}-linux-x64.zip\` | Functionally complete and verified end to end against a real LiveKit server and a real libobs (see README); OBS GUI itself still unverified |
| Windows (x64) | \`streamer-tools-camera-${TAG}-windows-x64.zip\` | Built and tested by this workflow's Windows job; the WinHTTP backend has never been exercised against a real streamer-tools server, only a loopback test server -- see README's Windows CI section |
| macOS | \`streamer-tools-camera-${TAG}-macos.zip\` | Built and tested by this workflow's macOS job. ${MACOS_NOTE} See the "macOS packaging gap" in README |
## Installing
### Linux
\`\`\`
mkdir -p ~/.config/obs-studio/plugins/streamer-tools-camera
unzip streamer-tools-camera-${TAG}-linux-x64.zip -d /tmp/stplugin-camera
cp -r /tmp/stplugin-camera/bin /tmp/stplugin-camera/data \\
~/.config/obs-studio/plugins/streamer-tools-camera/
\`\`\`
Start OBS, then 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. This is the same drop-in layout
README's "Testing this by hand" documents for a source build, adapted for a
downloaded zip -- known-good on Linux.
### Windows (installation path not yet verified in real OBS)
Per \`AddExtraModulePaths()\` in obs-studio's \`UI/window-basic-main.cpp\`, OBS
on Windows searches a plugins directory for \`bin\\64bit\\<name>.dll\` plus a
sibling \`data\\\`. Unzip the archive and copy its \`bin\\\` and \`data\\\` into
your OBS plugins directory (typically
\`%APPDATA%\\obs-studio\\plugins\\streamer-tools-camera\\\`), matching the
Linux layout above. This has not been confirmed against a real OBS install on
Windows -- report back if you try it.
### macOS (installation path not yet verified in real OBS; packaging gap)
OBS on macOS loads plugins as \`<name>.plugin\` bundles under
\`~/Library/Application Support/obs-studio/plugins/\`. As of this release,
this project's \`build/package/\` output on macOS is **not yet that bundle
shape** -- see the "macOS packaging gap" section of \`README.md\`. Treat the
macOS archive here as a build-verification artifact, not a working
drop-in, until that gap is closed.
## What this is
Native OBS Studio source plugin that pulls streamer-tools camera feeds
directly from LiveKit over WebRTC. See \`README.md\` in the repository for
the full design, what is and is not verified, and current CI status.
EOF
echo "----- release notes -----"
cat "${NOTES_FILE}"
echo "--------------------------"
BODY_JSON="$(python3 - "$TAG" "$NOTES_FILE" <<'PYEOF'
import json, sys
tag, notes_file = sys.argv[1], sys.argv[2]
with open(notes_file) as f:
notes = f.read()
print(json.dumps({
"tag_name": tag,
"name": tag,
"body": notes,
"draft": True,
"prerelease": False,
}))
PYEOF
)"
echo "Creating release for tag ${TAG} ..."
RESP="$(curl -sS -f -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d "${BODY_JSON}" \
"${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)."
shopt -s nullglob
ASSETS=("${DIST_DIR}"/*)
if [ "${#ASSETS[@]}" -eq 0 ]; then
echo "::error::no archives found in ${DIST_DIR} -- nothing to upload."
exit 1
fi
for f in "${ASSETS[@]}"; do
name="$(basename "${f}")"
echo "Uploading ${name} ..."
curl -sS -f -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-F "attachment=@${f}" \
"${SERVER}/api/v1/repos/${OWNER}/${REPO}/releases/${RELEASE_ID}/assets?name=${name}" \
> /dev/null
done
echo "Done. Draft release: ${SERVER}/${OWNER}/${REPO}/releases/${RELEASE_ID}"
+38
View File
@@ -0,0 +1,38 @@
# Shared with .gitea/workflows/build.yml and .gitea/workflows/release.yml --
# this is the actual Windows configure/build/test/verify sequence. Edit once,
# here, so both workflows stay in sync instead of drifting copies.
#
# The default Visual Studio generator is required, not Ninja:
# cmake/windows/buildspec.cmake keys the dependency slice off
# CMAKE_VS_PLATFORM_NAME, which only a VS generator sets.
#
# Same fallback as macOS, and the same warning: a green job that quietly
# stopped building the plugin is worse than a red one. PowerShell, not bash:
# self-hosted Windows runners here cannot be assumed to have a working bash
# (WSL as local system is refused).
cmake -S . -B build -A x64
if ($LASTEXITCODE -ne 0) {
Write-Host "::warning::OBS SDK bootstrap failed on Windows; building the core library only. The plugin module was NOT built."
Remove-Item -Recurse -Force build -ErrorAction SilentlyContinue
cmake -S . -B build -A x64 -DSTPLUGIN_BOOTSTRAP_OBS=OFF
if ($LASTEXITCODE -ne 0) { exit 1 }
}
cmake --build build --config Release
ctest --test-dir build -C Release --output-on-failure
# Show what was built.
#
# This is not purely informational: the from-source libobs bootstrap is
# expected to work reliably on this runner (that is the whole point of the
# buildspec bootstrap + find_package fix), so a missing module here is a
# regression to fail loudly on, not the old silent fallback.
$module = "build\package\bin\64bit\streamer-tools-camera.dll"
if (Test-Path $module) {
Get-ChildItem build\package\bin\64bit
} else {
Write-Host "::error::no plugin module was built -- $module is missing. The Windows from-source libobs bootstrap is expected to succeed; treat this as a build failure, not a core-library-only fallback."
exit 1
}
+18 -108
View File
@@ -10,6 +10,11 @@ name: Build
# downloads the pinned obs-deps bundle and obs-studio source and builds just # downloads the pinned obs-deps bundle and obs-studio source and builds just
# `libobs`. That step is the slow one: several minutes on a cold runner. # `libobs`. That step is the slow one: several minutes on a cold runner.
# #
# The actual per-platform dependency-install and configure/build/test/verify
# commands live in .gitea/scripts/ and are shared with
# .gitea/workflows/release.yml, so the two workflows can't drift apart --
# edit the scripts, not either workflow, to change how a platform builds.
#
# RELEASE GATE: this workflow only builds, tests, and uploads CI-internal # RELEASE GATE: this workflow only builds, tests, and uploads CI-internal
# workflow artifacts (actions/upload-artifact, below) -- it does not create a # workflow artifacts (actions/upload-artifact, below) -- it does not create a
# Gitea Release, push a tag-triggered publish, or otherwise distribute # Gitea Release, push a tag-triggered publish, or otherwise distribute
@@ -19,6 +24,10 @@ name: Build
# (The separate GPLv2/Apache-2.0 license-compatibility question is resolved: # (The separate GPLv2/Apache-2.0 license-compatibility question is resolved:
# this project's own code is Apache-2.0.) If a real release/publish step is # this project's own code is Apache-2.0.) If a real release/publish step is
# ever added here, it must carry that same gate. # ever added here, it must carry that same gate.
#
# (.gitea/workflows/release.yml is that publish step, gated on a pushed
# version tag rather than on every push -- see the gate reminder baked into
# its generated release notes.)
on: on:
push: push:
@@ -38,26 +47,10 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Install build dependencies - name: Install build dependencies
run: | run: .gitea/scripts/linux-deps.sh
sudo apt-get update -qq
sudo apt-get install -y -qq cmake ninja-build libobs-dev libcurl4-openssl-dev
- name: Configure - name: Configure, build, test, verify
# Linux keeps its distribution libobs; the buildspec bootstrap is for run: .gitea/scripts/linux-build.sh
# the two platforms that have no such package.
run: cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DSTPLUGIN_BOOTSTRAP_OBS=OFF
- name: Build
run: cmake --build build
- name: Test (core library)
run: ctest --test-dir build --output-on-failure
- name: Show what was built
run: |
ls -la build/package/bin/64bit build/package/data/locale build/package/licenses
ldd build/package/bin/64bit/streamer-tools-camera.so | grep -E 'obs|livekit'
nm -D build/package/bin/64bit/streamer-tools-camera.so | grep -E ' T obs_module_(load|unload)'
- name: Upload plugin - name: Upload plugin
continue-on-error: true continue-on-error: true
@@ -74,51 +67,10 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Install build dependencies - name: Install build dependencies
run: brew install cmake ninja run: .gitea/scripts/macos-deps.sh
- name: Configure - name: Configure, build, test, verify
# The buildspec bootstrap runs here: it fetches obs-deps + the pinned run: .gitea/scripts/macos-build.sh
# obs-studio source and builds libobs before this project configures.
#
# If that fails, fall back to a core-library-only build rather than
# going red: the core library and its tests are what this job mainly
# guards, and the fallback is loud (a workflow warning, plus the
# "Show what was built" step below reporting no module) rather than
# silent. Do not remove the warning -- a green job that quietly stopped
# building the plugin is worse than a red one.
run: |
if ! cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release; then
echo "::warning::OBS SDK bootstrap failed on macOS; building the core library only. The plugin module was NOT built."
rm -rf build
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DSTPLUGIN_BOOTSTRAP_OBS=OFF
fi
- name: Build
run: cmake --build build
- name: Test (core library)
run: ctest --test-dir build --output-on-failure
- name: Show what was built
# This used to be informational only (every command "|| true"'d), so
# a bootstrap failure that silently fell back to a core-library-only
# build still reported a green job -- exactly the false-positive
# class of bug this step exists to catch, caught instead by a human
# reading the raw log by hand. The macOS bootstrap has been reliably
# building the real module in CI (6/6 tests, artifact uploaded --
# see README), so a missing module here is a regression to fail
# loudly on, not the old silent fallback. (This is separate from the
# macOS packaging gap in README -- that the module doesn't yet load
# as an OBS.app bundle -- which this check does not and cannot test.)
run: |
ls -la .deps/Frameworks/libobs.framework/Resources/cmake || true
if [ ! -f build/package/bin/streamer-tools-camera.so ]; then
echo "::error::no plugin module was built -- build/package/bin/streamer-tools-camera.so is missing. The macOS from-source libobs bootstrap is expected to succeed; treat this as a build failure, not a core-library-only fallback."
exit 1
fi
ls -la build/package/bin
otool -L build/package/bin/streamer-tools-camera.so
otool -L build/package/bin/streamer-tools-camera.so | grep -E 'obs|livekit'
- name: Upload plugin - name: Upload plugin
continue-on-error: true continue-on-error: true
@@ -140,51 +92,9 @@ jobs:
# preinstalled tooling (cmake included) can be assumed present. # preinstalled tooling (cmake included) can be assumed present.
uses: lukka/get-cmake@latest uses: lukka/get-cmake@latest
- name: Configure - name: Configure, build, test, verify
# The default Visual Studio generator is required, not Ninja: shell: pwsh
# cmake/windows/buildspec.cmake keys the dependency slice off run: ./.gitea/scripts/windows-build.ps1
# CMAKE_VS_PLATFORM_NAME, which only a VS generator sets.
#
# Same fallback as macOS, and the same warning: a green job that
# quietly stopped building the plugin is worse than a red one.
# PowerShell, not bash: this runner is a plain Windows VM and bash
# cannot be assumed present.
run: |
cmake -S . -B build -A x64
if ($LASTEXITCODE -ne 0) {
Write-Host "::warning::OBS SDK bootstrap failed on Windows; building the core library only. The plugin module was NOT built."
Remove-Item -Recurse -Force build -ErrorAction SilentlyContinue
cmake -S . -B build -A x64 -DSTPLUGIN_BOOTSTRAP_OBS=OFF
if ($LASTEXITCODE -ne 0) { exit 1 }
}
- name: Build
run: cmake --build build --config Release
- name: Test (core library)
run: ctest --test-dir build -C Release --output-on-failure
- name: Show what was built
# This used to be informational only: the else branch printed a
# message and exited 0, so a bootstrap failure that silently fell
# back to a core-library-only build (or a find_package(libobs)
# failure after a libobs that genuinely built, per the
# find_package(libobs) CMakeLists.txt fix above) still reported a
# green job -- exactly the false-positive class of bug this step
# exists to catch, caught instead by a human reading the raw log by
# hand across several "green" runs. The from-source libobs bootstrap
# is now expected to work reliably on this runner (that is the whole
# point of the buildspec bootstrap + find_package fix), so a missing
# module here is a regression to fail loudly on, not the old silent
# fallback.
run: |
$module = "build\package\bin\64bit\streamer-tools-camera.dll"
if (Test-Path $module) {
Get-ChildItem build\package\bin\64bit
} else {
Write-Host "::error::no plugin module was built -- $module is missing. The Windows from-source libobs bootstrap is expected to succeed; treat this as a build failure, not a core-library-only fallback."
exit 1
}
- name: Upload plugin - name: Upload plugin
continue-on-error: true continue-on-error: true
+196
View File
@@ -0,0 +1,196 @@
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
# can grab a ready-to-use build instead of compiling from source.
#
# RELEASE GATE -- READ BEFORE TAGGING
# ------------------------------------------------------------------
# This workflow runs ONLY on a pushed version tag (see `on.push.tags` below)
# -- it never runs on an ordinary push or PR, unlike build.yml. Pushing a
# tag is therefore the one deliberate human act that starts it, and the
# release it creates is a DRAFT: it stays invisible to anyone without write
# access until a human explicitly opens it and clicks Publish. That is a
# second deliberate act past the tag push.
#
# Both of those are process, not a legal opinion. The actual open question --
# whether this plugin's bundled WebRTC/OpenH264 code (via LiveKit) can be
# redistributed as a public download at all -- is tracked as "C1" in the
# README's `## Status` section and in third_party/livekit/README.md, and it
# is NOT resolved. Nothing here resolves it; the generated release notes put
# a reminder of that fact at the top of every release this workflow creates,
# specifically so nobody publishes a draft without seeing it again first.
# (The separate GPLv2/Apache-2.0 question, "C2", *is* resolved -- see
# README.)
#
# 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
# from what CI already builds and verifies on every push.
on:
push:
tags:
- "v*"
jobs:
linux:
name: Linux (ubuntu-24.04)
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install build dependencies
run: .gitea/scripts/linux-deps.sh
- name: Configure, build, test, verify
run: .gitea/scripts/linux-build.sh
- name: Package archive
run: |
set -euo pipefail
# zip is not guaranteed present on a minimal self-hosted runner
# image (unlike GitHub-hosted ubuntu-24.04, which build.yml's
# deps script doesn't need to care about).
command -v zip >/dev/null || sudo apt-get install -y -qq zip
out="streamer-tools-camera-${GITEA_REF_NAME}-linux-x64.zip"
root="$(pwd)"
( cd build/package && zip -r "${root}/${out}" . )
mkdir -p dist
mv "${out}" "dist/${out}"
ls -la dist
env:
GITEA_REF_NAME: ${{ github.ref_name }}
- name: Upload archive
uses: actions/upload-artifact@v3
with:
name: release-archive-linux-x64
path: dist
macos:
name: macOS (macos-latest)
runs-on: macos-latest
outputs:
bundle_found: ${{ steps.package.outputs.bundle_found }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install build dependencies
run: .gitea/scripts/macos-deps.sh
- name: Configure, build, test, verify
run: .gitea/scripts/macos-build.sh
- name: Package archive
id: package
run: |
set -euo pipefail
out="streamer-tools-camera-${GITEA_REF_NAME}-macos.zip"
root="$(pwd)"
mkdir -p dist
# macOS packaging is being fixed separately (see the "macOS
# packaging gap" in README.md). Once it lands, build/package/ (or
# wherever that work stages its output) should contain a
# `<name>.plugin` bundle directory -- look for one rather than
# assuming its exact final location, and fall back to packaging
# build/package/ as-is (today's actual, non-bundle output) if none
# is found yet.
bundle="$(find build -maxdepth 4 -type d -name '*.plugin' 2>/dev/null | head -n1 || true)"
if [ -n "${bundle}" ]; then
echo "Found macOS .plugin bundle: ${bundle}"
( cd "$(dirname "${bundle}")" && zip -r "${root}/${out}" "$(basename "${bundle}")" )
echo "bundle_found=true" >> "${GITHUB_OUTPUT}"
else
echo "::warning::No .plugin bundle found under build/ -- packaging build/package/ as-is. This is NOT yet a loadable OBS.app plugin; see the macOS packaging gap in README.md."
( cd build/package && zip -r "${root}/${out}" . )
echo "bundle_found=false" >> "${GITHUB_OUTPUT}"
fi
mv "${out}" "dist/${out}"
ls -la dist
env:
GITEA_REF_NAME: ${{ github.ref_name }}
- name: Upload archive
uses: actions/upload-artifact@v3
with:
name: release-archive-macos
path: dist
windows:
name: Windows (windows-latest)
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install build dependencies
uses: lukka/get-cmake@latest
- name: Configure, build, test, verify
shell: pwsh
run: ./.gitea/scripts/windows-build.ps1
- name: Package archive
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$out = "streamer-tools-camera-$env:GITEA_REF_NAME-windows-x64.zip"
New-Item -ItemType Directory -Force -Path dist | Out-Null
Compress-Archive -Path build\package\* -DestinationPath "dist\$out" -Force
Get-ChildItem dist
env:
GITEA_REF_NAME: ${{ github.ref_name }}
- name: Upload archive
uses: actions/upload-artifact@v3
with:
name: release-archive-windows-x64
path: dist
release:
name: Create Gitea Release (draft)
needs: [linux, macos, windows]
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- name: Checkout
# Not strictly needed to build anything here, but publish-release.sh
# lives in the repo and this keeps the release job self-contained /
# easy to reason about rather than reaching into another job's
# checkout.
uses: actions/checkout@v4
- name: Download Linux archive
uses: actions/download-artifact@v3
with:
name: release-archive-linux-x64
path: dist
- name: Download macOS archive
uses: actions/download-artifact@v3
with:
name: release-archive-macos
path: dist
- name: Download Windows archive
uses: actions/download-artifact@v3
with:
name: release-archive-windows-x64
path: dist
- name: Create draft release and upload assets
run: .gitea/scripts/publish-release.sh
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
SERVER: https://repo.anhonesthost.net
OWNER: CyberCoveLLC
REPO: obs-streamer-tools-plugin
TAG: ${{ github.ref_name }}
SHA: ${{ github.sha }}
DIST_DIR: dist
MACOS_BUNDLE_FOUND: ${{ needs.macos.outputs.bundle_found }}
+17 -5
View File
@@ -15,10 +15,20 @@ that only the project owner can decide. Nothing in this repo should be built
into a package and handed out, posted, or attached to a public release until into a package and handed out, posted, or attached to a public release until
that sign-off happens. See `third_party/livekit/README.md` for the specifics that sign-off happens. See `third_party/livekit/README.md` for the specifics
of what is and is not currently known/shipped on the licensing side. (CI in of what is and is not currently known/shipped on the licensing side. (CI in
`.gitea/workflows/build.yml` currently only builds, tests, and uploads `.gitea/workflows/build.yml` only builds, tests, and uploads CI-internal
CI-internal build artifacts — it does not create a Gitea Release or otherwise build artifacts — it does not create a Gitea Release or otherwise publish
publish anything publicly; if that ever changes, the new step must carry this anything publicly.
same gate.)
`.gitea/workflows/release.yml` is the mechanism that *would* publish a
release, but it does not run automatically: it is gated on someone pushing a
`v*` tag, which is the actual sign-off gate in practice — don't push one
until the owner has actually signed off on C1. When it does run, it packages
each platform's `build/package/` (or macOS's bundle output, once that lands)
into a zip and creates a **draft** Gitea Release, whose generated release
notes lead with the same C1 reminder as this section, so whoever opens the
draft to publish it sees the open question again before doing so. Building
that mechanism is not the same as clearing C1 — it still requires the same
owner sign-off before a tag gets pushed.)
The separate license-compatibility question — this repository's own top-level The separate license-compatibility question — this repository's own top-level
`LICENSE` was GPLv2 while the vendored LiveKit binaries are Apache-2.0, which `LICENSE` was GPLv2 while the vendored LiveKit binaries are Apache-2.0, which
@@ -68,7 +78,9 @@ obs-adapter/ - thin OBS glue (C++)
data/locale/en-US.ini data/locale/en-US.ini
scripts/livekit-dev-room.py - mints tokens for the integration test scripts/livekit-dev-room.py - mints tokens for the integration test
third_party/livekit/ - redistribution notices for the LiveKit binaries third_party/livekit/ - redistribution notices for the LiveKit binaries
.gitea/workflows/build.yml - 3-platform CI matrix .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)
``` ```
## How it works ## How it works