Skip to content

Merge pull request #17 from OpenIPC/fix/camera-test-status-and-reacha… #44

Merge pull request #17 from OpenIPC/fix/camera-test-status-and-reacha…

Merge pull request #17 from OpenIPC/fix/camera-test-status-and-reacha… #44

Workflow file for this run

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') }}