diff --git a/.github/workflows/release-packages.yml b/.github/workflows/release-packages.yml new file mode 100644 index 0000000..2d14915 --- /dev/null +++ b/.github/workflows/release-packages.yml @@ -0,0 +1,111 @@ +name: Build And Release Packages + +on: + push: + tags: + - "v*.*.*" + workflow_dispatch: + +permissions: + contents: write + +jobs: + build-and-release: + runs-on: ubuntu-24.04 + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Decide release publishing + id: publish_gate + run: | + set -euo pipefail + publish_release=false + + if [[ "${GITHUB_REF}" == refs/tags/* ]]; then + default_branch="${{ github.event.repository.default_branch }}" + git fetch origin "${default_branch}" --depth=1 + if git merge-base --is-ancestor "${GITHUB_SHA}" "origin/${default_branch}"; then + publish_release=true + fi + fi + + echo "publish_release=${publish_release}" >> "${GITHUB_OUTPUT}" + + - name: Validate tag format + if: startsWith(github.ref, 'refs/tags/') + run: | + set -euo pipefail + if [[ ! "${GITHUB_REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Tag '${GITHUB_REF_NAME}' does not match required format vX.Y.Z" + exit 1 + fi + + - name: Validate tag vs Debian upstream version + if: steps.publish_gate.outputs.publish_release == 'true' + run: | + set -euo pipefail + tag_version="${GITHUB_REF_NAME#v}" + debian_version="$(dpkg-parsechangelog -S Version)" + upstream_version="${debian_version%%-*}" + + if [[ "${tag_version}" != "${upstream_version}" ]]; then + echo "Tag version (${tag_version}) does not match debian upstream version (${upstream_version})" + exit 1 + fi + + - name: Install build dependencies + run: | + set -euo pipefail + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + build-essential \ + debhelper \ + desktop-file-utils \ + devscripts \ + dpkg-dev \ + rsync + + - name: Build Debian packages + run: | + set -euo pipefail + make deb + + - name: Create source zip archive + id: bundle + run: | + set -euo pipefail + mkdir -p dist + ref_name_safe="${GITHUB_REF_NAME//\//-}" + zip_name="cameractrls-${ref_name_safe}-source.zip" + git archive \ + --format=zip \ + --prefix="cameractrls-${ref_name_safe}/" \ + --output="dist/${zip_name}" \ + HEAD + echo "zip_asset=dist/${zip_name}" >> "${GITHUB_OUTPUT}" + + - name: Upload workflow artifacts + uses: actions/upload-artifact@v4 + with: + name: deb-packages-${{ github.run_id }}-${{ github.run_attempt }} + path: | + dist/deb/* + dist/*.zip + if-no-files-found: error + + - name: Publish GitHub release assets + if: steps.publish_gate.outputs.publish_release == 'true' + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.ref_name }} + name: ${{ github.ref_name }} + generate_release_notes: true + files: | + dist/deb/*.deb + dist/deb/*.changes + dist/deb/*.buildinfo + ${{ steps.bundle.outputs.zip_asset }} diff --git a/.gitignore b/.gitignore index 84c7a37..2a7a328 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,15 @@ -__pycache__ +__pycache__/ +*.py[cod] +*~ +*.swp + +# Local scratch dir used during development rust + +# Built Debian artifacts +dist/ +debian/.debhelper/ +debian/debhelper-build-stamp +debian/files +debian/*.debhelper +debian/*.substvars diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..346e2fa --- /dev/null +++ b/Makefile @@ -0,0 +1,25 @@ +.PHONY: help deb clean-deb + +PACKAGE := $(shell dpkg-parsechangelog -S Source) +VERSION := $(shell dpkg-parsechangelog -S Version) +BUILD_DIR ?= /tmp/$(PACKAGE)-deb-build +OUT_DIR ?= dist/deb + +help: + @echo "Targets:" + @echo " make deb Build Ubuntu/Debian .deb packages into $(OUT_DIR)/" + @echo " make clean-deb Remove generated package artifacts in $(OUT_DIR)/" + +deb: + rm -rf "$(BUILD_DIR)" + mkdir -p "$(BUILD_DIR)" "$(OUT_DIR)" + rsync -a --delete --exclude ".git/" ./ "$(BUILD_DIR)/" + cd "$(BUILD_DIR)" && dpkg-buildpackage -us -uc -b + find "$(BUILD_DIR)/.." -maxdepth 1 -type f -name "*_$(VERSION)_all.deb" -exec cp -f {} "$(OUT_DIR)/" \; + find "$(BUILD_DIR)/.." -maxdepth 1 -type f -name "*_$(VERSION)_*.changes" -exec cp -f {} "$(OUT_DIR)/" \; + find "$(BUILD_DIR)/.." -maxdepth 1 -type f -name "*_$(VERSION)_*.buildinfo" -exec cp -f {} "$(OUT_DIR)/" \; + @echo "Built packages:" + @ls -1 "$(OUT_DIR)"/*"_$(VERSION)_all.deb" + +clean-deb: + rm -f "$(OUT_DIR)"/*.deb "$(OUT_DIR)"/*.changes "$(OUT_DIR)"/*.buildinfo diff --git a/README.md b/README.md index 994b937..78683ef 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,26 @@ pacman -S cameractrls pamac install cameractrls ``` +## From GitHub Releases (Ubuntu .deb packages) + +Supported Ubuntu versions: 22.04, 24.04, 26.xx. + +Download the `.deb` files from the latest release: + +https://github.com/soyersoyer/cameractrls/releases/latest + +Install all apps (CLI + GTK3 + GTK4): +```shell +sudo apt install ./cameractrls_*_all.deb \ + ./cameractrls-gtk_*_all.deb \ + ./cameractrls-gtk4_*_all.deb +``` + +Or install only the CLI/core tools: +```shell +sudo apt install ./cameractrls_*_all.deb +``` + ## Git Install method Install the dependencies via apt: diff --git a/debian/cameractrls-gtk.install b/debian/cameractrls-gtk.install new file mode 100644 index 0000000..267058f --- /dev/null +++ b/debian/cameractrls-gtk.install @@ -0,0 +1,3 @@ +cameractrlsgtk.py usr/bin/ +pkg/hu.irl.cameractrls.desktop usr/share/applications/ +pkg/hu.irl.cameractrls.metainfo.xml usr/share/metainfo/ diff --git a/debian/cameractrls-gtk4.install b/debian/cameractrls-gtk4.install new file mode 100644 index 0000000..f2b0b1d --- /dev/null +++ b/debian/cameractrls-gtk4.install @@ -0,0 +1,2 @@ +cameractrlsgtk4.py usr/bin/ +debian/hu.irl.cameractrls.gtk4.desktop usr/share/applications/ diff --git a/debian/cameractrls.docs b/debian/cameractrls.docs new file mode 100644 index 0000000..88dae24 --- /dev/null +++ b/debian/cameractrls.docs @@ -0,0 +1,2 @@ +README.md +CHANGELOG.md diff --git a/debian/cameractrls.install b/debian/cameractrls.install new file mode 100644 index 0000000..c465044 --- /dev/null +++ b/debian/cameractrls.install @@ -0,0 +1,8 @@ +cameractrls.py usr/bin/ +cameractrlsd.py usr/bin/ +cameraview.py usr/bin/ +cameraptzgame.py usr/bin/ +cameraptzmidi.py usr/bin/ +cameraptzspnav.py usr/bin/ +debian/hu.irl.cameractrls.viewer.desktop usr/share/applications/ +pkg/hu.irl.cameractrls.svg usr/share/icons/hicolor/scalable/apps/ diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..4056535 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,14 @@ +cameractrls (0.6.10-2) unstable; urgency=medium + + * Fix Ubuntu dependency name for TurboJPEG runtime: + accept libturbojpeg0 or libturbojpeg. + + -- Sebels Thu, 26 Feb 2026 21:11:01 +0100 + +cameractrls (0.6.10-1) unstable; urgency=medium + + * Initial Debian/Ubuntu packaging for all shipped apps. + * Split GUI applications into GTK3 and GTK4 binary packages. + * Install desktop entries, icon, and AppStream metadata. + + -- Sebels Thu, 26 Feb 2026 20:49:35 +0100 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..253ed5c --- /dev/null +++ b/debian/control @@ -0,0 +1,63 @@ +Source: cameractrls +Section: video +Priority: optional +Maintainer: Sebels +Build-Depends: + debhelper-compat (= 13), + desktop-file-utils +Standards-Version: 4.7.0 +Rules-Requires-Root: no +Homepage: https://github.com/soyersoyer/cameractrls + +Package: cameractrls +Architecture: all +Depends: + ${misc:Depends}, + libasound2, + libsdl2-2.0-0, + libspnav0, + libturbojpeg0 | libturbojpeg, + python3 +Recommends: + spacenavd +Description: Camera controls for Linux (CLI, daemon, viewer, PTZ helpers) + Standalone Python tools to configure V4L2 camera controls on Linux. + . + This package provides: + * cameractrls.py (CLI) + * cameractrlsd.py (restore daemon) + * cameraview.py (SDL viewer) + * cameraptzgame.py, cameraptzmidi.py, cameraptzspnav.py (PTZ input helpers) + * desktop launcher for cameraview.py + * shared icon used by desktop launchers + +Package: cameractrls-gtk +Architecture: all +Depends: + ${misc:Depends}, + cameractrls (= ${binary:Version}), + gir1.2-gtk-3.0, + python3, + python3-gi +Description: Camera controls for Linux (GTK3 GUI) + GTK3 graphical frontend for cameractrls. + . + This package installs: + * cameractrlsgtk.py + * hu.irl.cameractrls.desktop launcher + * hu.irl.cameractrls.metainfo.xml AppStream metadata + +Package: cameractrls-gtk4 +Architecture: all +Depends: + ${misc:Depends}, + cameractrls (= ${binary:Version}), + gir1.2-gtk-4.0, + python3, + python3-gi +Description: Camera controls for Linux (GTK4 GUI) + GTK4 graphical frontend for cameractrls. + . + This package installs: + * cameractrlsgtk4.py + * hu.irl.cameractrls.gtk4.desktop launcher diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..42425d1 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,20 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: cameractrls +Upstream-Contact: https://github.com/soyersoyer/cameractrls/issues +Source: https://github.com/soyersoyer/cameractrls + +Files: * +Copyright: 2021-2026 Gergo Koteles +License: LGPL-3.0-or-later + This package is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + . + This package 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 Lesser General Public License for more details. + . + On Debian systems, the complete text of the GNU Lesser General Public License + version 3 can be found in /usr/share/common-licenses/LGPL-3. diff --git a/debian/hu.irl.cameractrls.gtk4.desktop b/debian/hu.irl.cameractrls.gtk4.desktop new file mode 100644 index 0000000..8120a5e --- /dev/null +++ b/debian/hu.irl.cameractrls.gtk4.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Type=Application +Version=1.0 +Name=Cameractrls (GTK4) +Comment=Camera controls for Linux +Exec=cameractrlsgtk4.py +Icon=hu.irl.cameractrls +Terminal=false +Categories=AudioVideo;Video;GTK; +Keywords=picture;photos;camera;webcam; diff --git a/debian/hu.irl.cameractrls.viewer.desktop b/debian/hu.irl.cameractrls.viewer.desktop new file mode 100644 index 0000000..6fdf8f5 --- /dev/null +++ b/debian/hu.irl.cameractrls.viewer.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Type=Application +Version=1.0 +Name=Cameractrls Viewer +Comment=Camera viewer for Linux +Exec=cameraview.py +Icon=hu.irl.cameractrls +Terminal=false +Categories=AudioVideo;Video; +Keywords=picture;photos;camera;webcam;viewer; diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..0fc3651 --- /dev/null +++ b/debian/rules @@ -0,0 +1,8 @@ +#!/usr/bin/make -f + +%: + dh $@ + +override_dh_auto_build: + +override_dh_auto_test: diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/pkg/hu.irl.cameractrls.desktop b/pkg/hu.irl.cameractrls.desktop index 13ece4d..633ce6b 100644 --- a/pkg/hu.irl.cameractrls.desktop +++ b/pkg/hu.irl.cameractrls.desktop @@ -6,5 +6,5 @@ Comment=Camera controls for Linux Exec=cameractrlsgtk.py Icon=hu.irl.cameractrls Terminal=false -Categories=Settings;AudioVideo;Video;Office;Utility;GNOME;GTK; +Categories=AudioVideo;Video;GTK; Keywords=picture;photos;camera;webcam;