Skip to content

Commit 48667be

Browse files
committed
feat: implement cross-platform build system with GitHub Actions
Set up comprehensive build infrastructure for creating standalone executables across all target platforms: - Migrate from deprecated pkg to @yao-pkg/pkg (v5.15.0) - Maintained fork with Node 20+ support - Better ARM64 compatibility - Add GitHub Actions workflow (.github/workflows/release.yml) - Matrix build for 6 platforms (Windows x64, macOS x64/ARM64, Linux x64/ARM64/ARMv7) - Uses FREE native ARM64 runners (ubuntu-24.04-arm) for optimal performance - Automatic GitHub Release creation with artifacts - Manual workflow dispatch with version input - Add platform build wrapper script - Provides formatted timing output for local builds - Color-coded status indicators - Adapted from FlashForgeUI-Electron project - Enhance package.json build scripts - Add wrapped build commands with timing (build:*:wrapped) - Support for all 6 target platforms - Added tsx for TypeScript script execution This enables both local multi-platform builds and automated releases via GitHub Actions. Ready for production release workflow.
1 parent 3040293 commit 48667be

5 files changed

Lines changed: 1174 additions & 320 deletions

File tree

.claude/settings.local.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
"Bash(dir /s /b *.tsx 2)",
88
"Bash(nul)",
99
"Bash(dir /s /b:*)",
10-
"Bash(findstr:*)"
10+
"Bash(findstr:*)",
11+
"WebSearch",
12+
"Bash(node:*)"
1113
],
1214
"deny": [],
1315
"ask": []

.github/workflows/release.yml

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
name: Build and Release FlashForgeWebUI
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
version:
7+
description: 'Version Number (e.g., 1.0.0)'
8+
required: true
9+
default: ''
10+
prerelease:
11+
description: 'Is this a Pre-Release?'
12+
type: boolean
13+
default: false
14+
15+
jobs:
16+
build:
17+
runs-on: ${{ matrix.os }}
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
include:
22+
# Windows x64 (native)
23+
- os: windows-latest
24+
platform: win
25+
arch: x64
26+
output: flashforge-webui-win-x64.exe
27+
28+
# macOS x64 (Intel)
29+
- os: macos-13
30+
platform: mac
31+
arch: x64
32+
output: flashforge-webui-macos-x64
33+
34+
# macOS ARM64 (Apple Silicon)
35+
- os: macos-latest
36+
platform: mac
37+
arch: arm64
38+
output: flashforge-webui-macos-arm64
39+
40+
# Linux x64
41+
- os: ubuntu-latest
42+
platform: linux
43+
arch: x64
44+
output: flashforge-webui-linux-x64
45+
46+
# Linux ARM64 (native ARM runner - requires public repo)
47+
- os: ubuntu-24.04-arm
48+
platform: linux
49+
arch: arm64
50+
output: flashforge-webui-linux-arm64
51+
52+
# Linux ARMv7 (cross-compile from x64)
53+
- os: ubuntu-latest
54+
platform: linux
55+
arch: armv7
56+
output: flashforge-webui-linux-armv7
57+
58+
steps:
59+
- name: Checkout FlashForgeWebUI
60+
uses: actions/checkout@v4
61+
62+
- name: Setup Node.js 20
63+
uses: actions/setup-node@v4
64+
with:
65+
node-version: 20
66+
cache: 'npm'
67+
68+
- name: Configure GitHub Packages Authentication
69+
shell: bash
70+
run: |
71+
echo "Setting up GitHub Packages authentication"
72+
echo "@ghosttypes:registry=https://npm.pkg.github.com" >> .npmrc
73+
echo "@parallel-7:registry=https://npm.pkg.github.com" >> .npmrc
74+
echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> .npmrc
75+
env:
76+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77+
78+
- name: Run npm ci
79+
shell: bash
80+
run: |
81+
npm ci
82+
env:
83+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
84+
85+
- name: Set Application Version
86+
shell: bash
87+
run: |
88+
VERSION="${{ github.event.inputs.version }}"
89+
if [[ "$VERSION" == *.* && "$VERSION" != *.*.* ]]; then
90+
VERSION="${VERSION}.0"
91+
elif [[ "$VERSION" != *.* ]]; then
92+
VERSION="${VERSION}.0.0"
93+
fi
94+
echo "Setting version to: $VERSION"
95+
npm version "$VERSION" --no-git-tag-version --allow-same-version
96+
97+
- name: Build application
98+
shell: bash
99+
run: |
100+
# Build the TypeScript source
101+
npm run build
102+
103+
# Package with yao-pkg based on platform/arch
104+
if [[ "${{ matrix.platform }}" == "win" ]]; then
105+
npx yao-pkg . --targets node20-win-${{ matrix.arch }} --output dist/${{ matrix.output }}
106+
elif [[ "${{ matrix.platform }}" == "mac" ]]; then
107+
npx yao-pkg . --targets node20-macos-${{ matrix.arch }} --output dist/${{ matrix.output }}
108+
elif [[ "${{ matrix.platform }}" == "linux" ]]; then
109+
npx yao-pkg . --targets node20-linux-${{ matrix.arch }} --output dist/${{ matrix.output }}
110+
fi
111+
112+
- name: Upload Build Artifacts
113+
uses: actions/upload-artifact@v4
114+
with:
115+
name: ${{ matrix.output }}
116+
path: dist/${{ matrix.output }}
117+
if-no-files-found: error
118+
119+
create_github_release:
120+
needs: build
121+
runs-on: ubuntu-latest
122+
permissions:
123+
contents: write
124+
steps:
125+
- name: Checkout code
126+
uses: actions/checkout@v4
127+
128+
- name: Download all build artifacts
129+
uses: actions/download-artifact@v4
130+
with:
131+
path: artifacts
132+
133+
- name: Display downloaded artifacts structure
134+
shell: bash
135+
run: |
136+
echo "Downloaded artifacts layout:"
137+
ls -R artifacts
138+
139+
- name: Prepare Release Assets
140+
id: prep_assets
141+
shell: bash
142+
run: |
143+
mkdir release_assets
144+
145+
# Copy all executables from artifact directories
146+
find artifacts/ -type f -executable -o -name "*.exe" | while IFS= read -r file; do
147+
filename=$(basename "$file")
148+
cp "$file" "release_assets/$filename"
149+
echo "Copied $file to release_assets/$filename"
150+
done
151+
152+
# Also copy any non-executable files (in case executables lose +x during artifact download)
153+
find artifacts/ -type f ! -name "*.exe" | while IFS= read -r file; do
154+
filename=$(basename "$file")
155+
if [[ ! -f "release_assets/$filename" ]]; then
156+
cp "$file" "release_assets/$filename"
157+
echo "Copied $file to release_assets/$filename"
158+
fi
159+
done
160+
161+
echo "Prepared assets in release_assets:"
162+
ls -lh release_assets/
163+
164+
- name: Generate Release Notes
165+
id: generate_notes
166+
shell: bash
167+
run: |
168+
VERSION="${{ github.event.inputs.version }}"
169+
if [[ "$VERSION" == *.* && "$VERSION" != *.*.* ]]; then
170+
VERSION="${VERSION}.0"
171+
elif [[ "$VERSION" != *.* ]]; then
172+
VERSION="${VERSION}.0.0"
173+
fi
174+
175+
IS_PRERELEASE="${{ github.event.inputs.prerelease }}"
176+
RELEASE_TYPE_BADGE=""
177+
if [[ "$IS_PRERELEASE" == "true" ]]; then
178+
RELEASE_TYPE_BADGE=" (Pre-release)"
179+
fi
180+
181+
cat > RELEASE_NOTES.md << EOF
182+
# FlashForgeWebUI v${VERSION}${RELEASE_TYPE_BADGE}
183+
184+
Standalone web-based interface for FlashForge 3D printers.
185+
186+
## Downloads
187+
188+
Choose the appropriate binary for your platform:
189+
190+
- **Windows (x64)**: \`flashforge-webui-win-x64.exe\`
191+
- **macOS (Intel)**: \`flashforge-webui-macos-x64\`
192+
- **macOS (Apple Silicon)**: \`flashforge-webui-macos-arm64\`
193+
- **Linux (x64)**: \`flashforge-webui-linux-x64\`
194+
- **Linux (ARM64)**: \`flashforge-webui-linux-arm64\` (Raspberry Pi 4/5, ARM servers)
195+
- **Linux (ARMv7)**: \`flashforge-webui-linux-armv7\` (Raspberry Pi 3, older ARM devices)
196+
197+
## Installation
198+
199+
1. Download the appropriate binary for your platform
200+
2. Make it executable (Linux/macOS): \`chmod +x flashforge-webui-*\`
201+
3. Run it: \`./flashforge-webui-*\` (or \`flashforge-webui-*.exe\` on Windows)
202+
203+
## Usage
204+
205+
Run with no arguments to start the WebUI server only:
206+
\`\`\`bash
207+
./flashforge-webui-linux-x64
208+
\`\`\`
209+
210+
Or use CLI options to auto-connect to printers:
211+
\`\`\`bash
212+
# Connect to last used printer
213+
./flashforge-webui-linux-x64 --last-used
214+
215+
# Connect to all saved printers
216+
./flashforge-webui-linux-x64 --all-saved-printers
217+
218+
# Connect to specific printer(s)
219+
./flashforge-webui-linux-x64 --printers="192.168.1.100:new:12345678"
220+
221+
# Customize WebUI port and password
222+
./flashforge-webui-linux-x64 --webui-port=3001 --webui-password=mypassword
223+
\`\`\`
224+
225+
See the [README](https://github.com/Parallel-7/FlashForgeWebUI) for full documentation.
226+
227+
EOF
228+
229+
echo "VERSION_TAG=v${VERSION}" >> $GITHUB_ENV
230+
echo "RELEASE_NAME=FlashForgeWebUI v${VERSION}${RELEASE_TYPE_BADGE}" >> $GITHUB_ENV
231+
echo "RELEASE_NOTES_PATH=RELEASE_NOTES.md" >> $GITHUB_ENV
232+
233+
- name: Create GitHub Release
234+
uses: softprops/action-gh-release@v2
235+
with:
236+
tag_name: ${{ env.VERSION_TAG }}
237+
name: ${{ env.RELEASE_NAME }}
238+
body_path: ${{ env.RELEASE_NOTES_PATH }}
239+
draft: false
240+
prerelease: ${{ github.event.inputs.prerelease }}
241+
files: |
242+
release_assets/*
243+
env:
244+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)