name: Build Comic Strip Browser on: push: branches: [ main, master, develop ] tags: - 'v*' pull_request: branches: [ main, master ] workflow_dispatch: permissions: contents: write env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true' jobs: # ─── Windows ────────────────────────────────────────────── build-windows: runs-on: windows-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.4 (Node 24) - name: Set up Python uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 (Node 24) with: python-version: '3.12' cache: 'pip' - name: Install dependencies run: | python -m pip install --upgrade pip pip install PyQt6 requests beautifulsoup4 Pillow pyinstaller - name: Build (onefile) run: | python -m PyInstaller comic_browser.spec --clean --noconfirm shell: pwsh - name: Upload Windows EXE uses: actions/upload-artifact@v4.4.0 with: name: ComicStripBrowser-Windows path: dist/ComicStripBrowser.exe retention-days: 30 # ─── Linux ───────────────────────────────────────────────── build-linux: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.4 (Node 24) - name: Set up Python uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0 (Node 24) with: python-version: '3.12' cache: 'pip' - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y \ libxcb-cursor0 libxcb-xinerama0 libxcb-icccm4 libxcb-image0 \ libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 \ libxcb-xfixes0 libxcb-xkb1 libxkbcommon-x11-0 \ dpkg-dev rpm file fuse - name: Install Python dependencies run: | python -m pip install --upgrade pip pip install PyQt6 requests beautifulsoup4 Pillow pyinstaller - name: Build binary (onefile) run: | python -m PyInstaller comic_browser.spec --clean --noconfirm - name: Upload binary uses: actions/upload-artifact@v4.4.0 with: name: ComicStripBrowser-linux-binary path: dist/comic-strip-browser retention-days: 30 - name: Build .deb package run: | python3 build_scripts/create_deb.py - name: Find .deb artifact id: deb run: | DEB_FILE=$(find build/ -maxdepth 1 -name "*.deb" -type f | head -1) echo "path=$DEB_FILE" >> "$GITHUB_OUTPUT" echo "name=$(basename "$DEB_FILE")" >> "$GITHUB_OUTPUT" - name: Upload .deb uses: actions/upload-artifact@v4.4.0 with: name: ComicStripBrowser-deb path: ${{ steps.deb.outputs.path }} retention-days: 30 - name: Build .rpm package run: | VERSION=$(python3 -c "from version import __version__; print(__version__)") RELEASE="1" BINARY="dist/comic-strip-browser" RPMBUILD="$HOME/rpmbuild" mkdir -p "$RPMBUILD"/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} TMPDIR=$(mktemp -d) SRCDIR="$TMPDIR/comic-strip-browser-$VERSION" mkdir -p "$SRCDIR" cp "$BINARY" "$SRCDIR/comic-strip-browser" chmod +x "$SRCDIR/comic-strip-browser" [ -f assets/comic-strip-browser.desktop ] && cp assets/comic-strip-browser.desktop "$SRCDIR/" [ -f assets/comic-strip-browser.appdata.xml ] && cp assets/comic-strip-browser.appdata.xml "$SRCDIR/" ICON_SRC="initial_transparent_alpha.png" [ ! -f "$ICON_SRC" ] && ICON_SRC="assets/comic-strip-browser.png" [ -f "$ICON_SRC" ] && cp "$ICON_SRC" "$SRCDIR/comic-strip-browser.png" [ -f LICENSE ] && cp LICENSE "$SRCDIR/" [ -f README.md ] && cp README.md "$SRCDIR/" cd "$TMPDIR" tar czf "$RPMBUILD/SOURCES/comic-strip-browser-$VERSION.tar.gz" "comic-strip-browser-$VERSION" cd - >/dev/null rm -rf "$TMPDIR" SPEC="$RPMBUILD/SPECS/comic-strip-browser.spec" cat > "$SPEC" << EOF Name: comic-strip-browser Version: $VERSION Release: $RELEASE Summary: A standalone comic strip browser for GoComics.com License: MIT URL: https://github.com/DerLudditus/comic-strip-browser Source0: %{name}-%{version}.tar.gz BuildArch: x86_64 %description A standalone PyQt6 application for browsing comic strips from GoComics.com. %prep %autosetup %build %install install -D -m 0755 %{name} %{buildroot}%{_bindir}/%{name} [ -f %{name}.desktop ] && install -D -m 0644 %{name}.desktop %{buildroot}%{_datadir}/applications/%{name}.desktop [ -f %{name}.appdata.xml ] && install -D -m 0644 %{name}.appdata.xml %{buildroot}%{_datadir}/metainfo/%{name}.appdata.xml [ -f %{name}.png ] && install -D -m 0644 %{name}.png %{buildroot}%{_datadir}/pixmaps/%{name}.png [ -f %{name}.png ] && install -D -m 0644 %{name}.png %{buildroot}%{_datadir}/icons/hicolor/256x256/apps/%{name}.png %files %{_bindir}/%{name} %{_datadir}/applications/%{name}.desktop %{_datadir}/metainfo/%{name}.appdata.xml %{_datadir}/pixmaps/%{name}.png %{_datadir}/icons/hicolor/256x256/apps/%{name}.png %post if command -v update-desktop-database >/dev/null 2>&1; then update-desktop-database %{_datadir}/applications fi if command -v gtk-update-icon-cache >/dev/null 2>&1; then gtk-update-icon-cache -f -t %{_datadir}/icons/hicolor 2>/dev/null || true fi %postun if command -v update-desktop-database >/dev/null 2>&1; then update-desktop-database %{_datadir}/applications fi if command -v gtk-update-icon-cache >/dev/null 2>&1; then gtk-update-icon-cache -f -t %{_datadir}/icons/hicolor 2>/dev/null || true fi %changelog * $(date +"%a %b %d %Y") Homo Ludditus - ${VERSION}-${RELEASE} - Release $VERSION EOF rpmbuild -bb "$SPEC" - name: Find .rpm artifact id: rpm run: | RPM_FILE=$(find "$HOME/rpmbuild/RPMS/" -name "*.rpm" -type f | head -1) echo "path=$RPM_FILE" >> "$GITHUB_OUTPUT" echo "name=$(basename "$RPM_FILE")" >> "$GITHUB_OUTPUT" - name: Upload .rpm uses: actions/upload-artifact@v4.4.0 with: name: ComicStripBrowser-rpm path: ${{ steps.rpm.outputs.path }} retention-days: 30 - name: Create AppImage run: | VERSION=$(python3 -c "from version import __version__; print(__version__)") APPDIR="$PWD/build/ComicStripBrowser.AppDir" mkdir -p "$APPDIR"/{usr/bin,usr/share/applications,usr/share/pixmaps,usr/share/metainfo} cp dist/comic-strip-browser "$APPDIR/usr/bin/comic-strip-browser" chmod +x "$APPDIR/usr/bin/comic-strip-browser" ln -sf usr/bin/comic-strip-browser "$APPDIR/AppRun" [ -f assets/comic-strip-browser.desktop ] && cp assets/comic-strip-browser.desktop "$APPDIR/" [ -f assets/comic-strip-browser.appdata.xml ] && { cp assets/comic-strip-browser.appdata.xml "$APPDIR/usr/share/metainfo/" cp assets/comic-strip-browser.appdata.xml "$APPDIR/" } ICON_SRC="initial_transparent_alpha.png" [ ! -f "$ICON_SRC" ] && ICON_SRC="assets/comic-strip-browser.png" [ -f "$ICON_SRC" ] && { cp "$ICON_SRC" "$APPDIR/comic-strip-browser.png" cp "$ICON_SRC" "$APPDIR/.DirIcon" cp "$ICON_SRC" "$APPDIR/usr/share/pixmaps/comic-strip-browser.png" } wget -q https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage chmod +x appimagetool-x86_64.AppImage ARCH=x86_64 ./appimagetool-x86_64.AppImage "$APPDIR" "dist/comic-strip-browser-${VERSION}.AppImage" - name: Upload AppImage uses: actions/upload-artifact@v4.4.0 with: name: ComicStripBrowser-AppImage path: dist/comic-strip-browser-*.AppImage retention-days: 30 # ─── Release ─────────────────────────────────────────────── # Waits for both builds, pulls down all files, and creates exactly ONE release publish-release: needs: [build-windows, build-linux] if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: - name: Download all build artifacts uses: actions/download-artifact@v4 with: pattern: ComicStripBrowser-* path: release-assets merge-multiple: true - name: Create Release uses: softprops/action-gh-release@v2 with: files: release-assets/* body: ${{ github.event.head_commit.message }}