name: CI on: push: branches: [main, master] pull_request: branches: [main, master] jobs: build-and-test: strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git vestibule/helper/target key: ${{ runner.os }}-cargo-${{ hashFiles('vestibule/helper/Cargo.lock') }} restore-keys: ${{ runner.os }}-cargo- - name: Build usher working-directory: vestibule/helper run: cargo build --release - name: Smoke test (Linux) if: runner.os == 'Linux' working-directory: vestibule run: python3 scripts/test-native-messaging.py - name: Smoke test (Windows) if: runner.os == 'Windows' working-directory: vestibule run: python scripts\test-native-messaging.py - name: Validate JSON working-directory: vestibule run: | python3 -c "import json; json.load(open('extension/manifest.json'))" python3 -c "import json; json.load(open('config/policies.json'))" python3 -c "import json; json.load(open('config/com.vestibule.usher.linux.json'))" python3 -c "import json; json.load(open('config/com.vestibule.usher.windows.json'))" python3 -c "import json; json.load(open('packaging/net.dcos.Vestibule.json'))" - name: Validate XML + icon assets working-directory: vestibule run: | python3 -c "import xml.dom.minidom; xml.dom.minidom.parse('packaging/net.dcos.Vestibule.metainfo.xml')" python3 - <<'EOF' import os for f in ["packaging/icons/vestibule.ico", "packaging/icons/vestibule.svg"]: assert os.path.exists(f) and os.path.getsize(f) > 0, f print("icon assets ok") EOF - name: Check JS syntax working-directory: vestibule/extension run: | for f in *.js; do node --check "$f" || exit 1; done - name: URL policy unit tests working-directory: vestibule run: node scripts/test-url-policy.js - name: Check POSIX sh syntax if: runner.os == 'Linux' working-directory: vestibule/scripts run: | for f in *.sh vestibule-kiosk-launch; do sh -n "$f" || exit 1; done sh -n ../packaging/vestibule-flatpak-cli sh -n ../packaging/build-flatpak.sh - name: Check PowerShell syntax if: runner.os == 'Linux' working-directory: vestibule shell: pwsh run: | $files = Get-ChildItem scripts/*.ps1, packaging/*.ps1 foreach ($f in $files) { $errs = $null [void][System.Management.Automation.Language.Parser]::ParseFile($f.FullName, [ref]$null, [ref]$errs) if ($errs) { $errs | ForEach-Object { Write-Error "$($f.Name): $($_.Message)" } exit 1 } } Write-Host "PowerShell syntax OK ($($files.Count) files)" - name: Provision/deprovision integration test (rootless sandbox) if: runner.os == 'Linux' working-directory: vestibule run: sh scripts/test-provision-linux.sh - name: provision --check fails with documented exit code (no prereqs on runner) if: runner.os == 'Linux' working-directory: vestibule run: | code=0 sh scripts/provision-kiosk.sh --check || code=$? # The runner has systemd but no cage/LibreWolf -> documented exit 3. if [ "$code" -ne 3 ]; then echo "expected exit 3 (missing prerequisites), got $code" exit 1 fi echo "check mode returned documented exit code 3" - name: provision-kiosk.ps1 -Check fails fast off-Windows (exit 2) if: runner.os == 'Linux' working-directory: vestibule shell: pwsh run: | $code = 0 try { & pwsh -NoProfile -File scripts/provision-kiosk.ps1 -Check } catch { $code = 1 } if ($LASTEXITCODE -ne 2) { Write-Error "expected exit 2 (unsupported platform), got $LASTEXITCODE" exit 1 } Write-Host "Windows provisioner correctly refuses to run on Linux (exit 2)" package-windows: runs-on: windows-latest steps: - uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git vestibule/helper/target key: ${{ runner.os }}-cargo-${{ hashFiles('vestibule/helper/Cargo.lock') }} restore-keys: ${{ runner.os }}-cargo- - name: Install Inno Setup shell: powershell run: choco install innosetup -y --no-progress - name: Build installer + XPI working-directory: vestibule shell: powershell run: | powershell -NoProfile -ExecutionPolicy Bypass -File packaging\build-installer.ps1 # Standalone XPI artifact for policy-based manual deploys. Compress-Archive -Path extension\* -DestinationPath vestibule-1.2.2.xpi -Force - name: Upload installer artifact uses: actions/upload-artifact@v4 with: name: vestibule-setup-windows path: | vestibule/packaging/Output/Vestibule-Setup-1.2.2.exe vestibule/vestibule-1.2.2.xpi if-no-files-found: error package-linux: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git vestibule/helper/target key: ${{ runner.os }}-cargo-${{ hashFiles('vestibule/helper/Cargo.lock') }} restore-keys: ${{ runner.os }}-cargo- - name: Build usher (Linux binary) working-directory: vestibule/helper run: cargo build --release - name: Upload usher binary uses: actions/upload-artifact@v4 with: name: vestibule-usher-linux path: vestibule/helper/target/release/usher if-no-files-found: error - name: Build Flatpak bundle working-directory: vestibule run: | flatpak remote-add --if-not-exists --user flathub https://flathub.org/repo/flathub.flatpakrepo rm -rf packaging/repo packaging/builddir flatpak-builder --user --install-deps-from=flathub --force-clean \ --repo=packaging/repo packaging/builddir packaging/net.dcos.Vestibule.json flatpak build-bundle packaging/repo packaging/Vestibule-1.2.2.flatpak \ net.dcos.Vestibule 1.2.2 - name: Upload Flatpak artifact uses: actions/upload-artifact@v4 with: name: vestibule-flatpak-linux path: vestibule/packaging/Vestibule-1.2.2.flatpak if-no-files-found: error