name: Build & Package

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

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

jobs:
  build:
    strategy:
      matrix:
        os: [ 'ubuntu-20.04', 'macos-11', 'macos-12', '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-11' || matrix.os == 'macos-12'

      - uses: actions/checkout@v3
        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-11 g++-11 ninja-build
          sudo apt-get -y install libconfig++-dev 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 libicu-dev libxcb-image0
          sudo apt-get -y install libglu1-mesa-dev libfontconfig1-dev libx11-xcb-dev libicu-dev libxcb-* libxkbcommon-x11-0
          sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 11
          sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-11 11
          sudo update-alternatives --set gcc "/usr/bin/gcc-11"
          sudo update-alternatives --set g++ "/usr/bin/g++-11"
        if: matrix.os == 'ubuntu-20.04'

      - name: Install Boost (Linux)
        uses: MarkusJx/install-boost@v2.4.1
        id: install-boost
        with:
            # REQUIRED: Specify the required boost version
            # A list of supported versions can be found here:
            # https://github.com/MarkusJx/prebuilt-boost/blob/main/versions-manifest.json
            boost_version: 1.81.0
            # OPTIONAL: Specify a platform version
            platform_version: 20.04
            # OPTIONAL: Specify an architecture
            arch: x86

            # NOTE: If a boost version matching all requirements cannot be found,
            # this build step will fail
        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 --output $CERTIFICATE_PATH
          echo -n "${{secrets.GPGFRONTEND_XOCDE_PROVISIONING_PROFILE_DATA}}" | base64 --decode --output $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-11' || matrix.os == 'macos-12'

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

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

      - name: Build gpg-error (Linux)
        run: |
          cd  ${{github.workspace}}/third_party/libgpg-error
          ./autogen.sh
          ./configure --enable-maintainer-mode && make -j2
          sudo make install
          cd ${{github.workspace}}
        if: matrix.os == 'ubuntu-20.04'

      - name: Build assuan (Linux)
        run: |
          cd ${{github.workspace}}/third_party/libassuan
          ./autogen.sh
          ./configure --enable-maintainer-mode && make -j2
          sudo make install
          cd ${{github.workspace}}
        if: matrix.os == 'ubuntu-20.04'

      - name: Build GpgME (Linux)
        run: |
          cd  ${{github.workspace}}/third_party/gpgme
          ./autogen.sh
          ./configure --enable-maintainer-mode --enable-languages=cpp && make -j2
          sudo make install
          cd ${{github.workspace}}
        if: matrix.os == 'ubuntu-20.04'

      - 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 mingw-w64-x86_64-libconfig mingw-w64-x86_64-boost automake 
          pacman --noconfirm -S --needed mingw-w64-x86_64-qt6 libintl msys2-runtime-devel gettext-devel mingw-w64-x86_64-gpgme
          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-icu mingw-w64-x86_64-icu-debug-libs
        if: matrix.os == 'windows-2019'

      - 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}} -DBOOST_ROOT=${{steps.install-boost.outputs.BOOST_ROOT}}
          cmake --build ${{github.workspace}}/build --config {{$env.BUILD_TYPE}} -- -v
        if: matrix.os == 'ubuntu-20.04'

      - 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-11' || matrix.os == 'macos-12'

      - 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/artifactOut
          hdiutil convert ${{github.workspace}}/build/tmp.dmg -format UDZO -o ${{github.workspace}}/build/artifactOut/GpgFrontend.dmg
          codesign -s "${{secrets.GPGFRONTEND_XOCDE_CODE_SIGN_IDENTITY}}" ${{github.workspace}}/build/artifactOut/GpgFrontend.dmg
          mv ${{github.workspace}}/build/artifactOut/GpgFrontend.dmg \
            ${{github.workspace}}/build/artifactOut/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-11' || matrix.os == 'macos-12'

      - name: Notarize Release Build (macOS)
        run: |
          xcrun altool --notarize-app \
          -f ${{github.workspace}}/build/GpgFrontend-${{env.sha_short}}-x86_64.zip \
          --primary-bundle-id ${{secrets.GPGFRONTEND_XOCDE_APPID}} \
          -u ${{secrets.APPLE_DEVELOPER_ID}} \
          -p ${{secrets.APPLE_DEVELOPER_ID_SECRET}}
        if:  matrix.os == 'macos-11' || matrix.os == 'macos-12'

      - name: Package App Image (Linux)
        run: |
          mkdir ${{github.workspace}}/build/artifactOut
          cd ${{github.workspace}}/build/artifactOut
          wget -c -nv https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
          chmod u+x linuxdeployqt-continuous-x86_64.AppImage
          ./linuxdeployqt-continuous-x86_64.AppImage ${{github.workspace}}/build/release/gpgfrontend/usr/share/applications/*.desktop -appimage
        if: matrix.os == 'ubuntu-20.04'

      - name: Configure CMake & Build Binary(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_STABLE=ON ..
          # Build your program with the given configuration
          cmake --build . --config ${{env.BUILD_TYPE}}  -- -j 2
        if: matrix.os == 'windows-2019'

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

      - name: Upload Artifact(macOS)
        uses: actions/upload-artifact@master
        with:
          name: gpgfrontend-${{matrix.os}}-${{env.BUILD_TYPE}}-${{env.sha_short}}
          path: ${{github.workspace}}/build/artifactOut/*
        if:  matrix.os == 'macos-11' || matrix.os == 'macos-12'

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