Skip to content

Commit 4e96f90

Browse files
committed
FEAT: Automated Builds in Github
1 parent d746e71 commit 4e96f90

4 files changed

Lines changed: 967 additions & 0 deletions

File tree

.github/workflows/build-rpm.yml

Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
name: Build RPM Package
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
inputs:
9+
release_tag:
10+
description: 'Release tag (e.g., v1.0.0)'
11+
required: false
12+
default: 'v1.0.0'
13+
14+
env:
15+
APP_NAME: python-gui-menu
16+
APP_VERSION: ${{ github.ref_name || inputs.release_tag || 'v1.0.0' }}
17+
18+
jobs:
19+
build-rpm:
20+
name: Build RPM on CentOS Stream 9
21+
runs-on: ubuntu-latest
22+
container:
23+
image: quay.io/centos/centos:stream9
24+
25+
steps:
26+
- name: Install system dependencies
27+
run: |
28+
dnf update -y
29+
dnf install -y \
30+
git \
31+
python3 \
32+
python3-pip \
33+
python3-venv \
34+
rpm-build \
35+
rpmdevtools \
36+
gcc \
37+
gcc-c++ \
38+
make \
39+
qt5-qtbase-devel \
40+
qt5-qtwayland \
41+
libxcb-devel \
42+
mesa-libGL-devel \
43+
fontconfig-devel \
44+
freetype-devel \
45+
libX11-devel \
46+
libXext-devel \
47+
libXrender-devel \
48+
which \
49+
zip \
50+
desktop-file-utils
51+
52+
- name: Checkout repository
53+
uses: actions/checkout@v4
54+
55+
- name: Set up Python virtual environment
56+
run: |
57+
python3 -m venv build_venv
58+
source build_venv/bin/activate
59+
pip install --upgrade pip
60+
pip install wheel setuptools
61+
62+
- name: Install Python dependencies
63+
run: |
64+
source build_venv/bin/activate
65+
pip install -r requirements_build.txt
66+
67+
- name: Build application
68+
run: |
69+
echo "Building Python GUI Menu application..."
70+
source build_venv/bin/activate
71+
python3 build.py
72+
73+
# Verify the build was successful
74+
if [ ! -f "dist/menu" ]; then
75+
echo "ERROR: Build failed - executable not found"
76+
exit 1
77+
fi
78+
79+
# Get the package directory name
80+
PACKAGE_DIR=$(ls -d menu_* 2>/dev/null | head -1)
81+
if [ -z "$PACKAGE_DIR" ]; then
82+
echo "ERROR: Package directory not found"
83+
exit 1
84+
fi
85+
86+
echo "PACKAGE_DIR=$PACKAGE_DIR" >> $GITHUB_ENV
87+
echo "Build successful - package created: $PACKAGE_DIR"
88+
89+
- name: Prepare RPM build environment
90+
run: |
91+
# Set up RPM build directories
92+
mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
93+
94+
# Remove version prefix if present (v1.0.0 -> 1.0.0)
95+
VERSION="${APP_VERSION#v}"
96+
echo "RPM_VERSION=$VERSION" >> $GITHUB_ENV
97+
98+
# Create source tarball
99+
TARBALL_NAME="${APP_NAME}-${VERSION}.tar.gz"
100+
tar -czf ~/rpmbuild/SOURCES/$TARBALL_NAME \
101+
--transform "s|^|${APP_NAME}-${VERSION}/|" \
102+
--exclude=".git*" \
103+
--exclude="build_venv" \
104+
--exclude="build" \
105+
--exclude="__pycache__" \
106+
--exclude="*.pyc" \
107+
.
108+
109+
echo "TARBALL_NAME=$TARBALL_NAME" >> $GITHUB_ENV
110+
111+
- name: Create RPM spec file
112+
run: |
113+
cat > ~/rpmbuild/SPECS/${APP_NAME}.spec << 'EOF'
114+
Name: python-gui-menu
115+
Version: %{getenv:RPM_VERSION}
116+
Release: 1%{?dist}
117+
Summary: Python GUI Menu Application
118+
License: MIT
119+
URL: https://github.com/${{ github.repository }}
120+
Source0: %{name}-%{version}.tar.gz
121+
122+
BuildRequires: python3
123+
BuildRequires: python3-pip
124+
BuildRequires: python3-venv
125+
BuildRequires: qt5-qtbase-devel
126+
BuildRequires: desktop-file-utils
127+
128+
Requires: qt5-qtbase-gui
129+
Requires: qt5-qtwayland
130+
Requires: libxcb
131+
Requires: fontconfig
132+
133+
%description
134+
A cross-platform GUI menu application built with Python and PyQt5.
135+
Provides a customizable menu interface for executing system commands.
136+
137+
%prep
138+
%autosetup
139+
140+
%build
141+
# Create virtual environment and build
142+
python3 -m venv build_venv
143+
source build_venv/bin/activate
144+
pip install --upgrade pip
145+
pip install -r requirements_build.txt
146+
python3 build.py
147+
148+
%install
149+
# Create installation directories
150+
mkdir -p %{buildroot}/opt/PythonMenu
151+
mkdir -p %{buildroot}/opt/PythonMenu/Docs
152+
mkdir -p %{buildroot}/usr/bin
153+
mkdir -p %{buildroot}/usr/share/applications
154+
mkdir -p %{buildroot}/usr/share/pixmaps
155+
156+
# Find the generated package directory
157+
PACKAGE_DIR=$(ls -d menu_* 2>/dev/null | head -1)
158+
if [ -z "$PACKAGE_DIR" ]; then
159+
echo "ERROR: Package directory not found during install"
160+
exit 1
161+
fi
162+
163+
# Install application files to /opt/PythonMenu
164+
cp -r $PACKAGE_DIR/* %{buildroot}/opt/PythonMenu/
165+
166+
# Ensure executable has correct permissions
167+
chmod +x %{buildroot}/opt/PythonMenu/menu
168+
169+
# Install run script with correct permissions
170+
if [ -f %{buildroot}/opt/PythonMenu/run_linux.sh ]; then
171+
chmod +x %{buildroot}/opt/PythonMenu/run_linux.sh
172+
fi
173+
174+
# Install greeting script if it exists
175+
if [ -f %{buildroot}/opt/PythonMenu/greeting.sh ]; then
176+
chmod +x %{buildroot}/opt/PythonMenu/greeting.sh
177+
fi
178+
179+
# Create wrapper script in /usr/bin
180+
cat > %{buildroot}/usr/bin/python-gui-menu << 'WRAPPER_EOF'
181+
#!/bin/bash
182+
cd /opt/PythonMenu
183+
exec ./menu "$@"
184+
WRAPPER_EOF
185+
chmod +x %{buildroot}/usr/bin/python-gui-menu
186+
187+
# Install desktop entry
188+
cat > %{buildroot}/usr/share/applications/python-gui-menu.desktop << 'DESKTOP_EOF'
189+
[Desktop Entry]
190+
Name=Python GUI Menu
191+
Comment=Customizable GUI menu application
192+
Exec=/usr/bin/python-gui-menu
193+
Icon=python-gui-menu
194+
Terminal=false
195+
Type=Application
196+
Categories=Utility;System;
197+
DESKTOP_EOF
198+
199+
# Install icon if available
200+
if [ -f %{buildroot}/opt/PythonMenu/logo.png ]; then
201+
cp %{buildroot}/opt/PythonMenu/logo.png %{buildroot}/usr/share/pixmaps/python-gui-menu.png
202+
elif [ -f %{buildroot}/opt/PythonMenu/smallicon.png ]; then
203+
cp %{buildroot}/opt/PythonMenu/smallicon.png %{buildroot}/usr/share/pixmaps/python-gui-menu.png
204+
fi
205+
206+
%files
207+
/opt/PythonMenu/
208+
/usr/bin/python-gui-menu
209+
/usr/share/applications/python-gui-menu.desktop
210+
/usr/share/pixmaps/python-gui-menu.png
211+
212+
%post
213+
# Update desktop database
214+
if [ -x /usr/bin/update-desktop-database ]; then
215+
/usr/bin/update-desktop-database -q /usr/share/applications || :
216+
fi
217+
218+
%postun
219+
# Update desktop database
220+
if [ -x /usr/bin/update-desktop-database ]; then
221+
/usr/bin/update-desktop-database -q /usr/share/applications || :
222+
fi
223+
224+
%changelog
225+
* $(date '+%a %b %d %Y') GitHub Actions <actions@github.com> - %{version}-1
226+
- Automated build from GitHub Actions
227+
- Cross-platform enhanced build mode
228+
- Installation in /opt/PythonMenu directory
229+
230+
EOF
231+
232+
- name: Build RPM package
233+
run: |
234+
rpmbuild -ba ~/rpmbuild/SPECS/${APP_NAME}.spec
235+
236+
# Find the generated RPM
237+
RPM_FILE=$(find ~/rpmbuild/RPMS -name "*.rpm" -type f | head -1)
238+
if [ -z "$RPM_FILE" ]; then
239+
echo "ERROR: RPM package not found"
240+
exit 1
241+
fi
242+
243+
# Copy to workspace for artifact upload
244+
cp "$RPM_FILE" ./
245+
RPM_FILENAME=$(basename "$RPM_FILE")
246+
echo "RPM_FILENAME=$RPM_FILENAME" >> $GITHUB_ENV
247+
248+
echo "RPM package built successfully: $RPM_FILENAME"
249+
250+
- name: Test RPM installation
251+
run: |
252+
echo "Testing RPM installation..."
253+
dnf install -y ./$RPM_FILENAME
254+
255+
# Verify installation
256+
if [ ! -f "/opt/PythonMenu/menu" ]; then
257+
echo "ERROR: Application not installed correctly"
258+
exit 1
259+
fi
260+
261+
if [ ! -x "/usr/bin/python-gui-menu" ]; then
262+
echo "ERROR: Wrapper script not installed correctly"
263+
exit 1
264+
fi
265+
266+
if [ ! -f "/usr/share/applications/python-gui-menu.desktop" ]; then
267+
echo "ERROR: Desktop entry not installed correctly"
268+
exit 1
269+
fi
270+
271+
echo "RPM installation test passed!"
272+
273+
# Show package info
274+
echo "=== Package Information ==="
275+
rpm -qi python-gui-menu
276+
277+
echo "=== Package Files ==="
278+
rpm -ql python-gui-menu
279+
280+
- name: Upload RPM artifact
281+
uses: actions/upload-artifact@v4
282+
with:
283+
name: rpm-package
284+
path: ${{ env.RPM_FILENAME }}
285+
retention-days: 30
286+
287+
- name: Create Release
288+
if: startsWith(github.ref, 'refs/tags/')
289+
uses: softprops/action-gh-release@v1
290+
with:
291+
files: ${{ env.RPM_FILENAME }}
292+
generate_release_notes: true
293+
draft: false
294+
prerelease: false
295+
env:
296+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)