name: 📦🚀 Build Installer - Windows 10

on:
  workflow_dispatch:
  push:
    paths-ignore:
    - '**.md'
    branches:
      - 'long_lived/**'
      - main
      - 'release/**'
  release:
    types: [published]
  pull_request:
    paths-ignore:
    - '**.md'
    branches:
      - '**'

concurrency:
  # SHA is added to the end if on `main` to let all main workflows run
  group: ${{ github.ref }}-${{ github.workflow }}-${{ github.event_name }}-${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/') || startsWith(github.ref, 'refs/heads/long_lived/')) && github.sha || '' }}
  cancel-in-progress: true

jobs:
  build:
    name: Windows 10 Installer
    runs-on: [windows-2019]
    timeout-minutes: 50
    strategy:
      fail-fast: false
      matrix:
        python-version: [3.9]

    steps:
    - name: Checkout Code
      uses: actions/checkout@v3
      with:
        fetch-depth: 0
        submodules: recursive

    - name: Set Env
      uses: Chia-Network/actions/setjobenv@main
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    - name: Set git urls to https instead of ssh
      run: |
        git config --global url."https://github.com/".insteadOf ssh://git@github.com/

    - name: Get npm cache directory
      id: npm-cache
      shell: bash
      run: |
        echo "dir=$(npm config get cache)" >>$GITHUB_OUTPUT

    - name: Cache npm
      uses: actions/cache@v3
      with:
        path: ${{ steps.npm-cache.outputs.dir }}
        key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
        restore-keys: |
          ${{ runner.os }}-node-

    - name: Get pip cache dir
      id: pip-cache
      shell: bash
      run: |
        echo "dir=$(pip cache dir)" >>$GITHUB_OUTPUT

    - name: Cache pip
      uses: actions/cache@v3
      with:
        path: ${{ steps.pip-cache.outputs.dir }}
        key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
        restore-keys: |
          ${{ runner.os }}-pip-

    - uses: Chia-Network/actions/setup-python@main
      name: Install Python ${{ matrix.python-version }}
      with:
        python-version: ${{ matrix.python-version }}

    - name: Setup Node 16.x
      uses: actions/setup-node@v3
      with:
        node-version: '16.x'

    - name: Test for secrets access
      id: check_secrets
      shell: bash
      run: |
        unset HAS_SIGNING_SECRET
        unset HAS_AWS_SECRET
        unset HAS_GLUE_SECRET

        if [ -n "$SIGNING_SECRET" ]; then HAS_SIGNING_SECRET='true' ; fi
        echo "HAS_SIGNING_SECRET=${HAS_SIGNING_SECRET}" >>$GITHUB_OUTPUT

        if [ -n "$AWS_SECRET" ]; then HAS_AWS_SECRET='true' ; fi
        echo HAS_AWS_SECRET=${HAS_AWS_SECRET} >>$GITHUB_OUTPUT

        if [ -n "$GLUE_ACCESS_TOKEN" ]; then HAS_GLUE_SECRET='true' ; fi
        echo HAS_GLUE_SECRET=${HAS_GLUE_SECRET} >>$GITHUB_OUTPUT
      env:
        SIGNING_SECRET: "${{ secrets.WIN_CODE_SIGN_CERT }}"
        AWS_SECRET: "${{ secrets.INSTALLER_UPLOAD_KEY }}"
        GLUE_ACCESS_TOKEN: "${{ secrets.GLUE_ACCESS_TOKEN }}"

    - name: Decode code signing cert into an encrypted file
      if: steps.check_secrets.outputs.HAS_SIGNING_SECRET
      uses: kitek/decode-base64-into-file-action@1.0
      with:
        encoded-value: ${{ secrets.WIN_CODE_SIGN_CERT }}
        destination-file: .\win_code_sign_cert.p12

    # Create our own venv outside of the git directory JUST for getting the ACTUAL version so that install can't break it
    - name: Get version number
      id: version_number
      shell: bash
      run: |
        python -m venv ../venv
        source ../venv/Scripts/activate
        pip3 install setuptools_scm
        CHIA_INSTALLER_VERSION=$(python ./build_scripts/installer-version.py)
        echo "$CHIA_INSTALLER_VERSION"
        echo "CHIA_INSTALLER_VERSION=$CHIA_INSTALLER_VERSION" >>$GITHUB_OUTPUT
        deactivate

    - name: Get latest madmax plotter
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      shell: bash
      run: |
        LATEST_MADMAX=$(gh api repos/Chia-Network/chia-plotter-madmax/releases/latest --jq 'select(.prerelease == false) | .tag_name')
        mkdir $GITHUB_WORKSPACE\\madmax
        gh release download -R Chia-Network/chia-plotter-madmax $LATEST_MADMAX -p 'chia_plot-*.exe' -O $GITHUB_WORKSPACE\\madmax\\chia_plot.exe
        gh release download -R Chia-Network/chia-plotter-madmax $LATEST_MADMAX -p 'chia_plot_k34-*.exe' -O $GITHUB_WORKSPACE\\madmax\\chia_plot_k34.exe

    - name: Get latest bladebit plotter
      if: '!github.event.release.prerelease'
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      shell: bash
      run: |
        LATEST_BLADEBIT=$(gh api repos/Chia-Network/bladebit/releases/latest --jq 'select(.prerelease == false) | .tag_name')
        mkdir $GITHUB_WORKSPACE\\bladebit
        gh release download -R Chia-Network/bladebit $LATEST_BLADEBIT -p '*windows-x86-64.zip' -O $GITHUB_WORKSPACE\\bladebit\\bladebit.zip
        unzip $GITHUB_WORKSPACE\\bladebit\\bladebit.zip -d $GITHUB_WORKSPACE\\bladebit\\
        rm $GITHUB_WORKSPACE\\bladebit\\bladebit.zip

    - name: Get latest prerelease bladebit plotter
      if: env.PRE_RELEASE == 'true'
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      shell: bash
      run: |
        LATEST_PRERELEASE=$(gh api repos/Chia-Network/bladebit/releases --jq 'map(select(.prerelease)) | first | .tag_name')
        mkdir $GITHUB_WORKSPACE\\bladebit
        gh release download -R Chia-Network/bladebit $LATEST_PRERELEASE -p '*windows-x86-64.zip' -O $GITHUB_WORKSPACE\\bladebit\\bladebit.zip
        unzip $GITHUB_WORKSPACE\\bladebit\\bladebit.zip -d $GITHUB_WORKSPACE\\bladebit\\
        rm $GITHUB_WORKSPACE\\bladebit\\bladebit.zip

    - name: Run install script
      env:
        INSTALL_PYTHON_VERSION: ${{ matrix.python-version }}
      run: |
        .\Install.ps1 -d

    - uses: chia-network/actions/activate-venv@main

    - name: Prepare GUI cache
      id: gui-ref
      shell: bash
      run: |
        gui_ref=$(git submodule status chia-blockchain-gui | sed -e 's/^ //g' -e 's/ chia-blockchain-gui.*$//g')
        echo "${gui_ref}"
        echo "GUI_REF=${gui_ref}" >>$GITHUB_OUTPUT
        echo "rm -rf ./chia-blockchain-gui"
        rm -rf ./chia-blockchain-gui

    - name: Cache GUI
      uses: actions/cache@v3
      id: cache-gui
      with:
        path: .\chia-blockchain-gui
        key: ${{ runner.os }}-chia-blockchain-gui-${{ steps.gui-ref.outputs.GUI_REF }}

    - if: steps.cache-gui.outputs.cache-hit != 'true'
      name: Build GUI
      continue-on-error: false
      run: |
        cd .\build_scripts
        .\build_windows-1-gui.ps1

    - name: Build Windows installer
      env:
        CHIA_INSTALLER_VERSION: ${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}
        HAS_SECRET: ${{ steps.check_secrets.outputs.HAS_SIGNING_SECRET }}
        CSC_KEY_PASSWORD: ${{ secrets.WIN_CODE_SIGN_PASS }}
      run: |
        $env:path="C:\Program` Files` (x86)\Microsoft` Visual` Studio\2019\Enterprise\SDK\ScopeCppSDK\vc15\VC\bin\;$env:path"
        $env:path="C:\Program` Files` (x86)\Windows` Kits\10\App` Certification` Kit;$env:path"
        cd .\build_scripts
        .\build_windows-2-installer.ps1

    - name: Upload Installer to artifacts
      uses: actions/upload-artifact@v3
      with:
        name: chia-installers-windows-exe-intel
        path: ${{ github.workspace }}\chia-blockchain-gui\release-builds\

    - name: Install AWS CLI
      if: steps.check_secrets.outputs.HAS_AWS_SECRET
      run: |
          msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi

    - name: Configure AWS Credentials
      if: steps.check_secrets.outputs.HAS_AWS_SECRET
      uses: aws-actions/configure-aws-credentials@v2
      with:
        aws-access-key-id: ${{ secrets.INSTALLER_UPLOAD_KEY }}
        aws-secret-access-key: ${{ secrets.INSTALLER_UPLOAD_SECRET }}
        aws-region: us-west-2

    - name: Upload to s3
      if: steps.check_secrets.outputs.HAS_AWS_SECRET
      env:
        CHIA_INSTALLER_VERSION: ${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}
      shell: bash
      run: |
        GIT_SHORT_HASH=$(echo "${GITHUB_SHA}" | cut -c1-8)
        CHIA_DEV_BUILD=${CHIA_INSTALLER_VERSION}-$GIT_SHORT_HASH
        echo CHIA_DEV_BUILD=${CHIA_DEV_BUILD} >>$GITHUB_OUTPUT
        echo ${CHIA_DEV_BUILD}
        pwd
        aws s3 cp chia-blockchain-gui/release-builds/windows-installer/ChiaSetup-${CHIA_INSTALLER_VERSION}.exe s3://download.chia.net/dev/ChiaSetup-${CHIA_DEV_BUILD}.exe

    - name: Create Checksums
      env:
        CHIA_INSTALLER_VERSION: ${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}
      run: |
         certutil.exe -hashfile ${{ github.workspace }}\chia-blockchain-gui\release-builds\windows-installer\ChiaSetup-${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}.exe SHA256 > ${{ github.workspace }}\chia-blockchain-gui\release-builds\windows-installer\ChiaSetup-${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}.exe.sha256
         ls ${{ github.workspace }}\chia-blockchain-gui\release-builds\windows-installer\

    - name: Create torrent
      if: env.FULL_RELEASE == 'true'
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        py3createtorrent -f -t udp://tracker.opentrackr.org:1337/announce ${{ github.workspace }}\chia-blockchain-gui\release-builds\windows-installer\ChiaSetup-${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}.exe -o ${{ github.workspace }}\chia-blockchain-gui\release-builds\windows-installer\ChiaSetup-${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}.exe.torrent --webseed https://download.chia.net/install/ChiaSetup-${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}.exe
        ls
        gh release upload $env:RELEASE_TAG ${{ github.workspace }}\chia-blockchain-gui\release-builds\windows-installer\ChiaSetup-${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}.exe.torrent

    - name: Upload Dev Installer
      if: steps.check_secrets.outputs.HAS_AWS_SECRET && github.ref == 'refs/heads/main'
      env:
        CHIA_INSTALLER_VERSION: ${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}
      run: |
        aws s3 cp ${{ github.workspace }}\chia-blockchain-gui\release-builds\windows-installer\ChiaSetup-${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}.exe s3://download.chia.net/latest-dev/ChiaSetup-latest-dev.exe
        aws s3 cp ${{ github.workspace }}\chia-blockchain-gui\release-builds\windows-installer\ChiaSetup-${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}.exe.sha256 s3://download.chia.net/latest-dev/ChiaSetup-latest-dev.exe.sha256

    - name: Upload Release Files
      if: steps.check_secrets.outputs.HAS_AWS_SECRET && env.FULL_RELEASE == 'true'
      env:
        AWS_ACCESS_KEY_ID: ${{ secrets.INSTALLER_UPLOAD_KEY }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.INSTALLER_UPLOAD_SECRET }}
      run: |
        aws s3 cp ${{ github.workspace }}\chia-blockchain-gui\release-builds\windows-installer\ChiaSetup-${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}.exe s3://download.chia.net/install/
        aws s3 cp ${{ github.workspace }}\chia-blockchain-gui\release-builds\windows-installer\ChiaSetup-${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}.exe.sha256 s3://download.chia.net/install/
        aws s3 cp ${{ github.workspace }}\chia-blockchain-gui\release-builds\windows-installer\ChiaSetup-${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}.exe.torrent s3://download.chia.net/torrents/

    - name: Get tag name
      if: startsWith(github.ref, 'refs/tags/')
      id: tag-name
      shell: bash
      run: |
        echo "TAG_NAME=$(echo ${{ github.ref }} | cut -d'/' -f 3)" >>$GITHUB_OUTPUT
        echo "REPO_NAME=$(echo ${{ github.repository }} | cut -d'/' -f 2)" >>$GITHUB_OUTPUT

    - name: Upload release artifacts
      if: env.RELEASE == 'true'
      env:
        GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        CHIA_INSTALLER_VERSION: ${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}
      run: |
        gh release upload $env:RELEASE_TAG ${{ github.workspace }}\chia-blockchain-gui\release-builds\windows-installer\ChiaSetup-${{ steps.version_number.outputs.CHIA_INSTALLER_VERSION }}.exe

    - name: Mark installer complete
      if: steps.check_secrets.outputs.HAS_GLUE_SECRET && env.FULL_RELEASE == 'true'
      run: |
        $headers = @{
            Authorization="Bearer ${{ secrets.GLUE_ACCESS_TOKEN }}"
        }
        $data = @{
            chia_ref='${{ steps.tag-name.outputs.TAG_NAME }}'
        }
        $json = $data | ConvertTo-Json
        $response = Invoke-RestMethod '${{ secrets.GLUE_API_URL }}/api/v1/${{ steps.tag-name.outputs.REPO_NAME }}/${{ steps.tag-name.outputs.TAG_NAME }}/success/build-windows' -Method Post -Body $json -ContentType 'application/json' -Headers $headers

    - name: Remove Windows exe and installer to exclude from cache
      run: |
        Remove-Item .\chia-blockchain-gui\packages\gui\dist -Recurse -Force
        Remove-Item .\chia-blockchain-gui\packages\gui\daemon -Recurse -Force
        Remove-Item .\chia-blockchain-gui\Chia-win32-x64 -Recurse -Force
        Remove-Item .\chia-blockchain-gui\release-builds -Recurse -Force
