name: CI Actions for Fairbrix

on:
  push:
  workflow_dispatch:
    inputs:
     release:
       type: boolean
       description: 'Tick = Release, No tick = Pre-release'
       required: true
     tags:
      description: 'Set tag for release'
      required: true
     release-name:
       description: 'Specify a name for release'
       required: true

jobs:
  build_depends:
    name: Depends-${{ matrix.config.name }}
    runs-on: ${{ matrix.config.os }}
    env:
      APT_BASE: ccache
      SDK_URL: https://bitcoincore.org/depends-sources/sdks
    defaults:
      run:
        shell: bash
    strategy:
      fail-fast: false
      matrix:
        config:
          - name: ARM 32-bit
            os: ubuntu-20.04
            host: arm-linux-gnueabihf
            apt_get: python3 g++-arm-linux-gnueabihf

          - name: AARCH64
            os: ubuntu-20.04
            host: aarch64-linux-gnu
            apt_get: python3 g++-aarch64-linux-gnu

          - name: Win64
            os: ubuntu-20.04
            host: x86_64-w64-mingw32
            apt_get: python3 nsis g++-mingw-w64-x86-64 wine-binfmt wine64

          - name: 32-bit Linux
            os: ubuntu-20.04
            host: i686-pc-linux-gnu
            apt_get: g++-multilib python3-zmq

          - name: 64-bit Linux
            os: ubuntu-20.04
            host: x86_64-unknown-linux-gnu
            apt_get: python3-zmq

          - name: macOS 10.12
            os: ubuntu-20.04
            host: x86_64-apple-darwin16
            apt_get: cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python3-dev python3-setuptools
            XCODE_VERSION: 11.3.1
            XCODE_BUILD_ID: 11C505

    steps:
      - name: Get Source
        uses: actions/checkout@v2

      - name: Setup Environment
        run: |
          sudo apt-get update
          sudo apt-get install --no-install-recommends --no-upgrade -qq "$APT_BASE" ${{ matrix.config.apt_get }}

      - name: depends cache files
        uses: actions/cache@v4
        with:
          path: |
            depends/built
            depends/sdk-sources
            depends/${{ matrix.config.host }}
          key: ${{ runner.os }}-depends-${{ matrix.config.host }}
          restore-keys: ${{ runner.os }}-depends-${{ matrix.config.host }}

      - name: Build Depends
        run: |
          export LC_ALL=C.UTF-8

          PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g")
          # Add llvm-symbolizer directory to PATH. Needed to get symbolized stack traces from the sanitizers.
          PATH=$PATH:/usr/lib/llvm-6.0/bin/
          export PATH

          mkdir -p depends/SDKs depends/sdk-sources

          OSX_SDK_BASENAME="Xcode-${{ matrix.config.XCODE_VERSION }}-${{ matrix.config.XCODE_BUILD_ID }}-extracted-SDK-with-libcxx-headers.tar.gz"
          OSX_SDK_PATH="depends/sdk-sources/${OSX_SDK_BASENAME}"

          if [ -n "${{ matrix.config.XCODE_VERSION }}" ] && [ ! -f "$OSX_SDK_PATH" ]; then
            curl --location --fail "${SDK_URL}/${OSX_SDK_BASENAME}" -o "$OSX_SDK_PATH"
          fi

          if [ -n "${{ matrix.config.XCODE_VERSION }}" ] && [ -f "$OSX_SDK_PATH" ]; then
            tar -C "depends/SDKs" -xf "$OSX_SDK_PATH"
          fi

          if [[ ${{ matrix.config.host }} = *-mingw32 ]]; then
            BIN=$(which ${{ matrix.config.host }}-g++-posix)
            sudo update-alternatives --set ${{ matrix.config.host }}-g++ $BIN
          fi

          if [ -z "${{ matrix.config.no_depends }}" ]; then
            make -j2 -C depends HOST=${{ matrix.config.host }} ${{ matrix.config.dep_opts }}
          fi

  build_wallet:
    name: ${{ matrix.config.name }}
    runs-on: ${{ matrix.config.os }}
    needs: [build_depends]
    env:
      APT_BASE: ccache
      SDK_URL: https://bitcoincore.org/depends-sources/sdks
      CCACHE_DIR: ${{ github.workspace }}/.ccache
      CCACHE_SIZE: 500M
      CCACHE_COMPRESS: 1
      WINEDEBUG: fixme-all
      BOOST_TEST_RANDOM: 1${{ github.run_id }}
      TYPE: ${{ matrix.config.type }}
    defaults:
      run:
        shell: bash
    strategy:
      fail-fast: false
      matrix:
        config:
          - name: ARM 32-bit
            id: ARM32
            os: ubuntu-20.04
            host: arm-linux-gnueabihf
            apt_get: python3 g++-arm-linux-gnueabihf
            unit_tests: false
            functional_tests: false
            goal: install
            # -Wno-psabi is to disable ABI warnings: "note: parameter passing for argument of type ... changed in GCC 7.1"
            # This could be removed once the ABI change warning does not show up by default
            BITCOIN_CONFIG: "--with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports --disable-online-rust CXXFLAGS=-Wno-psabi --disable-tests --disable-bench"

          - name: AARCH64
            id: ARM64
            os: ubuntu-20.04
            host: aarch64-linux-gnu
            apt_get: python3 g++-aarch64-linux-gnu
            unit_tests: false
            functional_tests: false
            goal: install
            BITCOIN_CONFIG: "--with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports --disable-online-rust --disable-tests --disable-bench"

          - name: Win64
            id: Win64
            os: ubuntu-20.04
            host: x86_64-w64-mingw32
            apt_get: python3 nsis g++-mingw-w64-x86-64 wine-binfmt wine64
            unit_tests: false
            functional_tests: false
            symbol_check: true
            goal: deploy
            BITCOIN_CONFIG: "--with-gui=auto --enable-reduce-exports --disable-online-rust --disable-tests --disable-bench"

          - name: x86_64 Linux
            id: Linux-x86_64
            os: ubuntu-20.04
            host: x86_64-unknown-linux-gnu
            apt_get: python3-zmq
            unit_tests: false
            functional_tests: false
            goal: install
            test_runner_extra: "--coverage --all  --exclude feature_dbcrash"
            BITCOIN_CONFIG: "--enable-zmq --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports --disable-online-rust --disable-tests --disable-bench"

          - name: macOS 10.12
            id: macOS10.12
            os: ubuntu-20.04
            host: x86_64-apple-darwin16
            apt_get: cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python3-dev python3-setuptools
            XCODE_VERSION: 11.3.1
            XCODE_BUILD_ID: 11C505
            unit_tests: false
            functional_tests: false
            goal: deploy
            symbol_check: true
            BITCOIN_CONFIG: "--enable-gui --enable-reduce-exports --disable-online-rust --disable-tests --disable-bench"
    steps:
      - name: Get Source
        uses: actions/checkout@v2
        with:
          fetch-depth: '1'
          submodules: 'recursive'

      - name: Setup Environment
        run: |
          if [[ ${{ matrix.config.os }} = ubuntu* ]]; then
            sudo apt-add-repository "ppa:ondrej/php" -y
            sudo apt-get --yes update
            sudo apt-get install --no-install-recommends --no-upgrade -qq "$APT_BASE" ${{ matrix.config.apt_get }}
          fi
          if [[ ${{ matrix.config.os }} = macos* ]]; then
            brew install ${{ matrix.config.brew_install }}
            pip3.8 install ds_store mac_alias
          fi

      - name: depends cache files
        if: matrix.config.no_depends != 1
        uses: actions/cache@v4
        with:
          path: |
            depends/built
            depends/sdk-sources
            depends/${{ matrix.config.host }}
          key: ${{ runner.os }}-depends-${{ matrix.config.host }}
          restore-keys: ${{ runner.os }}-depends-${{ matrix.config.host }}

      - name: ccache cache files
        uses: actions/cache@v4
        with:
          path: |
            .ccache
          key: ${{ runner.os }}-depbuild-${{ matrix.config.id }}-ccache
          restore-keys: ${{ runner.os }}-depbuilt-${{ matrix.config.id }}-ccache

      - name: Build Wallet
        run: |
          export LC_ALL=C.UTF-8

          echo $CCACHE_DIR

          PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g")
          # Add llvm-symbolizer directory to PATH. Needed to get symbolized stack traces from the sanitizers.
          PATH=$PATH:/usr/lib/llvm-6.0/bin/
          export PATH

          mkdir -p depends/SDKs depends/sdk-sources

          OSX_SDK_BASENAME="Xcode-${{ matrix.config.XCODE_VERSION }}-${{ matrix.config.XCODE_BUILD_ID }}-extracted-SDK-with-libcxx-headers.tar.gz"
          OSX_SDK_PATH="depends/sdk-sources/${OSX_SDK_BASENAME}"

          if [ -n "${{ matrix.config.XCODE_VERSION }}" ] && [ ! -f "$OSX_SDK_PATH" ]; then
            curl --location --fail "${SDK_URL}/${OSX_SDK_BASENAME}" -o "$OSX_SDK_PATH"
          fi

          if [ -n "${{ matrix.config.XCODE_VERSION }}" ] && [ -f "$OSX_SDK_PATH" ]; then
            tar -C "depends/SDKs" -xf "$OSX_SDK_PATH"
          fi

          if [[ ${{ matrix.config.host }} = *-mingw32 ]]; then
            BIN=$(which ${{ matrix.config.host }}-g++-posix)
            sudo update-alternatives --set ${{ matrix.config.host }}-g++ $BIN
            sudo update-binfmts --import /usr/share/binfmts/wine
          fi

          if [[ ${{ matrix.config.os }} = macos* ]]; then
            CC=${{ matrix.config.cc }}
            CXX=${{ matrix.config.cxx }}
            export CC
            export CXX
          fi

          if [[ ${{ matrix.config.os }} = ubuntu* ]]; then
            OUTDIR_PATH="$GITHUB_WORKSPACE/$GITHUB_RUN_NUMBER-${{ matrix.config.host }}"
            BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$GITHUB_WORKSPACE/depends/${{ matrix.config.host }} --bindir=$OUTDIR_PATH/bin --libdir=$OUTDIR_PATH/lib"
          fi

          echo ::group::Autogen
          ./autogen.sh
          echo ::endgroup::

          mkdir build && cd build

          echo ::group::Configure
          ../configure --cache-file=config.cache $BITCOIN_CONFIG_ALL ${{ matrix.config.BITCOIN_CONFIG }} $PARAMS_FLAGS || ( cat config.log && false)
          echo ::endgroup::

          echo ::group::Distdir
          make distdir VERSION=${{ matrix.config.host }}
          echo ::endgroup::

          cd fairbrix-${{ matrix.config.host }}

          echo ::group::Configure
          ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL ${{ matrix.config.BITCOIN_CONFIG }} $PARAMS_FLAGS || ( cat config.log && false)
          echo ::endgroup

          echo ::group::Build
          make -j2 ${{ matrix.config.goal }} || ( echo "Build failure. Verbose build follows." && make ${{ matrix.config.goal }} V=1 ; false )
          echo ::endgroup::

          if [ "${{ matrix.config.unit_tests }}" = "true" ]; then
            echo ::group::Unit-Tests
            if [[ ${{ matrix.config.os }} = ubuntu* ]]; then
              LD_LIBRARY_PATH=$GITHUB_WORKSPACE/depends/"${{ matrix.config.host }}"/lib make -j2 check VERBOSE=1
            else
              make -j2 check VERBOSE=1
            fi
            echo ::endgroup::
          fi

          if [ "${{ matrix.config.functional_tests }}" = "true" ]; then
            echo ::group::Functional-Tests
            test/functional/test_runner.py --combinedlogslen=4000 ${{ matrix.config.test_runner_extra }}
            echo ::endgroup::
          fi

      - name: Zip Windows Builds
        if: ${{ matrix.config.host == 'x86_64-w64-mingw32' }}
        run: zip -rj fairbrix-Windows.zip /home/runner/work/fairbrix/fairbrix/build/fairbrix-x86_64-w64-mingw32/release

      - name: Zip Linux Builds
        if: ${{ matrix.config.host == 'x86_64-unknown-linux-gnu' }}
        run: zip -rj fairbrix-Linux.zip /home/runner/work/fairbrix/fairbrix/${{github.run_number}}-x86_64-unknown-linux-gnu/bin

      - name: Zip AArch64 Builds
        if: ${{ matrix.config.host == 'aarch64-linux-gnu' }}
        run: zip -rj fairbrix-AArch.zip /home/runner/work/fairbrix/fairbrix/${{github.run_number}}-aarch64-linux-gnu/bin

      - name: Zip Arm32 Builds
        if: ${{ matrix.config.host == 'arm-linux-gnueabihf' }}
        run: zip -rj fairbrix-Arm32.zip /home/runner/work/fairbrix/fairbrix/${{github.run_number}}-arm-linux-gnueabihf/bin

      - name: Upload Release Windows Builds
        uses: softprops/action-gh-release@v0.1.15
        if: matrix.config.host == 'x86_64-w64-mingw32' && github.event.inputs.release == 'true'
        with:
          name: ${{ github.event.inputs.release-name }}
          tag_name: ${{ github.event.inputs.tags }}
          prerelease: false
          files: |
            fairbrix-Windows.zip
            /home/runner/work/fairbrix/fairbrix/build/fairbrix-x86_64-w64-mingw32/fairbrix-*-setup-unsigned.exe

      - name: Upload PreRelease Windows Builds
        uses: softprops/action-gh-release@v0.1.15
        if: matrix.config.host == 'x86_64-w64-mingw32' && github.event.inputs.release == 'false'
        with:
          name: ${{ github.event.inputs.release-name }}
          tag_name: ${{ github.event.inputs.tags }}
          prerelease: true
          files: |
            fairbrix-Windows.zip
            /home/runner/work/fairbrix/fairbrix/build/fairbrix-x86_64-w64-mingw32/fairbrix-*-setup-unsigned.exe

      - name: Upload Release Linux Builds
        uses: softprops/action-gh-release@v0.1.15
        if: matrix.config.host == 'x86_64-unknown-linux-gnu' && github.event.inputs.release == 'true'
        with:
          name: ${{ github.event.inputs.release-name }}
          tag_name: ${{ github.event.inputs.tags }}
          prerelease: false
          files: fairbrix-Linux.zip

      - name: Upload PreRelease Linux Builds
        uses: softprops/action-gh-release@v0.1.15
        if: matrix.config.host == 'x86_64-unknown-linux-gnu' && github.event.inputs.release == 'false'
        with:
          name: ${{ github.event.inputs.release-name }}
          tag_name: ${{ github.event.inputs.tags }}
          prerelease: true
          files: fairbrix-Linux.zip

      - name: Upload Release Mac Builds
        uses: softprops/action-gh-release@v0.1.15
        if: matrix.config.host == 'x86_64-apple-darwin16' && github.event.inputs.release == 'true'
        with:
          name: ${{ github.event.inputs.release-name }}
          tag_name: ${{ github.event.inputs.tags }}
          prerelease: false
          files: /home/runner/work/fairbrix/fairbrix/build/fairbrix-x86_64-apple-darwin16/fairbrix-Core-Beta.dmg

      - name: Upload PreRelease Mac Builds
        uses: softprops/action-gh-release@v0.1.15
        if: matrix.config.host == 'x86_64-apple-darwin16' && github.event.inputs.release == 'false'
        with:
          name: ${{ github.event.inputs.release-name }}
          tag_name: ${{ github.event.inputs.tags }}
          prerelease: true
          files: /home/runner/work/fairbrix/fairbrix/build/fairbrix-x86_64-apple-darwin16/fairbrix-Core-Beta.dmg

      - name: Upload Release AArch Builds
        uses: softprops/action-gh-release@v0.1.15
        if: (matrix.config.host == 'aarch64-linux-gnu' && github.event.inputs.release == 'true')
        with:
          name: ${{ github.event.inputs.release-name }}
          tag_name: ${{ github.event.inputs.tags }}
          prerelease: false
          files: fairbrix-AArch.zip

      - name: Upload PreRelease AArch Builds
        uses: softprops/action-gh-release@v0.1.15
        if: (matrix.config.host == 'aarch64-linux-gnu' && github.event.inputs.release == 'false')
        with:
          name: ${{ github.event.inputs.release-name }}
          tag_name: ${{ github.event.inputs.tags }}
          prerelease: true
          files: fairbrix-AArch.zip

      - name: Upload Release Arm32 Builds
        uses: softprops/action-gh-release@v0.1.15
        if: (matrix.config.host == 'arm-linux-gnueabihf' && github.event.inputs.release == 'true')
        with:
          name: ${{ github.event.inputs.release-name }}
          tag_name: ${{ github.event.inputs.tags }}
          prerelease: false
          files: fairbrix-Arm32.zip

      - name: Upload PreRelease Arm32 Builds
        uses: softprops/action-gh-release@v0.1.15
        if: (matrix.config.host == 'arm-linux-gnueabihf' && github.event.inputs.release == 'false')
        with:
          name: ${{ github.event.inputs.release-name }}
          tag_name: ${{ github.event.inputs.tags }}
          prerelease: true
          files: fairbrix-Arm32.zip
