From d68ae5ff8fcfd931456d7597a0f1e5c23317dded Mon Sep 17 00:00:00 2001 From: Bearice Ren Date: Tue, 7 Jul 2026 15:22:43 +0900 Subject: [PATCH 1/2] fix(ci): correct rpm metadata syntax and grant release write permission MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two CI failures blocked the v2.4.0 release: 1. "Build .rpm" failed with "Field package.metadata.generate-rpm.recommends must be string or integer" — cargo-generate-rpm 0.21 expects dependency fields as a table section, not an inline array. Switch recommends to [package.metadata.generate-rpm.recommends] with per-package version constraints. Verified locally: produces rustcat-2.4.0-1.x86_64.rpm with Recommends: kdialog, plasma-systemmonitor and the icon in pixmaps/. 2. "Publish ... release" failed with "Resource not accessible by integration" — the workflow declared only pull-requests: write, which makes contents default to none, so action-gh-release couldn't upload assets. Add contents: write to the permissions block. Co-Authored-By: Claude --- .github/workflows/rust.yaml | 6 +++++- Cargo.toml | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index a0c3727..a4ba47e 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -10,8 +10,12 @@ on: types: [created, edited] permissions: + # contents: write is required by softprops/action-gh-release to upload + # assets to a GitHub release. Specifying any permission makes all others + # default to none, so this must be listed explicitly. + contents: write pull-requests: write - + jobs: #run build first to populate caches build-windows: diff --git a/Cargo.toml b/Cargo.toml index 392623a..32d2387 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,9 +90,15 @@ name = "rustcat" license = "Apache-2.0" summary = "Animated tray cat whose speed tracks CPU usage" description = "RustCat displays an animated cat or parrot tray icon whose animation speed reflects real-time CPU usage. Integrates with KDE Plasma via the StatusNotifierItem D-Bus protocol." -recommends = ["kdialog", "plasma-systemmonitor"] assets = [ { source = "target/release/rust_cat", dest = "/usr/bin/rust_cat", mode = "755" }, { source = "assets/rustcat.desktop", dest = "/usr/share/applications/rustcat.desktop", mode = "644" }, { source = "assets/appIcon.ico", dest = "/usr/share/pixmaps/rustcat.ico", mode = "644" }, ] + +# Dependency fields in cargo-generate-rpm use a table section (not inline +# arrays), per the 0.21 docs. Each key is a package, each value a version +# constraint ("*" = any). These are soft runtime hints. +[package.metadata.generate-rpm.recommends] +kdialog = "*" +plasma-systemmonitor = "*" From b0a44f42f35345206616bc719852e8dd5186d262 Mon Sep 17 00:00:00 2001 From: Bearice Ren Date: Tue, 7 Jul 2026 16:33:37 +0900 Subject: [PATCH 2/2] fix(ci): make AppImage build best-effort so it can't block deb/rpm/tarball The AppImage step had never run before (it sat after the failing rpm step), and linuxdeploy can be finicky in CI: it prefers a PNG icon over the raw .ico, and running an AppImage-from-AppImage needs FUSE which some runners gate. Rather than let a flaky AppImage block the core deb/rpm/tarball release artifacts: - Convert the icon to PNG via ImageMagick (magick v7 / convert v6) with a raw-.ico fallback. - Fall back to APPIMAGE_EXTRACT_AND_RUN when the nested AppImage can't run. - Mark the build step continue-on-error and the upload if-no-files-found: ignore / if: always(), so the Linux job still publishes deb/rpm/tarball when AppImage fails. Co-Authored-By: Claude --- .github/workflows/rust.yaml | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index a4ba47e..82fc9d5 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -167,6 +167,10 @@ jobs: cp target/generate-rpm/*.rpm rpm-out/RustCat-linux-x86_64.rpm - name: Build AppImage + # Best-effort: linuxdeploy + an AppImage-from-AppImage bootstrap can be + # finicky in CI. A failure here must not block the core deb/rpm/tarball + # artifacts, so this step is allowed to fail and its upload is lenient. + continue-on-error: true shell: bash run: | set -e @@ -175,7 +179,22 @@ jobs: mkdir -p appimage/AppDir/usr/share/icons cp target/release/rust_cat appimage/AppDir/usr/bin/ cp assets/rustcat.desktop appimage/AppDir/usr/share/applications/ - cp assets/appIcon.ico appimage/AppDir/usr/share/icons/rustcat.ico + + # linuxdeploy prefers a PNG icon; convert the multi-resolution ICO + # with whichever ImageMagick binary the runner ships (v7: magick, + # v6: convert). Fall back to the raw .ico if neither is present. + ICON_ARG=() + if command -v magick >/dev/null 2>&1; then + magick assets/appIcon.ico appimage/AppDir/usr/share/icons/rustcat.png + ICON_ARG=(--icon-file appimage/AppDir/usr/share/icons/rustcat.png) + elif command -v convert >/dev/null 2>&1; then + convert assets/appIcon.ico appimage/AppDir/usr/share/icons/rustcat.png + ICON_ARG=(--icon-file appimage/AppDir/usr/share/icons/rustcat.png) + else + cp assets/appIcon.ico appimage/AppDir/usr/share/icons/rustcat.ico + ICON_ARG=(--icon-file appimage/AppDir/usr/share/icons/rustcat.ico) + fi + # AppImage desktop entry must point to the binary inside the AppDir sed -i 's|^Exec=.*|Exec=rust_cat|' appimage/AppDir/usr/share/applications/rustcat.desktop @@ -184,9 +203,14 @@ jobs: export OUTPUT=RustCat-${VERSION}-${ARCH}.AppImage wget -qO linuxdeploy https://github.com/linuxdeploy/linuxdeploy/releases/latest/download/linuxdeploy-${ARCH}.AppImage chmod +x linuxdeploy + # Some runners can't run nested AppImages directly; fall back to + # extracting and running via the AppRun wrapper if FUSE is unavailable. + if ! ./linuxdeploy --version >/dev/null 2>&1; then + export APPIMAGE_EXTRACT_AND_RUN=1 + fi ./linuxdeploy --appdir appimage/AppDir \ --desktop-file appimage/AppDir/usr/share/applications/rustcat.desktop \ - --icon-file appimage/AppDir/usr/share/icons/rustcat.ico \ + "${ICON_ARG[@]}" \ --output appimage mv appimage/*.AppImage "${OUTPUT}" @@ -220,11 +244,12 @@ jobs: if-no-files-found: error - name: Upload Linux AppImage + if: always() uses: actions/upload-artifact@v4 with: name: RustCat-x86_64.AppImage path: RustCat-*.AppImage - if-no-files-found: error + if-no-files-found: ignore - name: Publish Linux release uses: softprops/action-gh-release@v1