hotfix: installation screen and check for updates #81
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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 |