Skip to content

hotfix: installation screen and check for updates #81

hotfix: installation screen and check for updates

hotfix: installation screen and check for updates #81

# Full workspace install (clone + Docker image + rosdep + colcon + yarn) plus a
# non-interactive launch smoke test, on both x86_64 and ARM64 GitHub-hosted runners.
#
# - DEV=false -> install.sh uses `url_https` from config/repos.json (sub-repos are public).
# - CI=true -> install.sh skips the host `xhost` check (no GUI on runners).
# - variant=arm runs on `ubuntu-24.04-arm` with `./install.sh --arm`; the built image
# is then verified to be linux/arm64 (linux/amd64 for the default variant).
# - Runner OS (22.04 or 24.04) is only the CI host. ROS Humble always runs inside
# Jammy-based images (`osrf/ros:humble-desktop` / `ros:humble-ros-base-jammy`).
# - `ubuntu-24.04-arm` is GitHub's hosted ARM64 runner label; there is no 22.04-arm
# standard runner. The container OS stays Jammy regardless.
# - The launch smoke test uses `./launch_lucy.sh --headless <command>`, which runs a
# single command inside the container (no control panel, no auto Gazebo/RViz).
name: Install, Launch & Release
on:
workflow_dispatch:
push:
branches: [master, dev]
tags:
- 'v*' # Run on version tags like v1.0, v2.3.4
pull_request:
branches: [master, dev]
permissions:
contents: read
jobs:
install-and-launch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.variant }}
cancel-in-progress: true
runs-on: ${{ matrix.runner }}
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
include:
- variant: default
runner: ubuntu-latest
use_arm_install: false
expected_arch: linux/amd64
- variant: arm
runner: ubuntu-24.04-arm
use_arm_install: true
expected_arch: linux/arm64
env:
DEV: "false"
CI: "true"
steps:
- uses: actions/checkout@v4
# Make sure no committed/local .env can flip DEV back to true at install time.
- name: Drop workspace .env if present
run: rm -f .env .env.local || true
# Docker Hub metadata/pull flakes (i/o timeout) fail `docker build` before
# any Dockerfile layer runs. Pre-pull with retries so the build reuses cache.
- name: Pre-pull base images (retry on Hub flakes)
run: |
pull_with_retry() {
image="$1"
for attempt in 1 2 3 4 5; do
if docker pull "$image"; then
return 0
fi
echo "docker pull ${image} failed (attempt ${attempt}/5), retrying..."
sleep $((attempt * 15))
done
return 1
}
if [ "${{ matrix.use_arm_install }}" = true ]; then
pull_with_retry ros:humble-ros-base-jammy
else
pull_with_retry osrf/ros:humble-desktop
fi
- name: Install (clone + Docker image + rosdep + colcon + yarn)
run: |
chmod +x install.sh launch_lucy.sh
if [ "${{ matrix.use_arm_install }}" = true ]; then
./install.sh --arm
else
./install.sh
fi
- name: Verify Lucy image architecture
run: |
osarch=$(docker image inspect lucy_ros2:humble --format '{{.Os}}/{{.Architecture}}')
echo "lucy_ros2:humble -> ${osarch}"
if [ "${osarch}" != "${{ matrix.expected_arch }}" ]; then
echo "::error::Expected ${{ matrix.expected_arch }} after ./install.sh on ${{ matrix.runner }}, got ${osarch}"
exit 1
fi
# Single command in the container -> bypasses the control-panel / Gazebo / RViz auto-launch.
- name: Launch smoke test (headless, no TTY)
run: ./launch_lucy.sh --headless ros2 doctor --report
# Windows-specific CI. NOTE: GitHub-hosted Windows runners cannot run Linux
# containers (no Hyper-V/nested virtualization, no WSL2), so the heavy install
# step (docker build of the ROS image + colcon) CANNOT run here — that is
# covered for both amd64/arm64 by the Linux `install-and-launch` job above.
# This job verifies the Windows-only pieces on real x64 AND arm64 hardware:
# - host CPU -> Docker platform detection (install_ops.host_container_platform)
# - Lucy.exe builds (PyInstaller) and its bundled --cli imports work
# - the NSIS installer compiles
windows-build-test:
name: Windows build & installer test (${{ matrix.arch }})
strategy:
fail-fast: false
matrix:
include:
- arch: x64
runner: windows-latest
expected_platform: linux/amd64
- arch: arm64
runner: windows-11-arm
expected_platform: linux/arm64
runs-on: ${{ matrix.runner }}
timeout-minutes: 30
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Generate releases manifest
run: python windows/generate_releases.py
- name: Verify host architecture detection
shell: pwsh
run: |
$expected = "${{ matrix.expected_platform }}"
$got = (python -c "import sys; sys.path.insert(0,'windows'); import install_ops; print(install_ops.host_container_platform())").Trim()
Write-Host "host_container_platform() -> $got (expected $expected)"
if ($got -ne $expected) {
Write-Error "Arch detection mismatch: got '$got', expected '$expected'"
exit 1
}
- name: Install PyInstaller
run: python -m pip install pyinstaller
- name: Build Lucy.exe
shell: pwsh
run: |
python -m PyInstaller --noconfirm --onefile --name Lucy `
--icon windows/assets/lucy-icon.ico `
--hidden-import install_ops `
--hidden-import install_runner `
--paths windows `
windows/Lucy.py
if (-not (Test-Path "dist/Lucy.exe")) { Write-Error "Lucy.exe not produced"; exit 1 }
- name: Smoke-test Lucy.exe CLI (bundled imports + prereq report)
shell: pwsh
run: |
dist\Lucy.exe --cli check-prereqs
$code = $LASTEXITCODE
Write-Host "check-prereqs exit code: $code"
# 0 (all present) or 1 (a prereq missing, e.g. no Docker on CI) both mean
# the exe ran fine; >1 = crash. Reset the propagated exit code explicitly.
if ($code -gt 1) { Write-Error "Lucy.exe --cli check-prereqs crashed (exit $code)"; exit 1 }
exit 0
- name: Install NSIS
run: choco install nsis -y --no-progress
- name: Build Lucy-Setup.exe (NSIS)
shell: pwsh
run: |
$makensis = "${env:ProgramFiles(x86)}\NSIS\makensis.exe"
& $makensis "/DMyAppVersion=0.0.0-ci" windows/installer/Lucy.nsi
if (-not (Test-Path "dist/Lucy-Setup-0.0.0-ci.exe")) { Write-Error "Installer not produced"; exit 1 }
- name: Upload Windows artifacts
uses: actions/upload-artifact@v4
with:
name: lucy-windows-${{ matrix.arch }}
path: |
dist/Lucy.exe
dist/Lucy-Setup-0.0.0-ci.exe
if-no-files-found: error
build-and-release-windows-exe:
name: Build and Release Windows Executable
# Only run this job when a new tag is pushed
if: startsWith(github.ref, 'refs/tags/')
runs-on: windows-latest
needs: install-and-launch
permissions:
contents: write # Required to create a release and upload assets
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Generate releases manifest
run: python windows/generate_releases.py
- name: Install PyInstaller
run: python -m pip install pyinstaller
- name: Build Lucy.exe
shell: pwsh
run: |
python -m PyInstaller --noconfirm --onefile --name Lucy `
--icon windows/assets/lucy-icon.ico `
--hidden-import install_ops `
--hidden-import install_runner `
--paths windows `
windows/Lucy.py
- name: Install NSIS
run: choco install nsis -y
- name: Build Lucy-Setup.exe
shell: pwsh
run: |
$version = "${{ github.ref_name }}" -replace '^v',''
if (-not $version) { $version = "0.0.0" }
$makensis = "${env:ProgramFiles(x86)}\NSIS\makensis.exe"
& $makensis "/DMyAppVersion=$version" windows/installer/Lucy.nsi
- name: Create Release and Upload Assets
uses: softprops/action-gh-release@v2
with:
files: |
dist/Lucy.exe
dist/Lucy-Setup-*.exe
draft: true