Skip to content

Commit 1c976ca

Browse files
committed
Initial Windows packaging
1 parent 809bf20 commit 1c976ca

File tree

11 files changed

+276
-114
lines changed

11 files changed

+276
-114
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Build Windows installer
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
workflow_dispatch:
7+
8+
jobs:
9+
build-installer:
10+
runs-on: windows-latest
11+
steps:
12+
- name: Checkout repository
13+
uses: actions/checkout@v4
14+
15+
- name: Set up JDK 21
16+
uses: actions/setup-java@v4
17+
with:
18+
distribution: temurin
19+
java-version: '21'
20+
21+
- name: Install WiX Toolset (Chocolatey)
22+
shell: pwsh
23+
run: |
24+
choco install wixtoolset -y
25+
26+
- name: Allow PowerShell scripts
27+
shell: pwsh
28+
run: Set-ExecutionPolicy Bypass -Scope Process -Force
29+
30+
- name: Run packaging script (creates installer or app-image)
31+
shell: pwsh
32+
run: |
33+
# Run jpackage script that builds jar and creates installer (requires WiX for exe)
34+
.\packaging\jpackage.ps1
35+
36+
- name: Show produced files
37+
shell: pwsh
38+
run: |
39+
Write-Host 'dist contents:'
40+
Get-ChildItem -Recurse -Force dist || true
41+
42+
- name: Upload installer artifact
43+
if: always()
44+
uses: actions/upload-artifact@v4
45+
with:
46+
name: smalltextpad-windows-installers
47+
path: |
48+
dist/installer/**
49+
dist/*-windows-appimage.zip

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# Build directories
55
/bin/
66
/out/
7+
/dist/
78
/target/
89
/build/
910
/classes/

SmallTextPad.iml

Lines changed: 0 additions & 14 deletions
This file was deleted.

package.ps1

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Windows PowerShell packaging script for SmallTextPad
2+
$ErrorActionPreference = "Stop"
3+
4+
# Run from the repository root
5+
Set-Location $PSScriptRoot
6+
7+
# Clean previous build artifacts
8+
Write-Host "[package] Cleaning previous build artifacts..."
9+
Remove-Item -Recurse -Force bin, dist -ErrorAction SilentlyContinue
10+
New-Item -ItemType Directory -Path bin | Out-Null
11+
New-Item -ItemType Directory -Path dist | Out-Null
12+
13+
# Compile Java sources
14+
Write-Host "[package] Compiling Java sources..."
15+
Get-ChildItem -Path src -Filter *.java -Recurse | Select-Object -ExpandProperty FullName | Set-Content sources.txt
16+
javac -d bin @(Get-Content sources.txt)
17+
18+
# Copy resource files (.properties)
19+
Write-Host "[package] Copying resource files..."
20+
$propDest = "bin/wagemaker/co/uk/lang"
21+
if (-not (Test-Path $propDest)) { New-Item -ItemType Directory -Path $propDest -Force | Out-Null }
22+
Copy-Item -Path src/wagemaker/co/uk/lang/*.properties -Destination $propDest -Force
23+
24+
# Copy images and other resources
25+
Write-Host "[package] Copying image resources..."
26+
# Copy the contents of res/ into bin root so resources are accessible as '/printer.png' etc.
27+
if (Test-Path res) {
28+
Copy-Item -Path (Join-Path $PSScriptRoot 'res\*') -Destination (Join-Path $PSScriptRoot 'bin') -Recurse -Force
29+
}
30+
31+
# Create JAR file
32+
Write-Host "[package] Creating JAR file..."
33+
$metaDest = "bin/META-INF"
34+
if (-not (Test-Path $metaDest)) { New-Item -ItemType Directory -Path $metaDest -Force | Out-Null }
35+
Copy-Item -Path src/META-INF/* -Destination $metaDest -Force
36+
$manifest = "bin/META-INF/MANIFEST.MF"
37+
$jarPath = "dist/SmallTextPad.jar"
38+
jar cfm $jarPath $manifest -C bin .
39+
40+
Write-Host "[package] Packaging complete. JAR created at $jarPath"
File renamed without changes.

packaging/README-windows.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Windows packaging
2+
3+
This repository contains `packaging/jpackage.ps1` which will produce either:
4+
5+
- a Windows installer (EXE) if the WiX toolset is installed on the system, or
6+
- an app-image ZIP (no installer) if WiX is not available.
7+
8+
Requirements (to build an EXE installer locally):
9+
- JDK 21+ with `jpackage` on PATH
10+
- WiX toolset (install via Chocolatey: `choco install wixtoolset -y` or download from https://wixtoolset.org)
11+
- PowerShell (run as Administrator for WiX installation)
12+
13+
Build locally:
14+
15+
1. From repo root run (PowerShell):
16+
17+
.\packaging\jpackage.ps1
18+
19+
2. If WiX is installed the installer will be in `dist/installer/`.
20+
Otherwise an app-image ZIP will be created at `dist/SmallTextPad-windows-appimage.zip`.
21+
22+
CI:
23+
24+
A GitHub Actions workflow `.github/workflows/windows-installer.yml` is provided to build the installer on a Windows runner and upload the produced artifacts.

packaging/jpackage.ps1

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Create a Windows installer EXE using jpackage
2+
# Usage: .\jpackage.ps1
3+
# Requires a JDK 14+ with jpackage on PATH
4+
# Requires choco install wixtoolset -y
5+
6+
$ErrorActionPreference = 'Stop'
7+
Set-Location $PSScriptRoot
8+
9+
# Ensure jpackage exists
10+
$jp = Get-Command jpackage -ErrorAction SilentlyContinue
11+
if (-not $jp) { Write-Error 'jpackage not found on PATH. Please install a JDK with jpackage (JDK 14+).' ; exit 1 }
12+
13+
# Build the jar first
14+
Write-Host '[jpackage] Building jar using package.ps1'
15+
try { & "$PSScriptRoot\..\package.ps1" } catch { Write-Error "package.ps1 failed: $_"; exit 1 }
16+
17+
# Read metadata from Details.java
18+
$detailsFile = Join-Path $PSScriptRoot '..\src\wagemaker\co\uk\utility\Details.java'
19+
if (-not (Test-Path $detailsFile)) { Write-Error 'Details.java not found'; exit 1 }
20+
$content = Get-Content $detailsFile -Raw
21+
$version = ([regex]::Match($content, 'public\s+static\s+String\s+Version\s*=\s*"([^\"]+)"')).Groups[1].Value
22+
$appName = ([regex]::Match($content, 'public\s+static\s+String\s+Title\s*=\s*"([^\"]+)"')).Groups[1].Value
23+
$vendor = ([regex]::Match($content, 'public\s+static\s+String\s+Developer\s*=\s*"([^\"]+)"')).Groups[1].Value
24+
$homepage = ([regex]::Match($content, 'public\s+static\s+String\s+remoteLicense\s*=\s*"([^\"]+)"')).Groups[1].Value
25+
26+
$jarPath = Join-Path $PSScriptRoot '..\dist\SmallTextPad.jar'
27+
if (-not (Test-Path $jarPath)) { Write-Error "Jar not found at $jarPath"; exit 1 }
28+
29+
# Prefer packaging/SmallTextPad.ico
30+
$iconIco = Join-Path $PSScriptRoot 'SmallTextPad.ico'
31+
if (Test-Path $iconIco) { Write-Host "[jpackage] Using icon: $iconIco" } else { Write-Host '[jpackage] packaging/SmallTextPad.ico not found; continuing without custom icon' ; $iconIco = $null }
32+
33+
# Destination folders
34+
$installerOut = Join-Path $PSScriptRoot '..\dist\installer'
35+
$appImageOut = Join-Path $PSScriptRoot '..\dist\appimage'
36+
if (-not (Test-Path $installerOut)) { New-Item -ItemType Directory -Path $installerOut | Out-Null }
37+
if (-not (Test-Path $appImageOut)) { New-Item -ItemType Directory -Path $appImageOut | Out-Null }
38+
39+
# Detect WiX (needed for exe/msi packaging on Windows)
40+
$wixFound = $false
41+
foreach ($tool in @('candle.exe','light.exe','wix.exe')) {
42+
if (Get-Command $tool -ErrorAction SilentlyContinue) { $wixFound = $true; break }
43+
}
44+
45+
if ($wixFound) {
46+
Write-Host '[jpackage] WiX toolset detected — creating Windows installer (exe)'
47+
$pkgType = 'exe'
48+
} else {
49+
Write-Host '[jpackage] WiX not detected — will create app-image (no installer). To produce an EXE installer install WiX and re-run this script.'
50+
$pkgType = 'app-image'
51+
}
52+
53+
# Build jpackage arguments depending on chosen type
54+
$inputDir = (Join-Path $PSScriptRoot '..\dist')
55+
$jpackageCmd = (Get-Command jpackage -ErrorAction SilentlyContinue).Source
56+
57+
try {
58+
if ($pkgType -eq 'exe') {
59+
$jpackArgs = @(
60+
'--type','exe',
61+
'--input', $inputDir,
62+
'--name', $appName,
63+
'--main-jar','SmallTextPad.jar',
64+
'--main-class','wagemaker.co.uk.main.Launcher',
65+
'--app-version',$version,
66+
'--vendor',$vendor,
67+
'--dest',$installerOut,
68+
'--win-menu','--win-shortcut'
69+
)
70+
if ($iconIco) { $jpackArgs += @('--icon',$iconIco) }
71+
if ($homepage) { $jpackArgs += @('--copyright',$homepage) }
72+
Write-Host "[jpackage] Running jpackage (installer)"
73+
& $jpackageCmd @jpackArgs
74+
Write-Host '[jpackage] Installer created. Contents of installer folder:'
75+
Get-ChildItem -Path $installerOut -Recurse | Select-Object FullName
76+
} else {
77+
$jpackArgs = @(
78+
'--type','app-image',
79+
'--input', $inputDir,
80+
'--name', $appName,
81+
'--main-jar','SmallTextPad.jar',
82+
'--main-class','wagemaker.co.uk.main.Launcher',
83+
'--app-version',$version,
84+
'--vendor',$vendor,
85+
'--dest',$appImageOut
86+
)
87+
if ($iconIco) { $jpackArgs += @('--icon',$iconIco) }
88+
if ($homepage) { $jpackArgs += @('--copyright',$homepage) }
89+
Write-Host "[jpackage] Running jpackage (app-image)"
90+
& $jpackageCmd @jpackArgs
91+
92+
# Zip the produced app-image for distribution
93+
$producedFolder = Join-Path $appImageOut $appName
94+
if (Test-Path $producedFolder) {
95+
$zipPath = Join-Path (Join-Path $PSScriptRoot '..\dist') "$appName-windows-appimage.zip"
96+
if (Test-Path $zipPath) { Remove-Item $zipPath -Force }
97+
Write-Host "[jpackage] Zipping app-image to $zipPath"
98+
Compress-Archive -Path (Join-Path $producedFolder '*') -DestinationPath $zipPath -Force
99+
Write-Host "[jpackage] App-image zip created: $zipPath"
100+
} else {
101+
Write-Warning "Expected app-image folder not found: $producedFolder"
102+
}
103+
}
104+
} catch {
105+
Write-Error "jpackage failed: $_"
106+
exit 1
107+
}
108+
109+
Write-Host '[jpackage] Packaging finished.'

packaging/snap/gui/smalltextpad.desktop

Lines changed: 0 additions & 11 deletions
This file was deleted.

packaging/snap/snapcraft.yaml

Lines changed: 0 additions & 69 deletions
This file was deleted.

run.ps1

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Quick test-run helper for SmallTextPad (Windows PowerShell)
2+
# Exits on any error
3+
$ErrorActionPreference = "Stop"
4+
5+
# Run from the repository root
6+
Set-Location $PSScriptRoot
7+
8+
# Ensure required tools exist
9+
if (-not (Get-Command javac -ErrorAction SilentlyContinue)) { Write-Error "javac not found in PATH"; exit 1 }
10+
if (-not (Get-Command java -ErrorAction SilentlyContinue)) { Write-Error "java not found in PATH"; exit 1 }
11+
12+
Write-Host "[run] Deleting compiled class files under bin/"
13+
Get-ChildItem -Path bin -Filter *.class -Recurse | Remove-Item
14+
15+
Write-Host "[run] Rebuilding sources.txt from src/"
16+
Get-ChildItem -Path src -Filter *.java -Recurse | Select-Object -ExpandProperty FullName | Set-Content sources.txt
17+
18+
Write-Host "[run] Compiling Java sources to bin/"
19+
javac -d bin @(Get-Content sources.txt)
20+
21+
Write-Host "[run] Copying resource files to bin/"
22+
# Ensure language properties are available in the classpath
23+
$propDest = "bin/wagemaker/co/uk/lang"
24+
if (-not (Test-Path $propDest)) { New-Item -ItemType Directory -Path $propDest -Force | Out-Null }
25+
Copy-Item -Path src/wagemaker/co/uk/lang/*.properties -Destination $propDest -Force
26+
27+
# Copy image resources into bin root so getResource("/name.png") works
28+
if (Test-Path res) {
29+
Copy-Item -Path (Join-Path $PSScriptRoot 'res\*') -Destination (Join-Path $PSScriptRoot 'bin') -Recurse -Force
30+
}
31+
32+
Write-Host "[run] Launching SmallTextPad (this will run until you close the GUI)"
33+
java -cp bin wagemaker.co.uk.main.Launcher

0 commit comments

Comments
 (0)