From 1c9fd5f10c30d4609afc2347742076029659b536 Mon Sep 17 00:00:00 2001 From: Evgeny Prilepin Date: Tue, 4 Nov 2025 19:12:07 +0000 Subject: [PATCH] Add RPM build CI/CD workflow --- .github/workflows/build-rpm.yml | 51 ++++++++++++++++++ .gitignore | 1 - VoiceRecorder.pyw | 11 ---- {voicerecorder/icons => icons}/mic.png | Bin {voicerecorder/icons => icons}/pause.png | Bin {voicerecorder/icons => icons}/play.png | Bin {voicerecorder/icons => icons}/rec.png | Bin {voicerecorder/icons => icons}/record.png | Bin {voicerecorder/icons => icons}/remove.png | Bin {voicerecorder/icons => icons}/stop.png | Bin pyproject.toml | 15 ++++-- rpm/voicerecorder.spec | 48 +++++++++++++++++ .../voicerecorder}/__init__.py | 0 .../voicerecorder}/__main__.py | 0 .../voicerecorder}/audioformat.py | 0 .../voicerecorder}/audiorecorder.py | 0 .../voicerecorder}/constants.py | 0 {voicerecorder => src/voicerecorder}/main.py | 0 .../voicerecorder}/mainwindow.py | 0 .../voicerecorder}/mainwindow_ui.py | 2 +- .../voicerecorder}/recordsmanager.py | 0 .../voicerecorder}/settings.py | 0 .../voicerecorder}/statusinfo.py | 0 {voicerecorder => src/voicerecorder}/utils.py | 0 .../voicerecorder/voicerecorder_rc.py | 25 ++++----- {voicerecorder => ui}/mainwindow.ui | 8 +-- uv.lock | 2 +- voicerecorder.desktop | 9 ++++ .../mainwindow.qrc => voicerecorder.qrc | 0 29 files changed, 135 insertions(+), 37 deletions(-) create mode 100644 .github/workflows/build-rpm.yml delete mode 100644 VoiceRecorder.pyw rename {voicerecorder/icons => icons}/mic.png (100%) rename {voicerecorder/icons => icons}/pause.png (100%) rename {voicerecorder/icons => icons}/play.png (100%) rename {voicerecorder/icons => icons}/rec.png (100%) rename {voicerecorder/icons => icons}/record.png (100%) rename {voicerecorder/icons => icons}/remove.png (100%) rename {voicerecorder/icons => icons}/stop.png (100%) create mode 100644 rpm/voicerecorder.spec rename {voicerecorder => src/voicerecorder}/__init__.py (100%) rename {voicerecorder => src/voicerecorder}/__main__.py (100%) rename {voicerecorder => src/voicerecorder}/audioformat.py (100%) rename {voicerecorder => src/voicerecorder}/audiorecorder.py (100%) rename {voicerecorder => src/voicerecorder}/constants.py (100%) rename {voicerecorder => src/voicerecorder}/main.py (100%) rename {voicerecorder => src/voicerecorder}/mainwindow.py (100%) rename {voicerecorder => src/voicerecorder}/mainwindow_ui.py (99%) rename {voicerecorder => src/voicerecorder}/recordsmanager.py (100%) rename {voicerecorder => src/voicerecorder}/settings.py (100%) rename {voicerecorder => src/voicerecorder}/statusinfo.py (100%) rename {voicerecorder => src/voicerecorder}/utils.py (100%) rename voicerecorder/mainwindow_rc.py => src/voicerecorder/voicerecorder_rc.py (97%) rename {voicerecorder => ui}/mainwindow.ui (95%) create mode 100644 voicerecorder.desktop rename voicerecorder/mainwindow.qrc => voicerecorder.qrc (100%) diff --git a/.github/workflows/build-rpm.yml b/.github/workflows/build-rpm.yml new file mode 100644 index 0000000..b4ea771 --- /dev/null +++ b/.github/workflows/build-rpm.yml @@ -0,0 +1,51 @@ +name: Build RPM + +on: + workflow_dispatch: + +jobs: + build-rpm: + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Build RPM in Fedora container + run: | + docker run --rm \ + -v ${{ github.workspace }}:/work \ + -w /work \ + fedora:43 \ + bash -euc ' + dnf install -y \ + rpm-build \ + python3-devel \ + python3-pip \ + python3-packaging \ + python3-wheel \ + python3-hatchling \ + pyproject-rpm-macros \ + curl + curl -Ls https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" + + UV_VERSION_OUT=$(uv version) + NAME=$(echo "$UV_VERSION_OUT" | awk "{print \$1}") + VERSION=$(echo "$UV_VERSION_OUT" | awk "{print \$2}") + + uv build --sdist + + mkdir -p rpmbuild/SOURCES rpmbuild/SPECS + cp dist/${NAME}-${VERSION}.tar.gz rpmbuild/SOURCES/ + cp rpm/${NAME}.spec rpmbuild/SPECS/ + + cd rpmbuild + rpmbuild -ba SPECS/${NAME}.spec --define "_topdir $(pwd)" + ' + + - name: Upload RPM artifacts + uses: actions/upload-artifact@v5 + with: + name: rpm-package + path: rpmbuild/RPMS/**/*.rpm diff --git a/.gitignore b/.gitignore index 38282c1..81f6aa0 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,6 @@ var/ # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest -*.spec # Installer logs pip-log.txt diff --git a/VoiceRecorder.pyw b/VoiceRecorder.pyw deleted file mode 100644 index 89d9cc0..0000000 --- a/VoiceRecorder.pyw +++ /dev/null @@ -1,11 +0,0 @@ -""" -VoiceRecorder is a simple application for voice recording - -""" - -import sys -from voicerecorder.main import main - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/voicerecorder/icons/mic.png b/icons/mic.png similarity index 100% rename from voicerecorder/icons/mic.png rename to icons/mic.png diff --git a/voicerecorder/icons/pause.png b/icons/pause.png similarity index 100% rename from voicerecorder/icons/pause.png rename to icons/pause.png diff --git a/voicerecorder/icons/play.png b/icons/play.png similarity index 100% rename from voicerecorder/icons/play.png rename to icons/play.png diff --git a/voicerecorder/icons/rec.png b/icons/rec.png similarity index 100% rename from voicerecorder/icons/rec.png rename to icons/rec.png diff --git a/voicerecorder/icons/record.png b/icons/record.png similarity index 100% rename from voicerecorder/icons/record.png rename to icons/record.png diff --git a/voicerecorder/icons/remove.png b/icons/remove.png similarity index 100% rename from voicerecorder/icons/remove.png rename to icons/remove.png diff --git a/voicerecorder/icons/stop.png b/icons/stop.png similarity index 100% rename from voicerecorder/icons/stop.png rename to icons/stop.png diff --git a/pyproject.toml b/pyproject.toml index d975c3b..78445c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ readme = "README.md" requires-python = ">=3.12" dependencies = [ - "pyside6>=6.10.0", + "pyside6>=6.9.2", ] [project.gui-scripts] @@ -31,10 +31,12 @@ package = true [tool.hatch.build.targets.sdist] -include = ["voicerecorder"] - -[tool.hatch.build.targets.wheel] -include = ["voicerecorder"] +exclude = [ + ".ruff_cache", + ".github", + ".cache", + ".venv", +] [tool.ruff] @@ -83,3 +85,6 @@ check = ["check-format", "check-lint"] fix-format = "ruff format ." fix-lint = "ruff check --fix ." fix = ["fix-format", "fix-lint"] + +rcc = "pyside6-rcc -o ./src/voicerecorder/voicerecorder_rc.py ./voicerecorder.qrc" +uic = "pyside6-uic --from-imports -o ./src/voicerecorder/mainwindow_ui.py ./ui/mainwindow.ui" diff --git a/rpm/voicerecorder.spec b/rpm/voicerecorder.spec new file mode 100644 index 0000000..892a248 --- /dev/null +++ b/rpm/voicerecorder.spec @@ -0,0 +1,48 @@ +Name: voicerecorder +Version: 0.6.0 +Release: 1%{?dist} +Summary: VoiceRecorder is a simple voice/audio recording application + +License: MIT +URL: https://github.com/espdev/VoiceRecorder +Source0: %{name}-%{version}.tar.gz + +BuildArch: noarch + +BuildRequires: python3-devel +BuildRequires: python3-pip +BuildRequires: python3-packaging +BuildRequires: python3-hatchling +BuildRequires: pyproject-rpm-macros + +Requires: python3-pyside6 + +%description +VoiceRecorder is a simple voice/audio recording application. + +%prep +%autosetup -n %{name}-%{version} + +%generate_buildrequires +%pyproject_buildrequires -R + +%build +%pyproject_wheel + +%install +%pyproject_install + +install -Dpm 644 voicerecorder.desktop %{buildroot}%{_datadir}/applications/voicerecorder.desktop +install -Dpm 644 icons/mic.png %{buildroot}%{_datadir}/icons/hicolor/32x32/apps/voicerecorder.png + +%files +%license LICENSE +%doc README.md +%{python3_sitelib}/voicerecorder* +%{_bindir}/voicerecorder +%{_datadir}/applications/voicerecorder.desktop +%{_datadir}/icons/hicolor/32x32/apps/voicerecorder.png + +%changelog +* Tue Nov 04 2025 Evgeny Prilepin - 0.6.0 +- Initial RPM release diff --git a/voicerecorder/__init__.py b/src/voicerecorder/__init__.py similarity index 100% rename from voicerecorder/__init__.py rename to src/voicerecorder/__init__.py diff --git a/voicerecorder/__main__.py b/src/voicerecorder/__main__.py similarity index 100% rename from voicerecorder/__main__.py rename to src/voicerecorder/__main__.py diff --git a/voicerecorder/audioformat.py b/src/voicerecorder/audioformat.py similarity index 100% rename from voicerecorder/audioformat.py rename to src/voicerecorder/audioformat.py diff --git a/voicerecorder/audiorecorder.py b/src/voicerecorder/audiorecorder.py similarity index 100% rename from voicerecorder/audiorecorder.py rename to src/voicerecorder/audiorecorder.py diff --git a/voicerecorder/constants.py b/src/voicerecorder/constants.py similarity index 100% rename from voicerecorder/constants.py rename to src/voicerecorder/constants.py diff --git a/voicerecorder/main.py b/src/voicerecorder/main.py similarity index 100% rename from voicerecorder/main.py rename to src/voicerecorder/main.py diff --git a/voicerecorder/mainwindow.py b/src/voicerecorder/mainwindow.py similarity index 100% rename from voicerecorder/mainwindow.py rename to src/voicerecorder/mainwindow.py diff --git a/voicerecorder/mainwindow_ui.py b/src/voicerecorder/mainwindow_ui.py similarity index 99% rename from voicerecorder/mainwindow_ui.py rename to src/voicerecorder/mainwindow_ui.py index d0ad344..ee5b049 100644 --- a/voicerecorder/mainwindow_ui.py +++ b/src/voicerecorder/mainwindow_ui.py @@ -19,7 +19,7 @@ QHBoxLayout, QHeaderView, QLabel, QMainWindow, QMenuBar, QPushButton, QSizePolicy, QSpacerItem, QStatusBar, QTableView, QVBoxLayout, QWidget) -from . import mainwindow_rc +from . import voicerecorder_rc class Ui_MainWindow(object): def setupUi(self, MainWindow): diff --git a/voicerecorder/recordsmanager.py b/src/voicerecorder/recordsmanager.py similarity index 100% rename from voicerecorder/recordsmanager.py rename to src/voicerecorder/recordsmanager.py diff --git a/voicerecorder/settings.py b/src/voicerecorder/settings.py similarity index 100% rename from voicerecorder/settings.py rename to src/voicerecorder/settings.py diff --git a/voicerecorder/statusinfo.py b/src/voicerecorder/statusinfo.py similarity index 100% rename from voicerecorder/statusinfo.py rename to src/voicerecorder/statusinfo.py diff --git a/voicerecorder/utils.py b/src/voicerecorder/utils.py similarity index 100% rename from voicerecorder/utils.py rename to src/voicerecorder/utils.py diff --git a/voicerecorder/mainwindow_rc.py b/src/voicerecorder/voicerecorder_rc.py similarity index 97% rename from voicerecorder/mainwindow_rc.py rename to src/voicerecorder/voicerecorder_rc.py index dca6ac4..082323d 100644 --- a/voicerecorder/mainwindow_rc.py +++ b/src/voicerecorder/voicerecorder_rc.py @@ -197,7 +197,7 @@ \x90\xde6\x00\x00\x00\x00IEND\xaeB`\x82\ " -qt_resource_name = b'\ +qt_resource_name = b"\ \x00\x05\ \x00o\xa6S\ \x00i\ @@ -230,36 +230,33 @@ \x07\x8b\xa6\x84\ \x00r\ \x00e\x00c\x00o\x00r\x00d\ -' +" -qt_resource_struct = b'\ +qt_resource_struct = b"\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x000\x00\x00\x00\x00\x00\x01\x00\x00\x02\xf3\ -\x00\x00\x01\x99}\xe7\xed:\ +\x00\x00\x01|\xbeG,\x8e\ \x00\x00\x00<\x00\x00\x00\x00\x00\x01\x00\x00\x05\xb4\ -\x00\x00\x01\x99}\xe7\xed:\ +\x00\x00\x01|\xbeG,\x8e\ \x00\x00\x00\x22\x00\x00\x00\x00\x00\x01\x00\x00\x01z\ -\x00\x00\x01\x99}\xe7\xed:\ +\x00\x00\x01|\xbeG,\x8e\ \x00\x00\x00H\x00\x00\x00\x00\x00\x01\x00\x00\x06\xea\ -\x00\x00\x01\x99}\xe7\xed:\ +\x00\x00\x01|\xbeG,\x8e\ \x00\x00\x00V\x00\x00\x00\x00\x00\x01\x00\x00\x08:\ -\x00\x00\x01\x99}\xe7\xed:\ +\x00\x00\x01|\xbeG,\x8e\ \x00\x00\x00f\x00\x00\x00\x00\x00\x01\x00\x00\x09\x84\ -\x00\x00\x01\x99}\xe7\xed:\ +\x00\x00\x01|\xbeG,\x8e\ \x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x99}\xe7\xed:\ -' - +\x00\x00\x01|\xbeG,\x8e\ +" def qInitResources(): QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) - def qCleanupResources(): QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) - qInitResources() diff --git a/voicerecorder/mainwindow.ui b/ui/mainwindow.ui similarity index 95% rename from voicerecorder/mainwindow.ui rename to ui/mainwindow.ui index 5972574..d8434a7 100644 --- a/voicerecorder/mainwindow.ui +++ b/ui/mainwindow.ui @@ -14,7 +14,7 @@ MainWindow - + :/icons/mic:/icons/mic @@ -64,7 +64,7 @@ Record - + :/icons/record:/icons/record @@ -87,7 +87,7 @@ Pause - + :/icons/pause:/icons/pause @@ -147,7 +147,7 @@ - + diff --git a/uv.lock b/uv.lock index b3a2253..fbb1c73 100644 --- a/uv.lock +++ b/uv.lock @@ -171,7 +171,7 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "pyside6", specifier = ">=6.10.0" }] +requires-dist = [{ name = "pyside6", specifier = ">=6.9.2" }] [package.metadata.requires-dev] dev = [ diff --git a/voicerecorder.desktop b/voicerecorder.desktop new file mode 100644 index 0000000..eb7af7c --- /dev/null +++ b/voicerecorder.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Name=VoiceRecorder +Comment=VoiceRecorder is a simple voice/audio recording application +Exec=voicerecorder +Icon=voicerecorder +Categories=Audio;Utility; +Terminal=false diff --git a/voicerecorder/mainwindow.qrc b/voicerecorder.qrc similarity index 100% rename from voicerecorder/mainwindow.qrc rename to voicerecorder.qrc