Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 58 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,26 @@ jobs:
run: uv sync --locked --all-extras --group desktop
- name: Build desktop application
run: uv run --locked --all-extras --group desktop pyinstaller --noconfirm --clean setuav-studio.spec
- name: Install NSIS
if: runner.os == 'Windows'
shell: pwsh
run: choco install nsis --no-progress -y
- name: Verify Linux or Windows bundle
if: runner.os != 'macOS'
env:
SETUAV_DESKTOP_SMOKE_TIMEOUT: "180"
shell: bash
run: |
python scripts/verify_desktop_resources.py dist/setuav-studio
python scripts/desktop_startup_smoke_test.py dist/setuav-studio
if [[ "${RUNNER_OS}" == "Windows" ]]; then
python scripts/desktop_startup_smoke_test.py dist/setuav-studio --skip-aero-3d
else
python scripts/desktop_startup_smoke_test.py dist/setuav-studio
fi
- name: Verify macOS bundle
if: runner.os == 'macOS'
env:
SETUAV_DESKTOP_SMOKE_TIMEOUT: "180"
run: |
python scripts/verify_desktop_resources.py "dist/Setuav Studio.app"
python scripts/desktop_startup_smoke_test.py "dist/Setuav Studio.app"
Expand All @@ -110,36 +122,77 @@ jobs:
shell: bash
run: |
archive="setuav-studio-${GITHUB_REF_NAME}-linux-x86_64.tar.gz"
appimage="setuav-studio-${GITHUB_REF_NAME}-linux-x86_64.AppImage"
tar -czf "${archive}" -C dist setuav-studio
sha256sum "${archive}" > "${archive}.sha256"
appdir="Setuav.AppDir"
mkdir -p "${appdir}/usr/lib/setuav-studio"
mkdir -p "${appdir}/usr/share/icons/hicolor/256x256/apps"
cp -a dist/setuav-studio/. "${appdir}/usr/lib/setuav-studio/"
cp packaging/AppRun "${appdir}/AppRun"
cp packaging/setuav.desktop "${appdir}/setuav.desktop"
cp src/setuav_studio/assets/icons/studio.png "${appdir}/setuav-studio.png"
cp src/setuav_studio/assets/icons/studio.png \
"${appdir}/usr/share/icons/hicolor/256x256/apps/setuav-studio.png"
chmod +x "${appdir}/AppRun"
wget -q -O appimagetool \
"https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage"
chmod +x appimagetool
ARCH=x86_64 ./appimagetool --appimage-extract-and-run --no-appstream \
"${appdir}" "${appimage}"
sha256sum "${appimage}" > "${appimage}.sha256"
echo "RELEASE_ARCHIVE=${archive}" >> "${GITHUB_ENV}"
echo "RELEASE_EXTRA_ASSET=${appimage}" >> "${GITHUB_ENV}"
echo "RELEASE_EXTRA_CHECKSUM=${appimage}.sha256" >> "${GITHUB_ENV}"
- name: Package Windows release
if: runner.os == 'Windows'
shell: pwsh
run: |
$archive = "setuav-studio-$env:GITHUB_REF_NAME-windows-x86_64.zip"
$version = $env:GITHUB_REF_NAME.Substring(1)
$installer = "dist\setuav-studio-Setup-$version.exe"
$installerAsset = "setuav-studio-$env:GITHUB_REF_NAME-windows-x86_64.exe"
Compress-Archive -Path "dist/setuav-studio" -DestinationPath $archive
& "C:\Program Files (x86)\NSIS\makensis.exe" "/DAPP_VERSION=$version" "packaging\installer.nsi"
if ($LASTEXITCODE -ne 0) { throw "NSIS build failed." }
if (-not (Test-Path $installer)) { throw "Windows installer was not created: $installer" }
Copy-Item $installer $installerAsset
$hash = (Get-FileHash $archive -Algorithm SHA256).Hash.ToLower()
"$hash $archive" | Set-Content "$archive.sha256"
$installerHash = (Get-FileHash $installerAsset -Algorithm SHA256).Hash.ToLower()
"$installerHash $installerAsset" | Set-Content "$installerAsset.sha256"
"RELEASE_ARCHIVE=$archive" >> $env:GITHUB_ENV
"RELEASE_EXTRA_ASSET=$installerAsset" >> $env:GITHUB_ENV
"RELEASE_EXTRA_CHECKSUM=$installerAsset.sha256" >> $env:GITHUB_ENV
- name: Package macOS release
if: runner.os == 'macOS'
shell: bash
run: |
architecture="$(uname -m)"
archive="setuav-studio-${GITHUB_REF_NAME}-macos-${architecture}.app.zip"
disk_image="setuav-studio-${GITHUB_REF_NAME}-macos-${architecture}.dmg"
ditto -c -k --sequesterRsrc --keepParent "dist/Setuav Studio.app" "${archive}"
hdiutil create \
-volname "Setuav Studio" \
-srcfolder "dist/Setuav Studio.app" \
-ov \
-format UDZO \
"${disk_image}"
shasum -a 256 "${archive}" > "${archive}.sha256"
shasum -a 256 "${disk_image}" > "${disk_image}.sha256"
echo "RELEASE_ARCHIVE=${archive}" >> "${GITHUB_ENV}"
echo "RELEASE_EXTRA_ASSET=${disk_image}" >> "${GITHUB_ENV}"
echo "RELEASE_EXTRA_CHECKSUM=${disk_image}.sha256" >> "${GITHUB_ENV}"
- name: Upload release assets
env:
GH_TOKEN: ${{ github.token }}
shell: bash
run: |
gh release upload "${GITHUB_REF_NAME}" \
"${RELEASE_ARCHIVE}" \
"${RELEASE_ARCHIVE}.sha256" \
--clobber
assets=("${RELEASE_ARCHIVE}" "${RELEASE_ARCHIVE}.sha256")
if [[ -n "${RELEASE_EXTRA_ASSET:-}" ]]; then
assets+=("${RELEASE_EXTRA_ASSET}" "${RELEASE_EXTRA_CHECKSUM}")
fi
gh release upload "${GITHUB_REF_NAME}" "${assets[@]}" --clobber

package:
name: Build Python packages
Expand Down
5 changes: 5 additions & 0 deletions packaging/AppRun
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -e

app_dir="$(dirname "$(readlink -f "$0")")"
exec "$app_dir/usr/lib/setuav-studio/setuav-studio" "$@"
71 changes: 71 additions & 0 deletions packaging/installer.nsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
; Setuav Studio Windows installer.
; Built by the release workflow with NSIS 3.x.

Unicode true
SetCompressor /SOLID lzma

!define APP_NAME "Setuav Studio"
!ifndef APP_VERSION
!define APP_VERSION "0.1.0"
!endif
!define APP_EXE "setuav-studio.exe"
!define SOURCE_DIR "..\dist\setuav-studio"
!define REG_UNINSTALL "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"

!include "MUI2.nsh"

!if /FileExists "..\src\setuav_studio\assets\icons\studio.ico"
!define MUI_ICON "..\src\setuav_studio\assets\icons\studio.ico"
!define MUI_UNICON "..\src\setuav_studio\assets\icons\studio.ico"
!endif

!define MUI_FINISHPAGE_RUN "$INSTDIR\${APP_EXE}"
!define MUI_FINISHPAGE_RUN_TEXT "Launch ${APP_NAME}"

!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"

Name "${APP_NAME} ${APP_VERSION}"
OutFile "..\dist\setuav-studio-Setup-${APP_VERSION}.exe"
InstallDir "$PROGRAMFILES64\Setuav Studio"
InstallDirRegKey HKLM "Software\${APP_NAME}" "Install_Dir"
RequestExecutionLevel admin
ShowInstDetails show
ShowUnInstDetails show

Section "Setuav Studio" SecMain
SectionIn RO
SetOutPath "$INSTDIR"
File /r "${SOURCE_DIR}\*"

WriteUninstaller "$INSTDIR\uninstall.exe"
WriteRegStr HKLM "Software\${APP_NAME}" "Install_Dir" "$INSTDIR"
WriteRegStr HKLM "${REG_UNINSTALL}" "DisplayName" "${APP_NAME}"
WriteRegStr HKLM "${REG_UNINSTALL}" "UninstallString" '"$INSTDIR\uninstall.exe"'
WriteRegStr HKLM "${REG_UNINSTALL}" "DisplayVersion" "${APP_VERSION}"
WriteRegStr HKLM "${REG_UNINSTALL}" "Publisher" "Setuav"
WriteRegStr HKLM "${REG_UNINSTALL}" "InstallLocation" "$INSTDIR"
WriteRegDWORD HKLM "${REG_UNINSTALL}" "NoModify" 1
WriteRegDWORD HKLM "${REG_UNINSTALL}" "NoRepair" 1
SectionEnd

Section "Start Menu shortcuts" SecStartMenu
CreateDirectory "$SMPROGRAMS\${APP_NAME}"
CreateShortcut "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" "$INSTDIR\${APP_EXE}"
CreateShortcut "$SMPROGRAMS\${APP_NAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe"
SectionEnd

Section "Uninstall"
Delete "$INSTDIR\uninstall.exe"
RMDir /r "$INSTDIR"
Delete "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk"
Delete "$SMPROGRAMS\${APP_NAME}\Uninstall.lnk"
RMDir "$SMPROGRAMS\${APP_NAME}"
DeleteRegKey HKLM "${REG_UNINSTALL}"
DeleteRegKey HKLM "Software\${APP_NAME}"
SectionEnd
9 changes: 9 additions & 0 deletions packaging/setuav.desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[Desktop Entry]
Name=Setuav Studio
Comment=Plugin-based UAV design and analysis studio
Exec=setuav-studio
Icon=setuav-studio
Terminal=false
Type=Application
Categories=Science;Engineering;
StartupNotify=true
34 changes: 22 additions & 12 deletions scripts/desktop_startup_smoke_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@

PROJECT_ROOT = Path(__file__).resolve().parent.parent
TEST_PROJECT = PROJECT_ROOT / "tests" / "fixtures" / "fixed-wing" / "project.json"
SMOKE_TEST_TIMEOUT_SECONDS = int(os.environ.get("SETUAV_DESKTOP_SMOKE_TIMEOUT", "60"))


def _parse_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument("bundle", type=Path, help="PyInstaller desktop bundle")
parser.add_argument(
"--skip-aero-3d",
action="store_true",
help="skip the native AeroSandbox/PyVista smoke test",
)
return parser.parse_args()


Expand All @@ -32,7 +38,7 @@ def _run_command(executable: Path, arguments: list[str], environment: dict[str,
check=False,
capture_output=True,
text=True,
timeout=60,
timeout=SMOKE_TEST_TIMEOUT_SECONDS,
env=environment,
)
if result.returncode != 0:
Expand Down Expand Up @@ -86,17 +92,21 @@ def main() -> int:
}
)
_run_command(executable, ["--smoke-test"], environment)
viewer_payload = _viewer_payload_path()
try:
_run_command(
executable,
["--smoke-test-aero-3d", str(viewer_payload)],
environment,
)
finally:
viewer_payload.unlink(missing_ok=True)

print(f"Desktop startup and VLM viewer smoke tests passed: {executable}")
if not arguments.skip_aero_3d:
viewer_payload = _viewer_payload_path()
try:
_run_command(
executable,
["--smoke-test-aero-3d", str(viewer_payload)],
environment,
)
finally:
viewer_payload.unlink(missing_ok=True)

if arguments.skip_aero_3d:
print(f"Desktop startup smoke test passed (AeroSandbox 3D skipped): {executable}")
else:
print(f"Desktop startup and VLM viewer smoke tests passed: {executable}")
return 0


Expand Down
Loading