diff --git a/.github/workflows/build-linux-packages.yml b/.github/workflows/build-linux-packages.yml new file mode 100644 index 0000000..9d29f52 --- /dev/null +++ b/.github/workflows/build-linux-packages.yml @@ -0,0 +1,77 @@ +name: Build Linux packages (.deb / .tar.xz) + +on: + release: + types: [published] + workflow_dispatch: + inputs: + version: + description: 'Release version to package (e.g. 2.5.1)' + required: true + +permissions: + contents: write + +jobs: + build-linux-packages: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install packaging tools + run: | + sudo apt-get update -qq + sudo apt-get install -y -qq unzip xz-utils dpkg-dev + + - name: Resolve version + id: version + run: | + VERSION="${{ inputs.version }}" + if [ -z "$VERSION" ]; then + VERSION="${GITHUB_REF_NAME#v}" + fi + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Download official Linux zip + run: | + VERSION="${{ steps.version.outputs.version }}" + mkdir -p /tmp/droidcam + URL="$(gh api repos/dev47apps/droidcam-obs-plugin/releases/tags/$VERSION \ + --jq '.assets[] | select(.name | test("linux")) | .browser_download_url' \ + 2>/dev/null | head -1)" + if [ -z "$URL" ]; then + URL="https://github.com/dev47apps/droidcam-obs-plugin/releases/download/$VERSION/droidcam_obs_${VERSION}_linux_x86_64.zip" + fi + echo "Downloading $URL" + for i in 1 2 3 4 5 6; do + if curl -fsSL -o /tmp/droidcam/plugin.zip "$URL"; then + break + fi + echo "download attempt $i failed, retrying in 20s" + sleep 20 + done + test -s /tmp/droidcam/plugin.zip || { + echo "error: failed to download the official Linux zip" + exit 1 + } + ls -lh /tmp/droidcam/plugin.zip + + - name: Unpack and build packages + run: | + VERSION="${{ steps.version.outputs.version }}" + mkdir -p /tmp/droidcam/unpacked + unzip -o /tmp/droidcam/plugin.zip -d /tmp/droidcam/unpacked + packaging/build-linux.sh /tmp/droidcam/unpacked "$VERSION" + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: droidcam-obs-linux-packages + path: dist/* + + - name: Attach to GitHub Release + if: github.event_name == 'release' + uses: softprops/action-gh-release@v2 + with: + files: dist/* diff --git a/packaging/README.md b/packaging/README.md new file mode 100644 index 0000000..749d384 --- /dev/null +++ b/packaging/README.md @@ -0,0 +1,40 @@ +# Linux packaging (.deb / .tar.xz) + +Repackages the official DroidCam OBS Linux zip into a Debian package and a +generic .tar.xz, without compiling anything. + +## How it works + +The workflow triggers when a GitHub Release is published (or manually, with a +version input), downloads the official Linux zip from the release assets, +unpacks it, and runs `packaging/build-linux.sh`: + +- `droidcam-obs__amd64.deb` installs the plugin into the system OBS + plugin directories (binary in `/usr/lib/x86_64-linux-gnu/obs-plugins`, data + in `/usr/share/obs/obs-plugins/droidcam-obs`). +- `droidcam-obs--linux-x86_64.tar.xz` mirrors the zip layout plus + `install.sh`, `README.TXT` and `LICENSE` when present. + +Because the artifacts are built from the official release binary, there are no +compiler dependencies, no library name pinning, and no risk of the built +plugin silently diverging from what the maintainers tested. If upstream ever +renames or drops the Linux zip, the workflow fails loudly at the download +step. + +## Building locally + +No build dependencies are required. Download the official zip, unpack it, and +run the script from the repo root: + + curl -LO https://github.com/dev47apps/droidcam-obs-plugin/releases/download/2.5.1/droidcam_obs_2.5.1_linux_x86_64.zip + unzip -o droidcam_obs_2.5.1_linux_x86_64.zip -d unpacked + packaging/build-linux.sh unpacked 2.5.1 + +Artifacts are written to `dist/`. + +## Notes + +- The plugin is a library that OBS loads from its plugins directory, not a + standalone application, so AppImage is not a natural format for it. +- Fedora ships its own RPM (`obs-studio-plugin-droidcam`) and Arch has AUR + packages, so this packaging targets Debian/Ubuntu plus a manual fallback. diff --git a/packaging/build-linux.sh b/packaging/build-linux.sh new file mode 100755 index 0000000..944d98d --- /dev/null +++ b/packaging/build-linux.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +# +# Repackages the official DroidCam OBS Linux zip into a Debian package (.deb) +# and a generic .tar.xz. No compilation is involved. +# +# Usage: packaging/build-linux.sh +# directory that contains droidcam-obs/ with +# bin/64bit/droidcam-obs.so and data/ +# release version, e.g. 2.5.1 +# +# Outputs are written to ./dist/ (relative to the current directory): +# droidcam-obs__amd64.deb +# droidcam-obs--linux-x86_64.tar.xz + +set -euo pipefail + +ZIP_DIR="${1:?usage: build-linux.sh }" +VERSION="${2:?usage: build-linux.sh }" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PKG_NAME="droidcam-obs" +ARCH="amd64" +PLUGIN_DIR="$ZIP_DIR/droidcam-obs" +PLUGIN_SO="$PLUGIN_DIR/bin/64bit/droidcam-obs.so" +DATA_DIR="$PLUGIN_DIR/data" +LIB_DIR="/usr/lib/x86_64-linux-gnu/obs-plugins" +DATA_INSTALL_DIR="/usr/share/obs/obs-plugins/$PKG_NAME" +DOC_DIR="/usr/share/doc/$PKG_NAME" + +if [[ ! -f "$PLUGIN_SO" ]]; then + echo "error: $PLUGIN_SO not found (did you unpack the official Linux zip?)" >&2 + exit 1 +fi +if [[ ! -d "$DATA_DIR" ]]; then + echo "error: $DATA_DIR not found" >&2 + exit 1 +fi + +OUT_DIR="$PWD/dist" +STAGE="$(mktemp -d)" +trap 'rm -rf "$STAGE"' EXIT + +DEB_ROOT="$STAGE/deb" +TXZ_ROOT="$STAGE/txz/droidcam-obs-$VERSION" + +mkdir -p "$DEB_ROOT/DEBIAN" "$DEB_ROOT$LIB_DIR" "$DEB_ROOT$DATA_INSTALL_DIR/locale" "$DEB_ROOT$DOC_DIR" "$TXZ_ROOT/droidcam-obs/bin/64bit" "$TXZ_ROOT/droidcam-obs/data" + +# Binary plugin +cp "$PLUGIN_SO" "$DEB_ROOT$LIB_DIR/droidcam-obs.so" +cp "$PLUGIN_SO" "$TXZ_ROOT/droidcam-obs/bin/64bit/droidcam-obs.so" + +# Plugin data (icons, locale) +cp -R "$DATA_DIR/." "$DEB_ROOT$DATA_INSTALL_DIR/" +cp -R "$DATA_DIR/." "$TXZ_ROOT/droidcam-obs/data/" + +# Keep the generic tarball self-contained, mirroring the official zip +for f in install.sh README.TXT LICENSE; do + if [[ -f "$ZIP_DIR/$f" ]]; then + cp "$ZIP_DIR/$f" "$TXZ_ROOT/" + fi +done + +# Debian metadata +{ + echo "droidcam-obs ($VERSION) unstable; urgency=medium" + echo "" + echo " * $VERSION release package." + echo " - Installs droidcam-obs.so into the system OBS plugins directory" + echo " - Installs plugin data (icons, locale) into /usr/share/obs/obs-plugins" + echo "" + echo " -- DroidCam OBS Plugin contributors $(date -R)" +} > "$DEB_ROOT$DOC_DIR/changelog" +gzip -9n "$DEB_ROOT$DOC_DIR/changelog" +cp "$SCRIPT_DIR/debian/copyright" "$DEB_ROOT$DOC_DIR/copyright" +sed "s/@VERSION@/$VERSION/" "$SCRIPT_DIR/debian/control.in" > "$DEB_ROOT/DEBIAN/control" + +# Normalize package permissions (dpkg-deb otherwise preserves the build umask) +find "$DEB_ROOT" -type d -exec chmod 755 {} + +find "$DEB_ROOT" -type f ! -name 'droidcam-obs.so' -exec chmod 644 {} + +chmod 755 "$DEB_ROOT$LIB_DIR/droidcam-obs.so" + +mkdir -p "$OUT_DIR" +dpkg-deb --build --root-owner-group "$DEB_ROOT" "$OUT_DIR/${PKG_NAME}_${VERSION}_${ARCH}.deb" >/dev/null +tar -C "$STAGE/txz" -cJf "$OUT_DIR/${PKG_NAME}-${VERSION}-linux-x86_64.tar.xz" "droidcam-obs-$VERSION" + +echo "Built:" +ls -lh "$OUT_DIR" diff --git a/packaging/debian/control.in b/packaging/debian/control.in new file mode 100644 index 0000000..fb630e5 --- /dev/null +++ b/packaging/debian/control.in @@ -0,0 +1,12 @@ +Package: droidcam-obs +Version: @VERSION@ +Section: video +Priority: optional +Architecture: amd64 +Maintainer: DroidCam OBS Plugin contributors +Depends: obs-studio (>= 30.0), libstdc++6 +Recommends: adb, usbmuxd +Description: Use your phone as a camera source in OBS Studio + DroidCam turns your Android or iOS phone into a wireless or USB camera + for OBS Studio, with support for HD video at up to 4K. +Homepage: https://droidcam.app/obs/ diff --git a/packaging/debian/copyright b/packaging/debian/copyright new file mode 100644 index 0000000..e7a2290 --- /dev/null +++ b/packaging/debian/copyright @@ -0,0 +1,22 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: DroidCam OBS Plugin +Source: https://github.com/dev47apps/droidcam-obs-plugin + +Files: * +Copyright: 2022 DEV47APPS +License: GPL-2.0 + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +The complete text of the GNU General Public License version 2 can be +found in /usr/share/common-licenses/GPL-2.