Skip to content

Commit 84da4c8

Browse files
committed
fix: GitHub Actions CI + build script for x86/ARM64
Workflow changes: - Split into separate native jobs (no QEMU cross-compile) - x86_64: runs on ubuntu-latest (native) - aarch64: runs on ubuntu-24.04-arm (native ARM64 runner) - Added disk space cleanup (runners have ~14GB, need ~12GB) - 90-minute timeout for ISO builds - Auto-release with both ISOs on version tags Build script fixes: - Fixed kernel package: linux-image-generic (not linux-image-amd64) - Fixed Chromium: use apt instead of snap (snap fails in chroot) - Qt6 binary patch: guarded to ARM64-only (offsets are arch-specific) - grub-efi meta-package instead of arch-specific variant
1 parent 01f3fdf commit 84da4c8

3 files changed

Lines changed: 147 additions & 45 deletions

File tree

.github/workflows/build-iso.yml

Lines changed: 111 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,58 +9,145 @@ on:
99
workflow_dispatch:
1010

1111
jobs:
12-
build-iso:
12+
# ═══════════════════════════════════════════════════════════════
13+
# x86_64 build — runs natively on standard Ubuntu runner
14+
# ═══════════════════════════════════════════════════════════════
15+
build-x86:
1316
runs-on: ubuntu-latest
1417
permissions:
1518
contents: write
19+
timeout-minutes: 90
1620

17-
strategy:
18-
matrix:
19-
arch: [x86_64, aarch64]
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v4
24+
25+
- name: Free disk space
26+
run: |
27+
# GitHub runners have ~14GB free. ISO build needs ~12GB.
28+
# Remove unnecessary pre-installed software to free space.
29+
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc \
30+
/usr/local/share/boost /usr/share/swift /opt/hostedtoolcache 2>/dev/null || true
31+
sudo apt-get autoremove -y 2>/dev/null || true
32+
sudo apt-get clean
33+
df -h /
34+
35+
- name: Install build dependencies
36+
run: |
37+
sudo apt-get update -qq
38+
sudo apt-get install -y \
39+
debootstrap xorriso mtools squashfs-tools \
40+
grub-efi-amd64-bin grub-pc-bin \
41+
dosfstools xz-utils
42+
43+
- name: Build ISO (x86_64)
44+
run: |
45+
chmod +x ./scripts/build-iso.sh
46+
sudo bash ./scripts/build-iso.sh --arch=x86_64 --clean
47+
48+
- name: Compress ISO
49+
run: |
50+
ls -lh tensoragent-os-x86_64.iso
51+
xz -T0 -6 tensoragent-os-x86_64.iso
52+
ls -lh tensoragent-os-x86_64.iso.xz
53+
54+
- name: Upload ISO artifact
55+
uses: actions/upload-artifact@v4
56+
with:
57+
name: tensoragent-os-x86_64
58+
path: tensoragent-os-x86_64.iso.xz
59+
retention-days: 30
60+
61+
- name: Upload to release (tags only)
62+
if: startsWith(github.ref, 'refs/tags/v')
63+
uses: softprops/action-gh-release@v2
64+
with:
65+
files: tensoragent-os-x86_64.iso.xz
66+
67+
# ═══════════════════════════════════════════════════════════════
68+
# aarch64 build — runs on native ARM64 runner (no QEMU needed)
69+
# ═══════════════════════════════════════════════════════════════
70+
build-arm64:
71+
runs-on: ubuntu-24.04-arm
72+
permissions:
73+
contents: write
74+
timeout-minutes: 90
2075

2176
steps:
2277
- name: Checkout
2378
uses: actions/checkout@v4
2479

80+
- name: Free disk space
81+
run: |
82+
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc \
83+
/usr/local/share/boost /usr/share/swift /opt/hostedtoolcache 2>/dev/null || true
84+
sudo apt-get autoremove -y 2>/dev/null || true
85+
sudo apt-get clean
86+
df -h /
87+
2588
- name: Install build dependencies
2689
run: |
27-
sudo apt-get update
90+
sudo apt-get update -qq
2891
sudo apt-get install -y \
2992
debootstrap xorriso mtools squashfs-tools \
30-
grub-pc-bin grub-efi-amd64-bin \
31-
qemu-user-static binfmt-support dosfstools xz-utils
93+
grub-efi-arm64-bin \
94+
dosfstools xz-utils
3295
33-
- name: Build ISO (${{ matrix.arch }})
96+
- name: Build ISO (aarch64)
3497
run: |
3598
chmod +x ./scripts/build-iso.sh
36-
sudo bash ./scripts/build-iso.sh --arch=${{ matrix.arch }} --skip-chromium
99+
sudo bash ./scripts/build-iso.sh --arch=aarch64 --clean
37100
38101
- name: Compress ISO
39102
run: |
40-
xz -T0 -9 tensoragent-os-${{ matrix.arch }}.iso
41-
ls -lh tensoragent-os-${{ matrix.arch }}.iso.xz
103+
ls -lh tensoragent-os-aarch64.iso
104+
xz -T0 -6 tensoragent-os-aarch64.iso
105+
ls -lh tensoragent-os-aarch64.iso.xz
42106
43107
- name: Upload ISO artifact
44108
uses: actions/upload-artifact@v4
45109
with:
46-
name: tensoragent-os-${{ matrix.arch }}
47-
path: tensoragent-os-*.iso.xz
110+
name: tensoragent-os-aarch64
111+
path: tensoragent-os-aarch64.iso.xz
48112
retention-days: 30
49113

50-
- name: Upload ISO for release
114+
- name: Upload to release (tags only)
51115
if: startsWith(github.ref, 'refs/tags/v')
52116
uses: softprops/action-gh-release@v2
53117
with:
54-
files: tensoragent-os-*.iso.xz
118+
files: tensoragent-os-aarch64.iso.xz
119+
120+
# ═══════════════════════════════════════════════════════════════
121+
# Create GitHub Release (on tags only)
122+
# ═══════════════════════════════════════════════════════════════
123+
release:
124+
if: startsWith(github.ref, 'refs/tags/v')
125+
needs: [build-x86, build-arm64]
126+
runs-on: ubuntu-latest
127+
permissions:
128+
contents: write
129+
130+
steps:
131+
- name: Download all ISOs
132+
uses: actions/download-artifact@v4
133+
with:
134+
merge-multiple: true
135+
136+
- name: Create Release
137+
uses: softprops/action-gh-release@v2
138+
with:
139+
files: |
140+
tensoragent-os-x86_64.iso.xz
141+
tensoragent-os-aarch64.iso.xz
55142
generate_release_notes: true
56143
body: |
57144
## TensorAgent OS ${{ github.ref_name }}
58145
59146
### Downloads
60-
| Architecture | File |
61-
|-------------|------|
62-
| x86_64 (Intel/AMD) | `tensoragent-os-x86_64.iso.xz` |
63-
| aarch64 (ARM64 / Apple Silicon) | `tensoragent-os-aarch64.iso.xz` |
147+
| Architecture | File | For |
148+
|-------------|------|-----|
149+
| x86_64 (Intel/AMD) | `tensoragent-os-x86_64.iso.xz` | PC, VirtualBox, VMware Workstation |
150+
| aarch64 (ARM64) | `tensoragent-os-aarch64.iso.xz` | Apple Silicon, UTM, VMware Fusion |
64151
65152
> **Decompress after download:** `xz -d tensoragent-os-*.iso.xz`
66153
@@ -74,13 +161,15 @@ jobs:
74161
75162
# VMware Fusion (Apple Silicon) — use the aarch64 ISO
76163
# UTM (macOS) — use the aarch64 ISO
164+
# VirtualBox / VMware Workstation — use the x86_64 ISO
77165
```
78166
79167
### What's included
80168
- 🐋 OpenWhale AI engine (multi-agent, MCP, tools)
81-
- 🖥️ WhaleOS Qt6 desktop shell
82-
- 📦 Debian Bookworm base
169+
- 🖥️ WhaleOS Qt6 Wayland desktop shell
170+
- 📦 Ubuntu 24.04 LTS (Noble) base
83171
- ⚡ Node.js 22, Python 3, SQLite
84-
- 🌐 Chromium, terminal, and system tools
172+
- 🌐 Chromium, Mousepad, Galculator, LibreOffice
173+
- 🔒 Enterprise security (AppArmor, auditd, fail2ban)
85174
86175
**Login:** `ainux` / `ainux`

scripts/build-iso.sh

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ sudo chroot "$ROOTFS_DIR" /bin/bash -c '
152152
# Core system + build tools
153153
apt-get install -y -qq \
154154
build-essential pkg-config g++ \
155-
linux-image-'"$KERNEL_ARCH"' grub-efi-'"$DEB_ARCH"' \
155+
linux-image-generic grub-efi \
156156
systemd-boot linux-firmware \
157-
2>/dev/null || apt-get install -y -qq build-essential pkg-config g++ linux-image-'"$KERNEL_ARCH"' grub-efi
157+
2>/dev/null || apt-get install -y -qq build-essential pkg-config g++ linux-image-generic grub-efi
158158
159159
# Graphics & Wayland
160160
apt-get install -y -qq \
@@ -216,10 +216,11 @@ sudo chroot "$ROOTFS_DIR" /bin/bash -c '
216216
evince \
217217
2>/dev/null || echo " [SKIP] Some office/PDF packages unavailable"
218218
219-
# Chromium — preinstalled web browser via snap (native .deb not available on Ubuntu 24.04 ARM64)
220-
snap install chromium 2>/dev/null \
221-
|| apt-get install -y -qq chromium-browser 2>/dev/null \
222-
|| echo " ⚠ Chromium not available for this architecture"
219+
# Chromium — preinstalled web browser
220+
# snap does not work in chroot/CI environments, use apt packages
221+
apt-get install -y -qq chromium-browser 2>/dev/null \
222+
|| apt-get install -y -qq chromium 2>/dev/null \
223+
|| echo " ⚠ Chromium not available for this architecture, install manually after first boot"
223224
224225
# Preinstalled native apps — all apps shown in NativeAppsLauncher
225226
apt-get install -y -qq \
@@ -300,29 +301,34 @@ NMRES
300301
301302
echo " ✓ Dependencies installed"
302303
303-
# ── Patch Qt 6.4.2 Wayland Compositor binary ──────────────────────
304+
# ── Patch Qt 6.4.2 Wayland Compositor binary (ARM64 ONLY) ─────────
304305
# Qt 6.4's libQt6WaylandCompositor has stub implementations for critical
305306
# Wayland protocol functions that print "Not implemented" and cause
306307
# Chrome/Chromium to crash on right-click (context menu popups).
307308
# We patch these stubs to ARM64 'ret' (immediate return, no-op).
308309
# This must happen OUTSIDE the chroot using the rootfs path from the host.
309-
QT_SO=$(find "${ROOTFS_DIR}/usr/lib" -name "libQt6WaylandCompositor.so.6.4.2" -type f 2>/dev/null | head -1)
310-
if [ -n "$QT_SO" ] && [ -f "$QT_SO" ]; then
311-
echo " Patching Qt Wayland Compositor: $QT_SO"
312-
RET='\xc0\x03\x5f\xd6' # ARM64: ret instruction
313-
# xdg_popup_destroy (0xada78) + thunk (0xadb14)
314-
printf "$RET" | dd of="$QT_SO" bs=1 seek=$((0xada78)) conv=notrunc 2>/dev/null
315-
printf "$RET" | dd of="$QT_SO" bs=1 seek=$((0xadb14)) conv=notrunc 2>/dev/null
316-
# xdg_popup_grab (0xadbb0) + thunk (0xadc4c)
317-
printf "$RET" | dd of="$QT_SO" bs=1 seek=$((0xadbb0)) conv=notrunc 2>/dev/null
318-
printf "$RET" | dd of="$QT_SO" bs=1 seek=$((0xadc4c)) conv=notrunc 2>/dev/null
319-
# subsurface_set_desync (0xc5050)
320-
printf "$RET" | dd of="$QT_SO" bs=1 seek=$((0xc5050)) conv=notrunc 2>/dev/null
321-
# subsurface_set_sync (0xc4f50)
322-
printf "$RET" | dd of="$QT_SO" bs=1 seek=$((0xc4f50)) conv=notrunc 2>/dev/null
323-
echo " ✓ Qt Wayland stubs patched (xdg_popup_destroy/grab, subsurface sync/desync)"
310+
# NOTE: The offsets and instruction are ARM64-specific — skip on x86.
311+
if [ "$ARCH" = "aarch64" ]; then
312+
QT_SO=$(find "${ROOTFS_DIR}/usr/lib" -name "libQt6WaylandCompositor.so.6.4.2" -type f 2>/dev/null | head -1)
313+
if [ -n "$QT_SO" ] && [ -f "$QT_SO" ]; then
314+
echo " Patching Qt Wayland Compositor: $QT_SO"
315+
RET='\xc0\x03\x5f\xd6' # ARM64: ret instruction
316+
# xdg_popup_destroy (0xada78) + thunk (0xadb14)
317+
printf "$RET" | dd of="$QT_SO" bs=1 seek=$((0xada78)) conv=notrunc 2>/dev/null
318+
printf "$RET" | dd of="$QT_SO" bs=1 seek=$((0xadb14)) conv=notrunc 2>/dev/null
319+
# xdg_popup_grab (0xadbb0) + thunk (0xadc4c)
320+
printf "$RET" | dd of="$QT_SO" bs=1 seek=$((0xadbb0)) conv=notrunc 2>/dev/null
321+
printf "$RET" | dd of="$QT_SO" bs=1 seek=$((0xadc4c)) conv=notrunc 2>/dev/null
322+
# subsurface_set_desync (0xc5050)
323+
printf "$RET" | dd of="$QT_SO" bs=1 seek=$((0xc5050)) conv=notrunc 2>/dev/null
324+
# subsurface_set_sync (0xc4f50)
325+
printf "$RET" | dd of="$QT_SO" bs=1 seek=$((0xc4f50)) conv=notrunc 2>/dev/null
326+
echo " ✓ Qt Wayland stubs patched (xdg_popup_destroy/grab, subsurface sync/desync)"
327+
else
328+
echo " ⚠ libQt6WaylandCompositor.so.6.4.2 not found in rootfs, skipping patch"
329+
fi
324330
else
325-
echo " ⚠ libQt6WaylandCompositor.so.6.4.2 not found in rootfs, skipping patch"
331+
echo " ⏭ Qt Wayland patch skipped (x86_64 — ARM64-specific offsets)"
326332
fi
327333

328334
# ─── Create User ───────────────────────────────────────────────

vmware_build/vmware.log

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,3 +1323,10 @@
13231323
2026-06-15T01:13:19.522Z In(05) vcpu-0 GuestInfo: HostinfoDetailedDataHeader version: 1
13241324
2026-06-15T01:13:19.522Z No(00) vcpu-0 ConfigDB: Setting guestInfo.detailed.data = <not printed>
13251325
2026-06-15T01:45:29.000Z In(05) vmx DISKLIB-LIB : numIOs = 50000 numMergedIOs = 16431 numSplitIOs = 567
1326+
2026-06-15T02:05:32.007Z In(05) vmx USB: New set of 2 USB devices.
1327+
2026-06-15T02:05:32.007Z In(05) vmx USB: Found device [name:Logitech\ Brio\ 100 vid:046d pid:094c path:48/1 speed:high family:audio,video serialnum:2508AP76H858 arbRuntimeKey:4 version:5]
1328+
2026-06-15T02:05:32.008Z In(05) vmx USB: Found device [name:Apple\ USB-C\ Digital\ AV\ Multiport\ Adapter vid:05ac pid:1460 path:0/1/2 speed:low family:other serialnum:DLC7476012CG2KQAP arbRuntimeKey:3 version:5]
1329+
2026-06-15T02:05:32.036Z In(05) host-39358774 VNET: MACVNetPortVirtApiPrimaryIfaceChanged: Global state callback for adapter: 0, primary if: en1
1330+
2026-06-15T02:05:32.036Z In(05) vmx VNET: MACVNetLinkStateEventHandler: event, up:1, adapter:0
1331+
2026-06-15T02:05:32.062Z In(05) host-39358774 VNET: MACVNetPortVirtApiPrimaryIfaceChanged: Global state callback for adapter: 0, primary if: en1
1332+
2026-06-15T02:05:32.062Z In(05) vmx VNET: MACVNetLinkStateEventHandler: event, up:1, adapter:0

0 commit comments

Comments
 (0)