Skip to content

Generate installers#280

Merged
rainxchzed merged 3 commits intomainfrom
generate-installers
Mar 1, 2026
Merged

Generate installers#280
rainxchzed merged 3 commits intomainfrom
generate-installers

Conversation

@rainxchzed
Copy link
Member

@rainxchzed rainxchzed commented Mar 1, 2026

Summary by CodeRabbit

  • New Features

    • Added Linux AppImage distribution so Linux users receive AppImage artifacts alongside existing installers.
  • Chores

    • Improved desktop build reliability with Gradle validation, cache cleanup, and consolidated retry logic.
    • Extended Linux build matrix to produce and publish AppImage, DEB, and RPM packages where applicable.

This commit adds support for building and uploading Linux AppImages as part of the desktop platform CI workflow. The build is restricted to the 'modern' matrix label and includes a retry mechanism for stability.

- **feat(ci)**: Added `Build Linux AppImage` step using `:composeApp:packageAppImage` Gradle task.
- **feat(ci)**: Added a `retry` shell function to the AppImage build step to handle transient failures.
- **feat(ci)**: Added `Upload Linux AppImage` step to archive the generated AppImage binaries.
- **chore(ci)**: Increased artifact compression level for Linux installers.
This commit updates the desktop build workflow to archive the Linux AppImage output into a `.tar.gz` file instead of uploading the raw directory. This ensures better compatibility and preservation of file permissions for Linux distributions.

- **ci(github-actions)**: Added steps to list and locate the AppImage build output directory dynamically.
- **ci(github-actions)**: Implemented a packaging step to compress the AppImage directory into `GitHub-Store-linux-x64.tar.gz`.
- **ci(github-actions)**: Updated the `linux-appimage` artifact upload to use the newly created compressed archive.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 1, 2026

Walkthrough

Adds Gradle wrapper validation, cache cleanup and retry logic, expands the Linux build matrix, and introduces AppImage build/packaging/upload steps in the desktop GitHub Actions workflow.

Changes

Cohort / File(s) Summary
Desktop CI workflow
.github/workflows/build-desktop-platforms.yml
Adds Gradle wrapper validation step, Gradle home cache cleanup and vfs.watch flag; centralizes retry logic for install/build steps; extends Linux matrix for AppImage/deb/rpm variants; adds AppImage build, list, tar.gz packaging, and artifact upload steps for modern Linux matrix; minor cache/options cleanup.

Sequence Diagram(s)

sequenceDiagram
    participant GH as GitHub Actions
    participant Runner as OS Runner (linux macOS windows)
    participant Gradle as Gradle Wrapper
    participant FS as Filesystem
    participant Upload as Actions Upload Artifact

    GH->>Runner: start platform job (matrix)
    Runner->>Gradle: validate gradle wrapper
    Gradle-->>Runner: validation result
    Runner->>Gradle: run install & build (with retry wrapper)
    Gradle-->>FS: write build outputs (AppImage, deb, rpm, installers)
    Runner->>FS: list AppImage output
    Runner->>FS: package AppImage into tar.gz
    Runner->>Upload: upload tar.gz and other installer artifacts
    Upload-->>GH: artifact stored
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰
Hop, hop — the builders hum and sing,
AppImages bundled beneath my wing;
Tarred and tagged, they leap to the sky,
Artifacts ready — hop, bye-bye! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Generate installers' is vague and generic; it does not clearly describe the specific changes made, such as adding Gradle validation, AppImage support, or workflow enhancements. Use a more specific title that captures the main changes, such as 'Add Gradle validation and AppImage support to desktop build workflows' or 'Enhance desktop build pipeline with installer packaging.'
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch generate-installers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
.github/workflows/build-desktop-platforms.yml (2)

246-270: Consider parameterizing the architecture in the artifact name.

The filename GitHub-Store-linux-x64.tar.gz hardcodes the architecture. While ubuntu-latest currently runs on x64, making this explicit would improve clarity and future-proof the workflow if arm64 Linux builds are added later.

♻️ Optional: Use a variable for architecture
       - name: Package AppImage as tar.gz
         if: matrix.label == 'modern'
         run: |
           set -euo pipefail
+          ARCH="x64"  # Matches ubuntu-latest runner architecture

           # Find the app-image output directory (could be app-image/ or app/)
           APPIMAGE_DIR=""
           ...

-          tar -czf composeApp/build/compose/binaries/main/GitHub-Store-linux-x64.tar.gz -C "$APPIMAGE_DIR" .
+          tar -czf "composeApp/build/compose/binaries/main/GitHub-Store-linux-${ARCH}.tar.gz" -C "$APPIMAGE_DIR" .
           echo "Created tar.gz archive:"
-          ls -lh composeApp/build/compose/binaries/main/GitHub-Store-linux-x64.tar.gz
+          ls -lh "composeApp/build/compose/binaries/main/GitHub-Store-linux-${ARCH}.tar.gz"
         shell: bash

And update the upload step path accordingly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-desktop-platforms.yml around lines 246 - 270, The
artifact filename in the "Package AppImage as tar.gz" step hardcodes the
architecture as GitHub-Store-linux-x64.tar.gz; change this to use a
parameter/variable (e.g., ARCH or matrix.arch) so the tar command and any later
upload paths use a templated name instead of x64. Update the tar invocation that
writes to composeApp/build/compose/binaries/main/GitHub-Store-linux-x64.tar.gz
and any references to that filename (including upload steps) to use the new ARCH
variable, and ensure the variable is populated from your build matrix or an
environment variable where the job defines the target architecture; keep
APPIMAGE_DIR detection logic and only substitute the output filename.

209-235: Consider extracting the duplicated retry() function.

The retry() function is now duplicated four times in this workflow (Windows, macOS, Linux DEB/RPM, and AppImage builds). This reduces maintainability—any change to retry behavior requires updating all four locations.

Consider extracting it to:

  • A shell script (e.g., .github/scripts/retry.sh) sourced by each step
  • A composite action
  • A reusable workflow for the build pattern
♻️ Example: Extract to a shared script

Create .github/scripts/retry.sh:

#!/bin/bash
retry() {
  local n=1
  local max=3
  local delay=5
  while true; do
    echo "Attempt #$n: $*"
    if "$@"; then
      break
    fi
    if [ $n -ge $max ]; then
      echo "Command failed after $n attempts."
      return 1
    fi
    n=$((n+1))
    echo "Command failed — retrying in $delay seconds..."
    sleep $delay
    delay=$((delay*2))
  done
}

Then in each step:

      - name: Build Linux AppImage
        if: matrix.label == 'modern'
        run: |
          set -euo pipefail
-
-          retry() {
-            local n=1
-            ...
-          }
-
+          source .github/scripts/retry.sh
          retry ./gradlew :composeApp:packageAppImage
        shell: bash
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-desktop-platforms.yml around lines 209 - 235, The
duplicated retry() shell function used in multiple build steps (e.g., the "Build
Linux AppImage" step) should be extracted to a single shared implementation and
sourced by each job: create a single shared script containing retry(), make it
executable, and update each step (Windows, macOS, Linux DEB/RPM, AppImage) to
source that script before calling retry ./gradlew ...; alternatively implement
the same shared behavior as a composite action or reusable workflow and replace
the inline retry() definitions with a call to the shared module so future
changes require editing only one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/build-desktop-platforms.yml:
- Around line 246-270: The artifact filename in the "Package AppImage as tar.gz"
step hardcodes the architecture as GitHub-Store-linux-x64.tar.gz; change this to
use a parameter/variable (e.g., ARCH or matrix.arch) so the tar command and any
later upload paths use a templated name instead of x64. Update the tar
invocation that writes to
composeApp/build/compose/binaries/main/GitHub-Store-linux-x64.tar.gz and any
references to that filename (including upload steps) to use the new ARCH
variable, and ensure the variable is populated from your build matrix or an
environment variable where the job defines the target architecture; keep
APPIMAGE_DIR detection logic and only substitute the output filename.
- Around line 209-235: The duplicated retry() shell function used in multiple
build steps (e.g., the "Build Linux AppImage" step) should be extracted to a
single shared implementation and sourced by each job: create a single shared
script containing retry(), make it executable, and update each step (Windows,
macOS, Linux DEB/RPM, AppImage) to source that script before calling retry
./gradlew ...; alternatively implement the same shared behavior as a composite
action or reusable workflow and replace the inline retry() definitions with a
call to the shared module so future changes require editing only one place.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a60d46 and 3101fbe.

📒 Files selected for processing (1)
  • .github/workflows/build-desktop-platforms.yml

This commit streamlines the GitHub Actions workflow for building desktop platforms by optimizing Gradle configurations, improving task management, and cleaning up redundant scripts.

- **chore(github-actions)**: Added `org.gradle.vfs.watch=false` to Gradle options to improve CI performance.
- **chore(github-actions)**: Integrated `gradle/actions/wrapper-validation` to verify the integrity of Gradle wrappers.
- **chore(github-actions)**: Refactored Gradle setup to use `gradle-home-cache-cleanup` and removed redundant `cache: 'gradle'` from `setup-java`.
- **refactor(github-actions)**: Simplified the `retry` shell function logic across all build jobs for better readability.
- **feat(github-actions)**: Parametrized Linux build tasks using a `gradle-tasks` matrix variable, consolidating the AppImage build into a single step.
- **chore**: Cleaned up whitespace and minor formatting in the workflow file.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.github/workflows/build-desktop-platforms.yml (1)

49-63: Centralize the duplicated retry() helper to reduce maintenance burden.

This workflow defines an identical retry() function in three separate jobs (Windows, macOS, and Linux builds). Moving it to a reusable composite action or script keeps retry behavior consistent and eliminates the risk of divergent implementations if one definition is updated independently.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-desktop-platforms.yml around lines 49 - 63, The
duplicated retry() helper function used in the Build Windows installers job
should be extracted to a single reusable location and invoked from each platform
job; create a reusable composite action or an executable script that implements
retry() and replace the inline function in the Windows, macOS and Linux build
jobs with a single call (e.g., run: ./scripts/retry -- ./gradlew
:composeApp:packageExe :composeApp:packageMsi or uses:
./github/actions/retry-action with args) so the symbol retry() is defined once
and every job (the Windows job that currently calls retry ./gradlew ...)
delegates to that centralized implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/build-desktop-platforms.yml:
- Around line 49-63: The duplicated retry() helper function used in the Build
Windows installers job should be extracted to a single reusable location and
invoked from each platform job; create a reusable composite action or an
executable script that implements retry() and replace the inline function in the
Windows, macOS and Linux build jobs with a single call (e.g., run:
./scripts/retry -- ./gradlew :composeApp:packageExe :composeApp:packageMsi or
uses: ./github/actions/retry-action with args) so the symbol retry() is defined
once and every job (the Windows job that currently calls retry ./gradlew ...)
delegates to that centralized implementation.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3101fbe and edeb305.

📒 Files selected for processing (1)
  • .github/workflows/build-desktop-platforms.yml

@rainxchzed rainxchzed merged commit fb501f9 into main Mar 1, 2026
7 checks passed
@rainxchzed rainxchzed deleted the generate-installers branch March 1, 2026 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant