name: Pipeline Segment - Electron Build

on:
  workflow_call:
    inputs:
      environment:
        description: using the production or testing environment
        required: false
        type: string
      target-platform:
        type: string
        description: 'Platform to run on, can be macos or linux'
        required: true
      target-arch:
        type: string
        description: 'Arch to build for, can be x64, arm64 or arm'
        required: true
      build-runs-on:
        type: string
        description: 'What host to run the build'
        required: true
      build-container:
        type: string
        description: 'JSON container information for aks runs-on'
        required: false
        default: '{"image":null}'
      is-release:
        description: 'Whether this build job is a release job'
        required: true
        type: boolean
        default: false
      gn-build-type:
        description: 'The gn build type - testing or release'
        required: true
        type: string
        default: testing
      generate-symbols: 
        description: 'Whether or not to generate symbols'
        required: true
        type: boolean
        default: false
      upload-to-storage: 
        description: 'Whether or not to upload build artifacts to external storage'
        required: true
        type: string
        default: '0'
      strip-binaries: 
        description: 'Strip the binaries before release (Linux only)'
        required: false
        type: boolean
        default: false
      is-asan: 
        description: 'Building the Address Sanitizer (ASan) Linux build'
        required: false
        type: boolean
        default: false


concurrency:
  group: electron-build-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref }}
  cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}

env:
  ELECTRON_ARTIFACTS_BLOB_STORAGE: ${{ secrets.ELECTRON_ARTIFACTS_BLOB_STORAGE }}
  ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
  ELECTRON_GITHUB_TOKEN: ${{ secrets.ELECTRON_GITHUB_TOKEN }}
  GCLIENT_EXTRA_ARGS: ${{ inputs.target-platform == 'macos' && '--custom-var=checkout_mac=True --custom-var=host_os=mac' || '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' }}
  ELECTRON_OUT_DIR: Default

jobs:
  build:
    runs-on: ${{ inputs.build-runs-on }}
    container: ${{ fromJSON(inputs.build-container) }}
    environment: ${{ inputs.environment }}
    env:
      TARGET_ARCH: ${{ inputs.target-arch }}
    steps:
    - name: Create src dir
      run: mkdir src
    - name: Checkout Electron
      uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
      with:
        path: src/electron
        fetch-depth: 0
    - name: Setup Node.js/npm
      if: ${{ inputs.target-platform == 'macos' }}
      uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8
      with:
        node-version: 20.11.x
        cache: yarn
        cache-dependency-path: src/electron/yarn.lock
    - name: Install Dependencies
      run: |
        cd src/electron
        node script/yarn install --frozen-lockfile
    - name: Install Python Tools (Mac)
      if: ${{ inputs.target-platform == 'macos' }}
      run: brew install python-setuptools
    - name: Install AZCopy
      if: ${{ inputs.target-platform == 'macos' }}
      run: brew install azcopy
    - name: Set GN_EXTRA_ARGS for Linux
      if: ${{ inputs.target-platform == 'linux' }}
      run: |
        if [ "${{ inputs.target-arch  }}" = "arm" ]; then
          if [ "${{ inputs.is-release  }}" = true ]; then
            GN_EXTRA_ARGS='target_cpu="arm" build_tflite_with_xnnpack=false symbol_level=1'
          else
            GN_EXTRA_ARGS='target_cpu="arm" build_tflite_with_xnnpack=false'
          fi
        elif [ "${{ inputs.target-arch }}" = "arm64" ]; then
          GN_EXTRA_ARGS='target_cpu="arm64" fatal_linker_warnings=false enable_linux_installer=false'
        elif [ "${{ inputs.is-asan }}" = true ]; then
          GN_EXTRA_ARGS='is_asan=true'
        fi
        echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV
    - name: Get Depot Tools
      timeout-minutes: 5
      run: |
        git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git

        SEDOPTION="-i"
        if [ "`uname`" = "Darwin" ]; then
          SEDOPTION="-i ''"
        fi

        # remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
        sed $SEDOPTION '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja

        # Ensure depot_tools does not update.
        test -d depot_tools && cd depot_tools
        if [ "`uname`" = "Linux" ]; then
          git apply --3way ../src/electron/.github/workflows/config/gclient.diff
        fi
        touch .disable_auto_update
    - name: Add Depot Tools to PATH
      run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
    - name: Generate DEPS Hash
      run: |
        node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
        DEPSHASH=v1-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')
        echo "DEPSHASH=$DEPSHASH" >> $GITHUB_ENV
        echo "CACHE_PATH=$DEPSHASH.tar" >> $GITHUB_ENV
    - name: Restore src cache via AZCopy
      if: ${{ inputs.target-platform == 'macos' }}
      uses: ./src/electron/.github/actions/restore-cache-azcopy
    - name: Restore src cache via AKS
      if: ${{ inputs.target-platform == 'linux' }}
      uses: ./src/electron/.github/actions/restore-cache-aks
    - name: Checkout Electron
      uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
      with:
        path: src/electron
        fetch-depth: 0
    - name: Install Build Tools
      uses: ./src/electron/.github/actions/install-build-tools
    - name: Init Build Tools
      run: |
        e init -f --root=$(pwd) --out=Default ${{ inputs.gn-build-type }} --import ${{ inputs.gn-build-type }} --target-cpu ${{ inputs.target-arch }} --only-sdk
    - name: Run Electron Only Hooks
      run: |
        gclient runhooks --spec="solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]"
    - name: Regenerate DEPS Hash
      run: |
        (cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
        echo "DEPSHASH=$(shasum src/electron/.depshash | cut -f1 -d' ')" >> $GITHUB_ENV
    - name: Add CHROMIUM_BUILDTOOLS_PATH to env
      run: echo "CHROMIUM_BUILDTOOLS_PATH=$(pwd)/src/buildtools" >> $GITHUB_ENV
    - name: Fix Sync
      uses: ./src/electron/.github/actions/fix-sync
      with:
        target-arch: ${{ inputs.target-arch }}
        target-platform: ${{ inputs.target-platform }}
    - name: Install build-tools & Setup RBE
      run: |
        echo "NUMBER_OF_NINJA_PROCESSES=${{ inputs.target-platform == 'linux' && '300' || '200' }}" >> $GITHUB_ENV
        cd ~/.electron_build_tools
        npx yarn --ignore-engines
        # Pull down credential helper and print status
        node -e "require('./src/utils/reclient.js').downloadAndPrepare({})"
        HELPER=$(node -p "require('./src/utils/reclient.js').helperPath({})")
        $HELPER login
        echo 'RBE_service='`node -e "console.log(require('./src/utils/reclient.js').serviceAddress)"` >> $GITHUB_ENV
        echo 'RBE_experimental_credentials_helper='`node -e "console.log(require('./src/utils/reclient.js').helperPath({}))"` >> $GITHUB_ENV
        echo 'RBE_experimental_credentials_helper_args=print' >> $GITHUB_ENV
    - name: Free up space (macOS)
      if: ${{ inputs.target-platform == 'macos' }}
      uses: ./src/electron/.github/actions/free-space-macos
    - name: Build Electron
      uses: ./src/electron/.github/actions/build-electron
      with:
        target-arch: ${{ inputs.target-arch }}
        target-platform: ${{ inputs.target-platform }}
        artifact-platform: ${{ inputs.target-platform == 'linux' && 'linux' || 'darwin' }}
        is-release: '${{ inputs.is-release }}'
        generate-symbols: '${{ inputs.generate-symbols }}'
        strip-binaries: '${{ inputs.strip-binaries }}'
        upload-to-storage: '${{ inputs.upload-to-storage }}'
        is-asan: '${{ inputs.is-asan }}'
    - name: Set GN_EXTRA_ARGS for MAS Build
      if: ${{ inputs.target-platform == 'macos' }}
      run: |
        echo "MAS_BUILD=true" >> $GITHUB_ENV
        GN_EXTRA_ARGS='is_mas_build=true'
        echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV
    - name: Build Electron (MAS)
      if: ${{ inputs.target-platform == 'macos' }}
      uses: ./src/electron/.github/actions/build-electron
      with:
        target-arch: ${{ inputs.target-arch }}
        target-platform: ${{ inputs.target-platform }}
        artifact-platform: 'mas'
        is-release: '${{ inputs.is-release }}'
        generate-symbols: '${{ inputs.generate-symbols }}'
        upload-to-storage: '${{ inputs.upload-to-storage }}'
        step-suffix: '(mas)'