name: Build & Package

on:
  push:
    branches: [ main, 'develop' ]
    paths-ignore:
      - 'resource/lfs/locale/**'
      - '**.md'
  pull_request:
    branches: [ main, 'develop' ]
    paths-ignore:
      - 'resource/lfs/locale/**'
      - '**.md'

env:
  # Customize the CMake build type here (Release, Debug, etc.)
  BUILD_TYPE: Release

jobs:
  build:
    strategy:
      matrix:
        os: [ 'ubuntu-20.04', 'macos-13', 'macos-12', "macos-14", 'windows-2019' ]
    runs-on: ${{ matrix.os }}
    continue-on-error: true
    steps:
      - name: Set git to use LF(Windows) or CRLF(MacOS) line endings
        run: |
          git config --global core.autocrlf false
          git config --global core.eol lf
        if: matrix.os == 'windows-2019' || matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'

      - uses: actions/checkout@v4
        with:
          lfs: 'false'
          submodules: recursive

      - name: Get Short SHA of Commit
        id: vars
        run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV

      - name: Install Dependence (Linux)
        run: |
          sudo apt-get update
          sudo apt-get -y install build-essential binutils git autoconf automake gettext texinfo
          sudo apt-get -y install gcc g++ ninja-build
          sudo apt-get -y install libarchive-dev libssl-dev
          sudo apt-get -y install gpgsm libxcb-xinerama0 libxcb-icccm4-dev libcups2-dev libdrm-dev libegl1-mesa-dev
          sudo apt-get -y install libgcrypt20-dev libnss3-dev libpci-dev libpulse-dev libudev-dev libxtst-dev gyp
          sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libxcb-image0
          sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libxcb-* libxkbcommon-x11-0
        if: matrix.os == 'ubuntu-20.04'

      - name: Codesign Configuration (macOS)
        run: |
          CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
          PP_PATH=$RUNNER_TEMP/${{secrets.GPGFRONTEND_XOCDE_PROVISIONING_PROFILE_UUID}}.provisionprofile
          KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db

          echo -n "${{secrets.MACOS_CERTIFICATE}}" | base64 --decode -o $CERTIFICATE_PATH
          echo -n "${{secrets.GPGFRONTEND_XOCDE_PROVISIONING_PROFILE_DATA}}" | base64 --decode -o $PP_PATH

          security create-keychain -p gpgfrontend build.keychain
          security default-keychain -s build.keychain
          security unlock-keychain -p gpgfrontend build.keychain
          security import $CERTIFICATE_PATH -k build.keychain -P ${{secrets.MAOS_CERTIFICATE_PWD}} -T /usr/bin/codesign
          security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k gpgfrontend build.keychain
          security set-keychain-settings -lut 3600

          mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
          cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
        if:  matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'

      - name: Install Qt6
        uses: jurplel/install-qt-action@v3
        with:
          version: '6.7.2'
          cache: 'true'
        if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'

      - name: Install Dependence (macOS)
        run: |
          brew install cmake autoconf automake texinfo gettext openssl@3
          brew install ninja libarchive gpgme googletest
          brew link openssl@3 --force
        if:  matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'

      - name: Set up MinGW (Windows)
        uses: msys2/setup-msys2@v2
        with:
          install: git msys2-devel base-devel binutils mingw-w64-x86_64-toolchain
          release: false
        if: matrix.os == 'windows-2019'

      - name: Set up Dependence (Windows)
        shell: msys2 {0}
        run: |
          pacman --noconfirm -S --needed mingw-w64-x86_64-gcc mingw-w64-x86_64-make mingw-w64-x86_64-cmake autoconf 
          pacman --noconfirm -S --needed make texinfo automake 
          pacman --noconfirm -S --needed mingw-w64-x86_64-qt6 mingw-w64-x86_64-icu libintl msys2-runtime-devel gettext-devel
          pacman --noconfirm -S --needed mingw-w64-x86_64-ninja mingw-w64-x86_64-gnupg mingw-w64-x86_64-libarchive
          pacman --noconfirm -S --needed mingw-w64-x86_64-gtest
        if: matrix.os == 'windows-2019'

      - name: Build gpg-error (Linux)
        run: |
          git clone --depth 1 --branch libgpg-error-1.47 git://git.gnupg.org/libgpg-error.git ${{github.workspace}}/third_party/libgpg-error
          cd  ${{github.workspace}}/third_party/libgpg-error
          ./autogen.sh
          ./configure --enable-maintainer-mode && make -j4
          sudo make install
          cd ${{github.workspace}}
        if: matrix.os == 'ubuntu-20.04'

      - name: Build gpg-error (Windows)
        shell: msys2 {0}
        run: |
          git clone --depth 1 --branch libgpg-error-1.47 git://git.gnupg.org/libgpg-error.git ${{github.workspace}}/third_party/libgpg-error
          cd  ${{github.workspace}}/third_party/libgpg-error
          ./autogen.sh
          ./configure --enable-maintainer-mode && make -j4
          make install
          cd ${{github.workspace}}
        if: matrix.os == 'windows-2019'

      - name: Build assuan (Linux)
        run: |
          git clone --depth 1 --branch libassuan-2.5.6 git://git.gnupg.org/libassuan.git ${{github.workspace}}/third_party/libassuan
          cd ${{github.workspace}}/third_party/libassuan
          ./autogen.sh
          ./configure --enable-maintainer-mode && make -j4
          sudo make install
          cd ${{github.workspace}}
        if: matrix.os == 'ubuntu-20.04'

      - name: Build assuan (Windows)
        shell: msys2 {0}
        run: |
          git clone --depth 1 --branch libassuan-2.5.6 git://git.gnupg.org/libassuan.git ${{github.workspace}}/third_party/libassuan
          cd ${{github.workspace}}/third_party/libassuan
          ./autogen.sh
          ./configure --enable-maintainer-mode && make -j4
          make install
          cd ${{github.workspace}}
        if: matrix.os == 'windows-2019'

      - name: Build GpgME (Linux)
        run: |
          git clone --depth 1 --branch gpgme-1.22.0 git://git.gnupg.org/gpgme.git ${{github.workspace}}/third_party/gpgme
          cd ${{github.workspace}}/third_party/gpgme
          ./autogen.sh
          ./configure --enable-maintainer-mode --enable-languages=cpp && make -j4
          sudo make install
          cd ${{github.workspace}}
        if: matrix.os == 'ubuntu-20.04'

      - name: Build GpgME (Windows)
        shell: msys2 {0}
        run: |
          git clone --depth 1 --branch fix/1.18.0 https://git.bktus.com/GpgFrontend/gpgme.git ${{github.workspace}}/third_party/gpgme
          cd ${{github.workspace}}/third_party/gpgme
          ./autogen.sh
          ./configure --enable-maintainer-mode --enable-languages=cpp --disable-gpg-test && make -j4
          make install
          cd ${{github.workspace}}
        if: matrix.os == 'windows-2019'

      - name: Build mimalloc (Linux)
        run: |
          cd ${{github.workspace}}/third_party/mimalloc
          mkdir build && cd build
          cmake -G Ninja -DMI_SECURE=ON ..
          ninja
          sudo ninja install
        if: matrix.os == 'ubuntu-20.04'

      - name: Build mimalloc (Windows)
        shell: msys2 {0}
        run: |
          cd ${{github.workspace}}/third_party/mimalloc
          mkdir build && cd build
          cmake -G Ninja -DMI_SECURE=ON ..
          ninja
          sudo ninja install
        if: matrix.os == 'windows-2019'

      - name: Build googletest (Linux)
        run: |
          cd ${{github.workspace}}/third_party/googletest
          mkdir build && cd build
          cmake -G Ninja ..
          ninja
          sudo ninja install
        if: matrix.os == 'ubuntu-20.04'

      - name: Build & Install Full SDK 
        run: |
          cmake -B ${{github.workspace}}/build-full-sdk -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_FULL_SDK=ON
          cmake --build ${{github.workspace}}/build-full-sdk --config {{$env.BUILD_TYPE}} -- -v
          sudo cmake --install ${{github.workspace}}/build-full-sdk --config {{$env.BUILD_TYPE}}
        if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'

      - name: Build & Install Full SDK (Windows)
        shell: msys2 {0}
        run: |
          cd $(echo "/${{github.workspace}}"  | sed 's/\\/\//g' | sed 's/://')
          mkdir build-full-sdk && cd build-full-sdk
          cmake -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_FULL_SDK=ON -DCMAKE_INSTALL_PREFIX=$MSYSTEM_PREFIX ..
          cmake --build . --config ${{env.BUILD_TYPE}}  -- -j 4
          cmake --install . --config {{$env.BUILD_TYPE}}
        if: matrix.os == 'windows-2019'

      - name: Build Integrated Modules
        run: |
          cmake -S ${{github.workspace}}/modules -B ${{github.workspace}}/modules/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/modules/build/artifacts
          cmake --build ${{github.workspace}}/modules/build --config {{$env.BUILD_TYPE}} -- -v
          cmake --install ${{github.workspace}}/modules/build --config {{$env.BUILD_TYPE}}
        if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'

      - name: Build Integrated Modules (Windows)
        shell: msys2 {0}
        run: |
          cd $(echo "/${{github.workspace}}"  | sed 's/\\/\//g' | sed 's/://')
          cd modules
          mkdir build && cd build
          cmake -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_STABLE=ON -DCMAKE_INSTALL_PREFIX=./artifacts ..
          cmake --build . --config ${{env.BUILD_TYPE}}  -- -j 4
          cmake --install . --config {{$env.BUILD_TYPE}}
        if: matrix.os == 'windows-2019'

      - name: Build & Export GpgFrontend (macOS)
        # Build your GpgFrontend with the given configuration
        run: |
          cmake -B ${{github.workspace}}/build -G Xcode \
           -DGPGFRONTEND_CONFIGURE_FOR_XCODE_BUILD=On \
           -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
           -DGPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY="${{secrets.GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}}" \
           -DGPGFRONTEND_XCODE_TEAM_ID="${{secrets.GPGFRONTEND_XCODE_TEAM_ID}}" \
           -DGPGFRONTEND_XOCDE_APPID="${{secrets.GPGFRONTEND_XOCDE_APPID}}" \
           -DGPGFRONTEND_XOCDE_PROVISIONING_PROFILE_UUID="${{secrets.GPGFRONTEND_XOCDE_PROVISIONING_PROFILE_UUID}}"
          xcodebuild -list -project ${{github.workspace}}/build/GpgFrontend.xcodeproj
          cd ${{github.workspace}}/build/
          xcodebuild -scheme GpgFrontend -configuration "${{env.BUILD_TYPE}}"\
            -archivePath ${{github.workspace}}/build/GpgFrontend.xcarchive archive
          mkdir ${{github.workspace}}/build/package
          xcodebuild -exportArchive -archivePath ${{github.workspace}}/build/GpgFrontend.xcarchive \
            -exportOptionsPlist ${{github.workspace}}/build/ExportOptions.plist \
            -exportPath ${{github.workspace}}/build/package/
        if:  matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'

      - name: Copy Modules into Bundle & Deploy Qt & Code Sign (macOS)
        run: |
          codesign -s "${{secrets.GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}}" -f --deep --options=runtime --timestamp ${{github.workspace}}/modules/build/artifacts/modules/*
          cmake -E copy_directory ${{github.workspace}}/modules/build/artifacts/modules ${{github.workspace}}/build/package/GpgFrontend.app/Contents/Modules
          macdeployqt ${{github.workspace}}/build/package/GpgFrontend.app -verbose=2 -appstore-compliant -always-overwrite
          codesign -s "${{secrets.GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}}" -f --deep --options=runtime --timestamp ${{github.workspace}}/build/package/GpgFrontend.app
        if:  matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'

      - name: Package & Sign App Bundle (macOS)
        run: |
          security -v unlock-keychain -p gpgfrontend
          ditto -c -k --keepParent ${{github.workspace}}/build/package/GpgFrontend.app ${{github.workspace}}/build/GpgFrontend.app.zip
          hdiutil create ${{github.workspace}}/build/tmp.dmg -ov \
            -volname "GpgFrontend" -fs HFS+ -srcfolder ${{github.workspace}}/build/package/
          mkdir ${{github.workspace}}/build/final-artifact
          hdiutil convert ${{github.workspace}}/build/tmp.dmg -format UDZO -o ${{github.workspace}}/build/final-artifact/GpgFrontend.dmg
          codesign -s "${{secrets.GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}}" ${{github.workspace}}/build/final-artifact/GpgFrontend.dmg
          mv ${{github.workspace}}/build/final-artifact/GpgFrontend.dmg \
            ${{github.workspace}}/build/final-artifact/GpgFrontend-${{env.sha_short}}-x86_64.dmg
          mv ${{github.workspace}}/build/GpgFrontend.app.zip \
            ${{github.workspace}}/build/GpgFrontend-${{env.sha_short}}-x86_64.zip
        if:  matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'

      - name: Notarize Release Build (macOS)
        run: |
          xcrun notarytool submit \
          --apple-id ${{secrets.APPLE_DEVELOPER_ID}} \
          --team-id ${{secrets.APPLE_DEVELOPER_TEAM_ID}} \
          --password ${{secrets.APPLE_DEVELOPER_ID_SECRET}} \
          ${{github.workspace}}/build/GpgFrontend-${{env.sha_short}}-x86_64.zip
          echo "BUILD_TYPE_LOWER=$(echo ${BUILD_TYPE} | tr '[:upper:]' '[:lower:]')" >> ${GITHUB_ENV}
          echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> ${GITHUB_ENV}
        if:  matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'
    
      - name: Build GpgFrontend (Linux)
        # Build your GpgFrontend with the given configuration
        run: |
          cmake -B ${{github.workspace}}/build -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DDGPGFRONTEND_BUILD_TYPE_ONLY_APPLICATION=ON
          cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v
        if: matrix.os == 'ubuntu-20.04'

      - name: Copy Modules & Package App Image (Linux)
        run: |
          cmake -E copy_directory ${{github.workspace}}/modules/build/artifacts/modules ${{github.workspace}}/build/artifacts/AppDir/usr/modules
          mkdir ${{github.workspace}}/build/final-artifact
          cd ${{github.workspace}}/build/final-artifact
          wget -c -nv https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
          chmod u+x linuxdeployqt-continuous-x86_64.AppImage
          export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
          ./linuxdeployqt-continuous-x86_64.AppImage ${{github.workspace}}/build/artifacts/AppDir/usr/share/applications/*.desktop -no-translations -extra-plugins=iconengines -appimage -executable-dir=${{github.workspace}}/build/artifacts/AppDir/usr/modules/
          echo "BUILD_TYPE_LOWER=${BUILD_TYPE,,}" >> ${GITHUB_ENV}
          echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> ${GITHUB_ENV}
        if: matrix.os == 'ubuntu-20.04'

      - name: Configure CMake & Build Application (Windows)
        shell: msys2 {0}
        run: |
          cd $(echo "/${{github.workspace}}"  | sed 's/\\/\//g' | sed 's/://')
          mkdir build && cd build
          cmake -G Ninja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DGPGFRONTEND_BUILD_TYPE_ONLY_APPLICATION=ON ..
          cmake --build . --config ${{env.BUILD_TYPE}}  -- -j 4
        if: matrix.os == 'windows-2019'
      
      - name: Copy Modules & Package (Windows)
        shell: msys2 {0}
        run: |
          cd $(echo "/${{github.workspace}}"  | sed 's/\\/\//g' | sed 's/://')
          mkdir -p build/artifacts/modules
          cp -r modules/build/artifacts/bin/* build/artifacts/modules
          cd build
          windeployqt-qt6 --no-translations --force ./artifacts/GpgFrontend.exe
          echo "BUILD_TYPE_LOWER=${BUILD_TYPE,,}" >> ${GITHUB_ENV}
          echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> ${GITHUB_ENV}
        if: matrix.os == 'windows-2019'

      - name: Upload Artifact (Linux)
        uses: actions/upload-artifact@master
        with:
          name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE_LOWER}}-${{env.SHORT_SHA}}
          path: ${{github.workspace}}/build/final-artifact/Gpg_Frontend*.AppImage*
        if: matrix.os == 'ubuntu-20.04'

      - name: Upload Artifact (macOS)
        uses: actions/upload-artifact@master
        with:
          name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE_LOWER}}-${{env.SHORT_SHA}}
          path: ${{github.workspace}}/build/final-artifact/*
        if:  matrix.os == 'macos-13' || matrix.os == 'macos-12' || matrix.os == 'macos-14'

      - name: Upload Artifact (Windows)
        uses: actions/upload-artifact@master
        with:
          name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE_LOWER}}-${{env.SHORT_SHA}}
          path: ${{github.workspace}}/build/artifacts/*
        if: matrix.os == 'windows-2019'
