Merge pull request #17 from OpenIPC/fix/camera-test-status-and-reacha… #44
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
| name: build | |
| on: | |
| push: | |
| branches: [main] | |
| tags: ['v*'] | |
| paths-ignore: | |
| - '**/*.md' | |
| - 'docs/**' | |
| - '.github/ISSUE_TEMPLATE/**' | |
| - 'LICENSE' | |
| - '.gitignore' | |
| pull_request: | |
| branches: [main] | |
| paths-ignore: | |
| - '**/*.md' | |
| - 'docs/**' | |
| - '.github/ISSUE_TEMPLATE/**' | |
| - 'LICENSE' | |
| - '.gitignore' | |
| workflow_dispatch: | |
| jobs: | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: windows-latest | |
| rid: win-x64 | |
| archive: zip | |
| - os: ubuntu-latest | |
| rid: linux-x64 | |
| archive: tar.gz | |
| - os: macos-14 | |
| rid: osx-arm64 | |
| archive: tar.gz | |
| runs-on: ${{ matrix.os }} | |
| name: build (${{ matrix.rid }}) | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up .NET 9 | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '9.0.x' | |
| - name: Install ffmpeg + libsecret (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y ffmpeg libavcodec-extra libsecret-1-0 libsecret-tools | |
| - name: Install ffmpeg (macOS) | |
| if: runner.os == 'macOS' | |
| run: brew install ffmpeg | |
| - name: Fetch bundled ffmpeg (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: ./tools/fetch-ffmpeg.ps1 | |
| # Mobile heads (Android/iOS) need workloads not installed on these | |
| # runners and build in their own jobs — so the desktop matrix uses a | |
| # solution that excludes them. The shared App project still multi-targets | |
| # the mobile TFMs, so IncludeMobileTargets=false strips them to net9.0 for | |
| # these builds (a solution build / restore evaluates every TFM otherwise). | |
| - name: Restore | |
| run: dotnet restore OpenIPC.Viewer.Desktop.slnx -p:IncludeMobileTargets=false | |
| - name: Build | |
| run: dotnet build OpenIPC.Viewer.Desktop.slnx --configuration Release --no-restore /warnaserror -p:IncludeMobileTargets=false | |
| - name: Test | |
| run: dotnet test OpenIPC.Viewer.Desktop.slnx --configuration Release --no-build --verbosity normal -p:IncludeMobileTargets=false | |
| - name: Publish | |
| run: dotnet publish src/OpenIPC.Viewer.Desktop/OpenIPC.Viewer.Desktop.csproj -c Release -r ${{ matrix.rid }} --self-contained true /p:PublishSingleFile=true /p:IncludeNativeLibrariesForSelfExtract=true -p:IncludeMobileTargets=false -o publish/${{ matrix.rid }} | |
| - name: Package (zip) | |
| if: matrix.archive == 'zip' | |
| shell: pwsh | |
| run: | | |
| Compress-Archive -Path publish/${{ matrix.rid }}/* -DestinationPath openipc-viewer-${{ matrix.rid }}.zip | |
| - name: Package (tar.gz) | |
| if: matrix.archive == 'tar.gz' | |
| run: | | |
| cd publish/${{ matrix.rid }} | |
| tar -czf ../../openipc-viewer-${{ matrix.rid }}.tar.gz . | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openipc-viewer-${{ matrix.rid }} | |
| path: openipc-viewer-${{ matrix.rid }}.* | |
| if-no-files-found: error | |
| android: | |
| runs-on: ubuntu-latest | |
| name: build (android) | |
| env: | |
| FFMPEG_VERSION: n7.1 | |
| NDK_VERSION: r27c | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: '17' | |
| - name: Set up .NET 10 | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '10.0.x' | |
| - name: Install android workload | |
| run: dotnet workload install android | |
| # FFmpeg .so build is the long pole (~15 min per ABI) — cache the output | |
| # dirs for both ABIs in one entry. Key on FFmpeg version + NDK version | |
| # + the build script hash so any of those changing invalidates the cache. | |
| - name: Cache FFmpeg android natives (arm64 + x64) | |
| id: ffmpeg-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| runtimes/android-arm64/native | |
| runtimes/android-x64/native | |
| key: ffmpeg-android-${{ env.FFMPEG_VERSION }}-ndk${{ env.NDK_VERSION }}-${{ hashFiles('tools/build-ffmpeg-android.sh') }} | |
| - name: Set up Android NDK | |
| if: steps.ffmpeg-cache.outputs.cache-hit != 'true' | |
| uses: nttld/setup-ndk@v1 | |
| id: setup-ndk | |
| with: | |
| ndk-version: ${{ env.NDK_VERSION }} | |
| add-to-path: false | |
| - name: Install FFmpeg build deps | |
| if: steps.ffmpeg-cache.outputs.cache-hit != 'true' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y yasm nasm pkg-config | |
| - name: Cross-compile FFmpeg for android-arm64 + android-x64 | |
| if: steps.ffmpeg-cache.outputs.cache-hit != 'true' | |
| env: | |
| ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} | |
| run: bash tools/build-ffmpeg-android.sh | |
| - name: Restore | |
| run: dotnet restore src/OpenIPC.Viewer.Android/OpenIPC.Viewer.Android.csproj | |
| - name: Build (Release, warnings as errors) | |
| run: dotnet build src/OpenIPC.Viewer.Android/OpenIPC.Viewer.Android.csproj -c Release --no-restore -p:TreatWarningsAsErrors=true | |
| - name: Publish APK (android-arm64) | |
| run: dotnet publish src/OpenIPC.Viewer.Android/OpenIPC.Viewer.Android.csproj -c Release -f net10.0-android -r android-arm64 -o publish/android-arm64 | |
| - name: Publish APK (android-x64) | |
| run: dotnet publish src/OpenIPC.Viewer.Android/OpenIPC.Viewer.Android.csproj -c Release -f net10.0-android -r android-x64 -o publish/android-x64 | |
| - name: Upload artifact (arm64) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openipc-viewer-android-arm64 | |
| path: publish/android-arm64/*-Signed.apk | |
| if-no-files-found: error | |
| - name: Upload artifact (x64) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openipc-viewer-android-x64 | |
| path: publish/android-x64/*-Signed.apk | |
| if-no-files-found: error | |
| ios: | |
| runs-on: macos-14 | |
| name: build (ios) | |
| # Temporarily disabled: the .NET 10 iOS workload pins to an Xcode version | |
| # the GitHub macOS runners don't ship yet (workload 26.5 needs Xcode 26.5), | |
| # so iOS can't build at all right now. Skip the job entirely and drop it | |
| # from the release gate so tagged releases still go out. Re-enable (set | |
| # `if:` back to a real condition) once a matching runner image is available. | |
| # See aka.ms/xcode-requirement. | |
| if: false | |
| continue-on-error: true | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up .NET 10 | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '10.0.x' | |
| - name: Install ios workload | |
| run: dotnet workload install ios | |
| # iOS Release builds for the device RID (ios-arm64), so restore must be | |
| # RID-specific or the assets file won't have a net10.0-ios/ios-arm64 | |
| # target and the --no-restore build fails with NETSDK1047. | |
| - name: Restore | |
| run: dotnet restore src/OpenIPC.Viewer.iOS/OpenIPC.Viewer.iOS.csproj -r ios-arm64 | |
| - name: Build (Release, warnings as errors) | |
| run: dotnet build src/OpenIPC.Viewer.iOS/OpenIPC.Viewer.iOS.csproj -c Release -r ios-arm64 --no-restore -p:TreatWarningsAsErrors=true | |
| # Unsigned IPA — TestFlight signing is post-MVP (Phase 11). The artifact | |
| # is a Release-published app bundle suitable for ad-hoc install via Xcode | |
| # or for someone with credentials to sign + upload later. | |
| - name: Publish (ios-arm64, unsigned) | |
| run: dotnet publish src/OpenIPC.Viewer.iOS/OpenIPC.Viewer.iOS.csproj -c Release -f net10.0-ios -r ios-arm64 -p:CodesignKey= -p:ArchiveOnBuild=true -o publish/ios-arm64 || true | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: openipc-viewer-ios-arm64 | |
| path: | | |
| publish/ios-arm64/**/*.ipa | |
| publish/ios-arm64/**/*.app | |
| if-no-files-found: warn | |
| release: | |
| needs: [build, android] | |
| # iOS is disabled for now (see the ios job above), so the release only | |
| # depends on the desktop matrix + android. Re-add `ios` here once that job | |
| # is re-enabled. | |
| if: always() && startsWith(github.ref, 'refs/tags/v') && needs.build.result == 'success' && needs.android.result == 'success' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| merge-multiple: true | |
| - uses: softprops/action-gh-release@v2 | |
| with: | |
| files: artifacts/**/* | |
| generate_release_notes: true | |
| prerelease: ${{ contains(github.ref_name, '-beta') || contains(github.ref_name, '-rc') || contains(github.ref_name, '-alpha') }} |