name: Build on: # Run on pushes to master and pushed tags, and on pull requests against master, but ignore the docs folder push: branches: [ master ] tags: - 'v*' paths: - '**' - '!docs/**' - '.github/**' pull_request: branches: [ master ] paths: - '**' - '!docs/**' - '.github/**' merge_group: jobs: build-client: name: "PhotonClient Build" defaults: run: working-directory: photon-client runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 18 - name: Install Dependencies run: npm ci - name: Build Production Client run: npm run build - uses: actions/upload-artifact@v4 with: name: built-client path: photon-client/dist/ build-examples: strategy: fail-fast: false matrix: include: - os: windows-2022 architecture: x64 - os: macos-14 architecture: aarch64 - os: ubuntu-22.04 name: "Photonlib - Build Examples - ${{ matrix.os }}" runs-on: ${{ matrix.os }} steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Fetch tags run: git fetch --tags --force - name: Install Java 17 uses: actions/setup-java@v4 with: java-version: 17 distribution: temurin - name: Install RoboRIO Toolchain run: ./gradlew installRoboRioToolchain # Need to publish to maven local first, so that C++ sim can pick it up - name: Publish photonlib to maven local run: ./gradlew photon-targeting:publishtomavenlocal photon-lib:publishtomavenlocal -x check - name: Build Java examples working-directory: photonlib-java-examples run: ./gradlew build - name: Build C++ examples working-directory: photonlib-cpp-examples run: ./gradlew build build-gradle: name: "Gradle Build" runs-on: ubuntu-22.04 steps: # Checkout code. - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Fetch tags run: git fetch --tags --force - name: Install Java 17 uses: actions/setup-java@v4 with: java-version: 17 distribution: temurin - name: Install mrcal deps run: sudo apt-get update && sudo apt-get install -y libcholmod3 liblapack3 libsuitesparseconfig5 - name: Gradle Build run: ./gradlew photon-targeting:build photon-core:build photon-server:build -x check - name: Gradle Tests run: ./gradlew testHeadless -i --stacktrace - name: Gradle Coverage run: ./gradlew jacocoTestReport - name: Publish Coverage Report uses: codecov/codecov-action@v4 with: file: ./photon-server/build/reports/jacoco/test/jacocoTestReport.xml - name: Publish Core Coverage Report uses: codecov/codecov-action@v4 with: file: ./photon-core/build/reports/jacoco/test/jacocoTestReport.xml build-offline-docs: name: "Build Offline Docs" runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install graphviz run: | sudo apt-get update sudo apt-get -y install graphviz - name: Install dependencies working-directory: docs run: | python -m pip install --upgrade pip pip install sphinx sphinx_rtd_theme sphinx-tabs sphinxext-opengraph doc8 pip install -r requirements.txt - name: Build the docs working-directory: docs run: | make html - uses: actions/upload-artifact@v4 with: name: built-docs path: docs/build/html build-photonlib-vendorjson: name: "Build Vendor JSON" runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Java 17 uses: actions/setup-java@v4 with: java-version: 17 distribution: temurin # grab all tags - run: git fetch --tags --force # Generate the JSON and give it the ""standard""" name maven gives it - run: | ./gradlew photon-lib:generateVendorJson export VERSION=$(git describe --tags --match=v*) mv photon-lib/build/generated/vendordeps/photonlib.json photon-lib/build/generated/vendordeps/photonlib-$(git describe --tags --match=v*).json # Upload it here so it shows up in releases - uses: actions/upload-artifact@v4 with: name: photonlib-vendor-json path: photon-lib/build/generated/vendordeps/photonlib-*.json build-photonlib-host: env: MACOSX_DEPLOYMENT_TARGET: 13 strategy: fail-fast: false matrix: include: - os: windows-2022 artifact-name: Win64 architecture: x64 - os: macos-14 artifact-name: macOS architecture: aarch64 - os: ubuntu-22.04 artifact-name: Linux name: "Photonlib - Build Host - ${{ matrix.artifact-name }}" runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Java 17 uses: actions/setup-java@v4 with: java-version: 17 distribution: temurin architecture: ${{ matrix.architecture }} - run: git fetch --tags --force - run: ./gradlew photon-targeting:build photon-lib:build -i name: Build with Gradle - run: ./gradlew photon-lib:publish photon-targeting:publish name: Publish env: ARTIFACTORY_API_KEY: ${{ secrets.ARTIFACTORY_API_KEY }} if: github.event_name == 'push' && github.repository_owner == 'photonvision' # Copy artifacts to build/outputs/maven - run: ./gradlew photon-lib:publish photon-targeting:publish -PcopyOfflineArtifacts - uses: actions/upload-artifact@v4 with: name: maven-${{ matrix.artifact-name }} path: build/outputs build-photonlib-docker: strategy: fail-fast: false matrix: include: - container: wpilib/roborio-cross-ubuntu:2024-22.04 artifact-name: Athena build-options: "-Ponlylinuxathena" - container: wpilib/raspbian-cross-ubuntu:bullseye-22.04 artifact-name: Raspbian build-options: "-Ponlylinuxarm32" - container: wpilib/aarch64-cross-ubuntu:bullseye-22.04 artifact-name: Aarch64 build-options: "-Ponlylinuxarm64" runs-on: ubuntu-22.04 container: ${{ matrix.container }} name: "Photonlib - Build Docker - ${{ matrix.artifact-name }}" steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Config Git run: | git config --global --add safe.directory /__w/photonvision/photonvision - name: Build PhotonLib # We don't need to run tests, since we specify only non-native platforms run: ./gradlew photon-targeting:build photon-lib:build ${{ matrix.build-options }} -i -x test - name: Publish run: ./gradlew photon-lib:publish photon-targeting:publish ${{ matrix.build-options }} env: ARTIFACTORY_API_KEY: ${{ secrets.ARTIFACTORY_API_KEY }} if: github.event_name == 'push' && github.repository_owner == 'photonvision' # Copy artifacts to build/outputs/maven - run: ./gradlew photon-lib:publish photon-targeting:publish -PcopyOfflineArtifacts ${{ matrix.build-options }} - uses: actions/upload-artifact@v4 with: name: maven-${{ matrix.artifact-name }} path: build/outputs combine: name: Combine needs: [build-photonlib-docker, build-photonlib-host] runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - run: git fetch --tags --force # download all maven-* artifacts to outputs/ - uses: actions/download-artifact@v4 with: merge-multiple: true path: output pattern: maven-* - run: find . - run: zip -r photonlib-$(git describe --tags --match=v*).zip . name: ZIP stuff up working-directory: output - run: ls output - uses: actions/upload-artifact@v4 with: name: photonlib-offline path: output/*.zip build-package: needs: [build-client, build-gradle, build-offline-docs] strategy: fail-fast: false matrix: include: - os: windows-latest artifact-name: Win64 architecture: x64 arch-override: winx64 - os: macos-latest artifact-name: macOS architecture: x64 arch-override: macx64 - os: macos-latest artifact-name: macOSArm architecture: x64 arch-override: macarm64 - os: ubuntu-22.04 artifact-name: Linux architecture: x64 arch-override: linuxx64 - os: ubuntu-22.04 artifact-name: LinuxArm64 architecture: x64 arch-override: linuxarm64 runs-on: ${{ matrix.os }} name: "Build fat JAR - ${{ matrix.artifact-name }}" steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Java 17 uses: actions/setup-java@v4 with: java-version: 17 distribution: temurin architecture: ${{ matrix.architecture }} - name: Install Arm64 Toolchain run: ./gradlew installArm64Toolchain if: ${{ (matrix.artifact-name) == 'LinuxArm64' }} - run: | rm -rf photon-server/src/main/resources/web/* mkdir -p photon-server/src/main/resources/web/docs if: ${{ (matrix.os) != 'windows-latest' }} - run: | del photon-server\src\main\resources\web\*.* mkdir photon-server\src\main\resources\web\docs if: ${{ (matrix.os) == 'windows-latest' }} - uses: actions/download-artifact@v4 with: name: built-client path: photon-server/src/main/resources/web/ - uses: actions/download-artifact@v4 with: name: built-docs path: photon-server/src/main/resources/web/docs - run: ./gradlew photon-targeting:jar photon-server:shadowJar -PArchOverride=${{ matrix.arch-override }} if: ${{ (matrix.arch-override != 'none') }} - run: ./gradlew photon-server:shadowJar if: ${{ (matrix.arch-override == 'none') }} - uses: actions/upload-artifact@v4 with: name: jar-${{ matrix.artifact-name }} path: photon-server/build/libs - uses: actions/upload-artifact@v4 with: name: photon-targeting_jar-${{ matrix.artifact-name }} path: photon-targeting/build/libs run-smoketest-native: needs: [build-package] strategy: fail-fast: false matrix: include: - os: ubuntu-22.04 artifact-name: jar-Linux extraOpts: -Djdk.lang.Process.launchMechanism=vfork - os: windows-latest artifact-name: jar-Win64 extraOpts: "" - os: macos-latest artifact-name: jar-macOS architecture: x64 runs-on: ${{ matrix.os }} steps: - name: Install Java 17 uses: actions/setup-java@v4 with: java-version: 17 distribution: temurin - uses: actions/download-artifact@v4 with: name: ${{ matrix.artifact-name }} # On linux, install mrcal packages - run: | sudo apt-get update sudo apt-get install --yes libcholmod3 liblapack3 libsuitesparseconfig5 if: ${{ (matrix.os) == 'ubuntu-22.04' }} # and actually run the jar - run: java -jar ${{ matrix.extraOpts }} *.jar --smoketest if: ${{ (matrix.os) != 'windows-latest' }} - run: ls *.jar | %{ Write-Host "Running $($_.Name)"; Start-Process "java" -ArgumentList "-jar `"$($_.FullName)`" --smoketest" -NoNewWindow -Wait; break } if: ${{ (matrix.os) == 'windows-latest' }} run-smoketest-chroot: needs: [build-package] strategy: fail-fast: false matrix: include: - os: ubuntu-22.04 artifact-name: LinuxArm64 image_suffix: RaspberryPi image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2025.0.0-beta-4/photonvision_raspi.img.xz cpu: cortex-a7 image_additional_mb: 0 extraOpts: -Djdk.lang.Process.launchMechanism=vfork runs-on: ${{ matrix.os }} name: smoketest-${{ matrix.image_suffix }} steps: - uses: actions/download-artifact@v4 with: name: jar-${{ matrix.artifact-name }} - uses: pguyot/arm-runner-action@v2 name: Run photon smoketest id: generate_image with: base_image: ${{ matrix.image_url }} image_additional_mb: ${{ matrix.image_additional_mb }} optimize_image: yes cpu: ${{ matrix.cpu }} # We do _not_ wanna copy photon into the image. Bind mount instead bind_mount_repository: true # our image better have java installed already commands: | java -jar ${{ matrix.extraOpts }} *.jar --smoketest build-image: needs: [build-package] if: ${{ github.event_name != 'pull_request' }} strategy: fail-fast: false matrix: include: - os: ubuntu-22.04 artifact-name: LinuxArm64 image_suffix: RaspberryPi image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2025.0.0-beta-6/photonvision_raspi.img.xz cpu: cortex-a7 image_additional_mb: 0 - os: ubuntu-22.04 artifact-name: LinuxArm64 image_suffix: limelight2 image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2025.0.0-beta-6/photonvision_limelight.img.xz cpu: cortex-a7 image_additional_mb: 0 - os: ubuntu-22.04 artifact-name: LinuxArm64 image_suffix: limelight3 image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2025.0.0-beta-6/photonvision_limelight3.img.xz cpu: cortex-a7 image_additional_mb: 0 - os: ubuntu-22.04 artifact-name: LinuxArm64 image_suffix: orangepi5 image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2025.0.0-beta-6/photonvision_opi5.img.xz cpu: cortex-a8 image_additional_mb: 1024 - os: ubuntu-22.04 artifact-name: LinuxArm64 image_suffix: orangepi5b image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2025.0.0-beta-6/photonvision_opi5b.img.xz cpu: cortex-a8 image_additional_mb: 1024 - os: ubuntu-22.04 artifact-name: LinuxArm64 image_suffix: orangepi5plus image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2025.0.0-beta-6/photonvision_opi5plus.img.xz cpu: cortex-a8 image_additional_mb: 1024 - os: ubuntu-22.04 artifact-name: LinuxArm64 image_suffix: orangepi5pro image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2025.0.0-beta-6/photonvision_opi5pro.img.xz cpu: cortex-a8 image_additional_mb: 1024 - os: ubuntu-22.04 artifact-name: LinuxArm64 image_suffix: orangepi5max image_url: https://github.com/PhotonVision/photon-image-modifier/releases/download/v2025.0.0-beta-6/photonvision_opi5max.img.xz cpu: cortex-a8 image_additional_mb: 1024 runs-on: ${{ matrix.os }} name: "Build image - ${{ matrix.image_url }}" steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/download-artifact@v4 with: name: jar-${{ matrix.artifact-name }} - uses: pguyot/arm-runner-action@HEAD name: Generate image id: generate_image with: base_image: ${{ matrix.image_url }} image_additional_mb: ${{ matrix.image_additional_mb }} optimize_image: yes cpu: ${{ matrix.cpu }} # We do _not_ wanna copy photon into the image. Bind mount instead bind_mount_repository: true commands: | chmod +x scripts/armrunner.sh ./scripts/armrunner.sh - name: Compress image run: | new_jar=$(realpath $(find . -name photonvision\*-linuxarm64.jar)) new_image_name=$(basename "${new_jar/.jar/_${{ matrix.image_suffix }}.img}") mv ${{ steps.generate_image.outputs.image }} $new_image_name sudo xz -T 0 -v $new_image_name - uses: actions/upload-artifact@v4 name: Upload image with: name: image-${{ matrix.image_suffix }} path: photonvision*.xz release: needs: [build-package, build-image, combine] runs-on: ubuntu-22.04 steps: # Download all fat JARs - uses: actions/download-artifact@v4 with: merge-multiple: true pattern: jar-* # Download offline photonlib - uses: actions/download-artifact@v4 with: merge-multiple: true pattern: photonlib-offline # Download vendor json - uses: actions/download-artifact@v4 with: merge-multiple: true pattern: photonlib-vendor-json # Download all images - uses: actions/download-artifact@v4 with: merge-multiple: true pattern: image-* - run: find # Push to dev release - uses: pyTooling/Actions/releaser@r0 with: token: ${{ secrets.GITHUB_TOKEN }} tag: 'Dev' rm: true files: | **/*.xz **/*.jar **/photonlib*.json **/photonlib*.zip if: github.event_name == 'push' # Upload all jars and xz archives # Split into two uploads to work around max size limits in action-gh-releases # https://github.com/softprops/action-gh-release/issues/353 - uses: softprops/action-gh-release@v2.0.9 with: files: | **/*orangepi5*.xz if: startsWith(github.ref, 'refs/tags/v') env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - uses: softprops/action-gh-release@v2.0.9 with: files: | **/!(*orangepi5*).xz **/*.jar **/photonlib*.json **/photonlib*.zip if: startsWith(github.ref, 'refs/tags/v') env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} dispatch: name: dispatch needs: [build-photonlib-vendorjson, release] runs-on: ubuntu-22.04 steps: - uses: peter-evans/repository-dispatch@v3 if: | github.repository == 'PhotonVision/photonvision' && startsWith(github.ref, 'refs/tags/v') with: token: ${{ secrets.VENDOR_JSON_REPO_PUSH_TOKEN }} repository: PhotonVision/vendor-json-repo event-type: tag client-payload: '{"run_id": "${{ github.run_id }}", "package_version": "${{ github.ref_name }}"}'