Skip to content

Release Desktop Client #6

Release Desktop Client

Release Desktop Client #6

name: Release Desktop Client
on:
workflow_dispatch:
inputs:
tag:
description: 'Release tag (e.g., v1.0.0). Leave empty to skip GitHub Release.'
required: false
default: ''
jobs:
build:
name: Build (${{ matrix.name }})
runs-on: ${{ matrix.runs-on }}
strategy:
fail-fast: false
matrix:
include:
- name: macos-arm64
runs-on: macos-latest
platform: macos
- name: macos-x64
runs-on: macos-14-large # Intel; larger runner (may require GitHub Team/Enterprise)
platform: macos
- name: windows
runs-on: windows-latest
platform: windows
- name: linux
runs-on: ubuntu-latest
platform: linux
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '25'
distribution: 'temurin'
- name: Install Linux deps
if: matrix.platform == 'linux'
run: sudo apt-get update && sudo apt-get install -y fakeroot
- name: Build app
run: mvn clean package -pl desktop-client -am -DskipTests
- name: Build macOS installer (dmg only)
if: matrix.platform == 'macos'
run: |
cd desktop-client
MAVEN_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
APP_VERSION=$(echo "$MAVEN_VERSION" | sed 's/-SNAPSHOT//' | sed 's/-.*//')
if [[ ! "$APP_VERSION" =~ \. ]]; then
APP_VERSION="${APP_VERSION}.0"
fi
JAR_NAME=$(basename target/desktop-client-*.jar)
ICON_ARG=""
if [ -f "src/main/resources/icons/app-icon.icns" ]; then
ICON_ARG="--icon src/main/resources/icons/app-icon.icns"
fi
jpackage --input target \
--name "Java Swing Tutor" \
--main-jar $JAR_NAME \
--main-class com.posadskiy.javaswingtutor.Start \
--type dmg \
--dest target/jpackage \
--app-version $APP_VERSION \
--vendor Posadskiy \
--java-options "-Dfile.encoding=UTF-8 -Dapp.env=prod" \
--mac-package-identifier com.posadskiy.javaswingtutor \
--mac-package-name "Java Swing Tutor" \
$ICON_ARG
# Rename so Intel and ARM64 DMGs are both included in release (no overwrite)
DMG=$(ls target/jpackage/*.dmg 2>/dev/null | head -1)
if [ -n "$DMG" ]; then
mv "$DMG" "target/jpackage/JavaSwingTutor-${APP_VERSION}-${{ matrix.name }}.dmg"
fi
- name: Build Windows installer (exe only)
if: matrix.platform == 'windows'
run: |
# Short JAVA_HOME/PATH for jpackage only (avoids "filename or extension is too long")
if (Test-Path C:\j) { cmd /c rmdir C:\j }
cmd /c mklink /J C:\j $env:JAVA_HOME
$env:JAVA_HOME = "C:\j"
$env:PATH = "C:\j\bin;C:\Windows\System32;C:\Windows"
subst X: $env:GITHUB_WORKSPACE
cd X:\desktop-client
$jarFile = Get-ChildItem target\desktop-client-*.jar | Select-Object -First 1
$JAR_NAME = $jarFile.Name
$APP_VERSION = ($jarFile.BaseName -replace 'desktop-client-', '') -replace '-SNAPSHOT', '' -replace '-.*', ''
if ($APP_VERSION -notmatch "\.") { $APP_VERSION = "$APP_VERSION.0" }
$iconArgs = @()
if (Test-Path "src\main\resources\icons\app-icon.ico") {
$iconArgs = @("--icon", "src\main\resources\icons\app-icon.ico")
}
Remove-Item -Path "C:\t" -Recurse -Force -ErrorAction SilentlyContinue
jpackage --input target --name "JSTutor" --main-jar $JAR_NAME --main-class com.posadskiy.javaswingtutor.Start --type exe --dest X:\d --temp C:\t --app-version $APP_VERSION --vendor Posadskiy --java-options "-Dfile.encoding=UTF-8 -Dapp.env=prod" --win-dir-chooser --win-menu --win-menu-group JSTutor --win-shortcut @iconArgs
New-Item -ItemType Directory -Force -Path "$env:GITHUB_WORKSPACE\windows-installer-out" | Out-Null
Copy-Item -Path "X:\d\*.exe" -Destination "$env:GITHUB_WORKSPACE\windows-installer-out" -Force
subst X: /d
- name: Build Linux installer (deb only)
if: matrix.platform == 'linux'
run: |
cd desktop-client
MAVEN_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
APP_VERSION=$(echo "$MAVEN_VERSION" | sed 's/-SNAPSHOT//' | sed 's/-.*//')
if [[ ! "$APP_VERSION" =~ \. ]]; then
APP_VERSION="${APP_VERSION}.0"
fi
JAR_NAME=$(basename target/desktop-client-*.jar)
ICON_ARG=""
if [ -f "src/main/resources/icons/app-icon.png" ]; then
ICON_ARG="--icon src/main/resources/icons/app-icon.png"
fi
jpackage --input target \
--name "Java Swing Tutor" \
--main-jar $JAR_NAME \
--main-class com.posadskiy.javaswingtutor.Start \
--type deb \
--dest target/jpackage \
--app-version $APP_VERSION \
--vendor Posadskiy \
--java-options "-Dfile.encoding=UTF-8 -Dapp.env=prod" \
--linux-menu-group Education \
--linux-shortcut \
--linux-package-name javaswingtutor \
$ICON_ARG
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: desktop-${{ matrix.name }}
path: |
desktop-client/target/jpackage/*.dmg
desktop-client/target/jpackage/*.deb
windows-installer-out/*.exe
retention-days: 30
bundle:
name: Bundle release
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/download-artifact@v4
with:
path: dist
- name: Create release bundle
run: |
mkdir -p release
find dist -type f \( -name "*.dmg" -o -name "*.exe" -o -name "*.deb" \) -exec cp {} release/ \;
(cd release && ls -la)
- name: Upload bundled artifacts
uses: actions/upload-artifact@v4
with:
name: desktop-release-bundle
path: release/*
retention-days: 30
- name: Publish GitHub Release
if: ${{ inputs.tag != '' }}
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ inputs.tag }}
name: ${{ inputs.tag }}
files: release/*