name: Build

on:
  push:
    branches: [ master ]
    paths: [ src/**, test/**, cmake/**, .github/workflows/ci.yml, CMakeLists.txt ]
  pull_request:
    branches: [ master ]
    paths: [ src/**, test/**, cmake/**, .github/workflows/ci.yml, CMakeLists.txt ]

concurrency:
  group: "${{ github.workflow }}-${{ github.ref }}"
  cancel-in-progress: true

env:
  BUILD_TYPE: RelWithDebInfo
  CTEST_OUTPUT_ON_FAILURE: 1
  VCPKG_BINARY_SOURCES: 'clear;nuget,GitHub,readwrite'

jobs:
  build-windows:
    name: "windows-${{matrix.platform}}"
    runs-on: windows-latest
    strategy:
      fail-fast: false
      matrix:
        platform: [ x64, x86 ]

    steps:
    - name: Checkout source code
      uses: actions/checkout@v4
      with:
        submodules: true

    - name: Update vcpkg
      shell: pwsh
      run: |
        $vcpkgCommit = '19847ac3d8cad7599e96bd531f9bc1f0ebae6131'
        pushd "$env:VCPKG_INSTALLATION_ROOT"
        git fetch origin $vcpkgCommit
        git reset --hard $vcpkgCommit
        ./bootstrap-vcpkg.bat
        ./vcpkg.exe integrate install
        popd

    - name: Setup NuGet Credentials
      shell: pwsh
      run: |
        $nugetCmd = vcpkg fetch nuget | Select-Object -Last 1
        $nugetSource = 'https://nuget.pkg.github.com/CelestiaProject/index.json'
        & "$nugetCmd" sources add `
          -Source "$nugetSource" `
          -StorePasswordInClearText `
          -Name "GitHub" `
          -Username 'CelestiaProject' `
          -Password '${{secrets.GITHUB_TOKEN}}'

    - name: Install dependencies
      shell: pwsh
      run: |
        $packages = @(
          'boost-container',
          'boost-smart-ptr',
          'cspice',
          'eigen3',
          'ffmpeg[core,avcodec,avformat,gpl,swscale,x264]',
          'fmt',
          'freetype',
          'gettext[tools]',
          'gperf',
          'libepoxy',
          'libjpeg-turbo',
          'libpng',
          'luajit',
          'qtbase[core,opengl,widgets,freetype,harfbuzz,jpeg,png]'
        )

        # We treat x86 builds as native, other builds keep host as x64-windows.
        # Currently this is equivalent to the platform triplet, but this would
        # differ if we enable arm64-windows builds in future

        if ( '${{matrix.platform}}' -eq 'x86' ) {
          $hostTriplet = 'x86-windows-release'
        } else {
          $hostTriplet = 'x64-windows-release'
        }

        pushd "$env:VCPKG_INSTALLATION_ROOT"
        ./vcpkg.exe --overlay-triplets=${{github.workspace}}/windows/vcpkg-triplets `
                    --triplet=${{matrix.platform}}-windows-release `
                    --host-triplet=$hostTriplet `
                    install --recurse @packages
        popd

    - name: Configure CMake
      shell: pwsh
      run: |
        if ( '${{matrix.platform}}' -eq 'x86' ) {
            $GeneratorPlatform = 'Win32'
        } else {
            $GeneratorPlatform = '${{matrix.platform}}'
        }

        cmake -B '${{github.workspace}}/build' `
            -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" `
            -DVCPKG_OVERLAY_TRIPLETS="${{github.workspace}}/windows/vcpkg-triplets" `
            -DVCPKG_TARGET_TRIPLET=${{matrix.platform}}-windows-release `
            -DCMAKE_GENERATOR_PLATFORM="$GeneratorPlatform" `
            -DCMAKE_INSTALL_PREFIX="${{github.workspace}}/install" `
            -DENABLE_SPICE=ON     `
            -DENABLE_TOOLS=ON     `
            -DENABLE_TESTS=ON     `
            -DENABLE_SDL=OFF      `
            -DENABLE_QT5=OFF      `
            -DENABLE_QT6=ON       `
            -DENABLE_FFMPEG=ON    `
            -DENABLE_MINIAUDIO=ON `
            -DENABLE_LTO=ON       `
            -DUSE_ICU=ON          `
            -DUSE_WIN_ICU=ON

    - name: Build
      shell: pwsh
      run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} '--' /maxcpucount:2 /nologo

    - name: Test
      shell: pwsh
      working-directory: ${{github.workspace}}/build
      run: ctest -C ${{env.BUILD_TYPE}}

    - name: Install Windows
      shell: pwsh
      run: |
        cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --component core
        cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --component wingui
        Rename-Item -Path "install" -NewName "install-wingui"

    - name: Upload Windows GUI
      uses: actions/upload-artifact@v4
      if: success()
      with:
        name: celestia-windows-${{matrix.platform}}-wingui
        if-no-files-found: error
        path: |
          ${{github.workspace}}/install-wingui/

    - name: Install Qt6
      shell: pwsh
      run: |
        cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --component core
        cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --component qt6gui
        Rename-Item -Path "install" -NewName "install-qt6gui"

    - name: Upload Qt6 GUI
      uses: actions/upload-artifact@v4
      if: success()
      with:
        name: celestia-windows-${{matrix.platform}}-qt6gui
        if-no-files-found: error
        path: |
          ${{github.workspace}}/install-qt6gui/

    - name: Install tools
      shell: pwsh
      run: |
        cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --component tools
        Rename-Item -Path "install" -NewName "install-tools"

    - name: Upload tools
      uses: actions/upload-artifact@v4
      if: success()
      with:
        name: celestia-windows-${{matrix.platform}}-tools
        if-no-files-found: error
        path: |
          ${{github.workspace}}/install-tools/

  build-posix:
    name: "${{matrix.config.os}}"
    strategy:
      fail-fast: false
      matrix:
        config:
        - os: ubuntu-20.04
          avif: OFF     # Not supported on Ubuntu20.04
          gles: ON
          gtk3: ON
          minaudio: ON
          wayland: ON
          icu: ON
          qt6: OFF
        - os: ubuntu-24.04
          avif: ON
          gles: ON
          gtk3: ON
          minaudio: ON
          wayland: ON
          icu: ON
          qt6: ON
          analysis_artifacts: 1

    runs-on: ${{matrix.config.os}}
    steps:
    - name: 'Install dependencies'
      run: |
        sudo apt-get update
        sudo apt-get install -y libboost-dev \
                                libeigen3-dev \
                                libepoxy-dev \
                                libavcodec-dev \
                                libavformat-dev \
                                libavutil-dev \
                                libswscale-dev \
                                libjpeg-dev \
                                libpng-dev \
                                libglu1-mesa-dev \
                                libgtk-3-dev \
                                libfreetype6-dev \
                                libsdl2-dev \
                                libluajit-5.1-dev \
                                libfmt-dev \
                                libicu-dev \
                                libwayland-dev \
                                wayland-protocols \
                                gettext \
                                gperf \
                                ninja-build \
                                qtbase5-dev qtbase5-dev-tools qtbase5-private-dev
        if [ "${{matrix.config.qt6}}" = "ON" ]; then
            sudo apt-get install -y qt6-base-dev qt6-base-dev-tools qt6-base-private-dev
        fi
        if [ "${{matrix.config.avif}}" = "ON" ]; then
            sudo apt-get install -y libavif-dev
        fi

    - name: 'Checkout source code'
      uses: actions/checkout@v4
      with:
        submodules: true

    - name: 'Configure CMake'
      run: |
        cmake -B ${{github.workspace}}/build            \
              -G Ninja                                  \
              -DENABLE_GLES=${{matrix.config.gles}}     \
              -DENABLE_SPICE=ON                         \
              -DENABLE_TOOLS=OFF                        \
              -DENABLE_TESTS=ON                         \
              -DENABLE_SDL=ON                           \
              -DENABLE_GTK=ON                           \
              -DUSE_GTK3=${{matrix.config.gtk3}}        \
              -DENABLE_QT5=ON                           \
              -DENABLE_QT6=${{matrix.config.qt6}}       \
              -DUSE_WAYLAND=${{matrix.config.wayland}}  \
              -DENABLE_FFMPEG=ON                        \
              -DENABLE_LIBAVIF=${{matrix.config.avif}}  \
              -DENABLE_MINIAUDIO=${{matrix.config.minaudio}} \
              -DUSE_ICU=${{matrix.config.icu}}

    - name: Build
      working-directory: ${{github.workspace}}/build
      run: ninja

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ctest

    - name: 'Package autogenerated headers'
      if: ${{ success() && matrix.config.analysis_artifacts }}
      run: |
        shopt -s globstar
        zip celestia-autogenerated-headers  \
            build/src/**/*_autogen/**/*.h   \
            build/src/**/*_autogen/**/*.inc

    - name: 'Write PR details'
      if: ${{ success() && github.event_name == 'pull_request' && matrix.config.analysis_artifacts }}
      run: |
        echo "PR_KEY=${{ github.event.number }}" > pr-details.txt
        echo "PR_BRANCH=${{ github.event.pull_request.head.ref }}" >> pr-details.txt
        echo "PR_BASE=${{ github.event.pull_request.base.ref }}" >> pr-details.txt

    - name: 'Upload autogenerated headers'
      uses: actions/upload-artifact@v4
      if: ${{ success() && matrix.config.analysis_artifacts }}
      with:
        name: celestia-autogenerated-headers
        path: celestia-autogenerated-headers.zip

    - name: 'Upload PR details'
      uses: actions/upload-artifact@v4
      if: ${{ success() && github.event_name == 'pull_request' && matrix.config.analysis_artifacts }}
      with:
        name: pr-details
        path: pr-details.txt

  build-macos:
    # Because of include path conflicts when both Qt5 and Qt6 are installed,
    # we run these as separate builds
    name: "macos-latest"
    runs-on: macos-latest
    steps:
    - name: 'Install dependencies'
      run: |
        brew install ninja \
                     eigen \
                     ffmpeg \
                     boost \
                     cspice \
                     fmt \
                     jpeg-turbo \
                     gettext \
                     gperf \
                     libpng \
                     lua \
                     freetype \
                     libepoxy \
                     libavif \
                     qt@6 \
                     sdl2

    - name: 'Checkout source code'
      uses: actions/checkout@v4
      with:
        submodules: true

    - name: 'Configure CMake'
      run: |
        cmake -B ${{github.workspace}}/build \
              -G Ninja                       \
              -DENABLE_GLES=OFF              \
              -DENABLE_SPICE=ON              \
              -DENABLE_TOOLS=OFF             \
              -DENABLE_TESTS=ON              \
              -DENABLE_SDL=ON                \
              -DENABLE_GTK=OFF               \
              -DUSE_GTK3=OFF                 \
              -DENABLE_QT5=OFF               \
              -DENABLE_QT6=ON                \
              -DUSE_WAYLAND=OFF              \
              -DENABLE_FFMPEG=ON             \
              -DENABLE_LIBAVIF=ON            \
              -DENABLE_MINIAUDIO=ON          \
              -DUSE_ICU=OFF

    - name: Build
      working-directory: ${{github.workspace}}/build
      run: ninja

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ctest

  gnulinux-arm64:
    runs-on: self-hosted
    steps:
    - name: 'Install dependencies'
      run: |
        #sudo dnf config-manager --set-enabled ol8_codeready_builder
        sudo yum install -y eigen3-devel \
                            libepoxy-devel \
                            libpng-devel \
                            libjpeg-turbo-devel \
                            boost-devel \
                            freetype-devel \
                            SDL2-devel \
                            lua-devel \
                            gtk3-devel \
                            qt5-qtbase-devel \
                            qt5-qttools \
                            gettext-devel \
                            libicu-devel \
                            cmake \
                            gperf \
                            ninja-build \
                            gcc-toolset-11-gcc-c++

    - name: 'Checkout source code'
      uses: actions/checkout@v4
      with:
        submodules: true

    - name: 'Configure CMake'
      run: |
        cmake -B ${{github.workspace}}/build  \
              -G Ninja                        \
              -DENABLE_GLES=ON                \
              -DENABLE_SPICE=ON               \
              -DENABLE_TOOLS=ON               \
              -DENABLE_TESTS=ON               \
              -DENABLE_SDL=ON                 \
              -DENABLE_GTK=ON                 \
              -DUSE_GTK3=ON                   \
              -DENABLE_QT5=ON                 \
              -DENABLE_QT6=OFF                \
              -DENABLE_FFMPEG=OFF             \
              -DENABLE_MINIAUDIO=ON           \
              -DUSE_ICU=ON
      env:
        CC: /opt/rh/gcc-toolset-11/root/usr/bin/gcc
        CXX: /opt/rh/gcc-toolset-11/root/usr/bin/g++

    - name: Build
      working-directory: ${{github.workspace}}/build
      run: ninja

    - name: Test
      working-directory: ${{github.workspace}}/build
      run: ctest
