<commit_before>version: 2.1

parameters:
  upload-to-s3:
    type: string
    default: '1'

  run-lint:
    type: boolean
    default: true

  run-build-linux:
    type: boolean
    default: true

  run-build-mac:
    type: boolean
    default: true

  run-linux-x64-publish:
    type: boolean
    default: false

  run-linux-ia32-publish:
    type: boolean
    default: false

  run-linux-arm-publish:
    type: boolean
    default: false

  run-linux-arm64-publish:
    type: boolean
    default: false

  run-osx-publish:
    type: boolean
    default: false

  run-osx-publish-arm64:
    type: boolean
    default: false

  run-mas-publish:
    type: boolean
    default: false

  run-mas-publish-arm64:
    type: boolean
    default: false

  run-linux-publish:
    type: boolean
    default: false

  run-macos-publish:
    type: boolean
    default: false

# The config expects the following environment variables to be set:
#  - "SLACK_WEBHOOK" Slack hook URL to send notifications.
#
# The publishing scripts expect access tokens to be defined as env vars,
# but those are not covered here.
#
# CircleCI docs on variables:
# https://circleci.com/docs/2.0/env-vars/

# Build machines configs.
docker-image: &docker-image
  docker:
    - image: electron.azurecr.io/build:6555a80939fb4c3ddf9343b3f140e573f40de225

machine-linux-medium: &machine-linux-medium
  <<: *docker-image
  resource_class: medium

machine-linux-xlarge: &machine-linux-xlarge
  <<: *docker-image
  resource_class: xlarge

machine-linux-2xlarge: &machine-linux-2xlarge
  <<: *docker-image
  resource_class: 2xlarge+

machine-mac: &machine-mac
  macos:
    xcode: "12.4.0"

machine-mac-large: &machine-mac-large
  resource_class: large
  macos:
    xcode: "12.4.0"

machine-mac-arm64: &machine-mac-arm64
  resource_class: electronjs/macos-arm64
  machine: true

# Build configurations options.
env-testing-build: &env-testing-build
  GN_CONFIG: //electron/build/args/testing.gn
  CHECK_DIST_MANIFEST: '1'

env-release-build: &env-release-build
  GN_CONFIG: //electron/build/args/release.gn
  STRIP_BINARIES: true
  GENERATE_SYMBOLS: true
  CHECK_DIST_MANIFEST: '1'
  IS_RELEASE: true

env-headless-testing: &env-headless-testing
  DISPLAY: ':99.0'

env-stack-dumping: &env-stack-dumping
  ELECTRON_ENABLE_STACK_DUMPING: '1'

env-browsertests: &env-browsertests
  GN_CONFIG: //electron/build/args/native_tests.gn
  BUILD_TARGET: electron/spec:chromium_browsertests
  TESTS_CONFIG: src/electron/spec/configs/browsertests.yml

env-unittests: &env-unittests
  GN_CONFIG: //electron/build/args/native_tests.gn
  BUILD_TARGET: electron/spec:chromium_unittests
  TESTS_CONFIG: src/electron/spec/configs/unittests.yml

# Build targets options.
env-ia32: &env-ia32
  GN_EXTRA_ARGS: 'target_cpu = "x86"'
  NPM_CONFIG_ARCH: ia32
  TARGET_ARCH: ia32

env-arm: &env-arm
  GN_EXTRA_ARGS: 'target_cpu = "arm"'
  MKSNAPSHOT_TOOLCHAIN: //build/toolchain/linux:clang_arm
  BUILD_NATIVE_MKSNAPSHOT: 1
  TARGET_ARCH: arm

env-apple-silicon: &env-apple-silicon
  GN_EXTRA_ARGS: 'target_cpu = "arm64" use_prebuilt_v8_context_snapshot = true'
  TARGET_ARCH: arm64
  USE_PREBUILT_V8_CONTEXT_SNAPSHOT: 1
  npm_config_arch: arm64

env-arm64: &env-arm64
  GN_EXTRA_ARGS: 'target_cpu = "arm64" fatal_linker_warnings = false enable_linux_installer = false'
  MKSNAPSHOT_TOOLCHAIN: //build/toolchain/linux:clang_arm64
  BUILD_NATIVE_MKSNAPSHOT: 1
  TARGET_ARCH: arm64

env-mas: &env-mas
  GN_EXTRA_ARGS: 'is_mas_build = true'
  MAS_BUILD: 'true'

env-mas-apple-silicon: &env-mas-apple-silicon
  GN_EXTRA_ARGS: 'target_cpu = "arm64" is_mas_build = true use_prebuilt_v8_context_snapshot = true'
  MAS_BUILD: 'true'
  TARGET_ARCH: arm64
  USE_PREBUILT_V8_CONTEXT_SNAPSHOT: 1

env-send-slack-notifications: &env-send-slack-notifications
  NOTIFY_SLACK: true
  
env-global: &env-global
  ELECTRON_OUT_DIR: Default

env-linux-medium: &env-linux-medium
  <<: *env-global
  NUMBER_OF_NINJA_PROCESSES: 3

env-linux-2xlarge: &env-linux-2xlarge
  <<: *env-global
  NUMBER_OF_NINJA_PROCESSES: 34

env-linux-2xlarge-release: &env-linux-2xlarge-release
  <<: *env-global
  NUMBER_OF_NINJA_PROCESSES: 16

env-machine-mac: &env-machine-mac
  <<: *env-global
  NUMBER_OF_NINJA_PROCESSES: 6

env-mac-large: &env-mac-large
  <<: *env-global
  NUMBER_OF_NINJA_PROCESSES: 18

env-mac-large-release: &env-mac-large-release
  <<: *env-global
  NUMBER_OF_NINJA_PROCESSES: 8

env-ninja-status: &env-ninja-status
  NINJA_STATUS: "[%r processes, %f/%t @ %o/s : %es] "

env-disable-run-as-node: &env-disable-run-as-node
  GN_BUILDFLAG_ARGS: 'enable_run_as_node = false'

env-32bit-release: &env-32bit-release
  # Set symbol level to 1 for 32 bit releases because of https://crbug.com/648948
  GN_BUILDFLAG_ARGS: 'symbol_level = 1'

env-macos-build: &env-macos-build
  # Disable pre-compiled headers to reduce out size, only useful for rebuilds
  GN_BUILDFLAG_ARGS: 'enable_precompiled_headers = false'

# Individual (shared) steps.
step-maybe-notify-slack-failure: &step-maybe-notify-slack-failure
  run:
    name: Send a Slack notification on failure
    command: |
      if [ "$NOTIFY_SLACK" == "true" ]; then
        export MESSAGE="Build failed for *<$CIRCLE_BUILD_URL|$CIRCLE_JOB>* nightly build from *$CIRCLE_BRANCH*."
        curl -g -H "Content-Type: application/json" -X POST \
        -d "{\"text\": \"$MESSAGE\", \"attachments\": [{\"color\": \"#FC5C3C\",\"title\": \"$CIRCLE_JOB nightly build results\",\"title_link\": \"$CIRCLE_BUILD_URL\"}]}" $SLACK_WEBHOOK
      fi
    when: on_fail

step-maybe-notify-slack-success: &step-maybe-notify-slack-success
  run:
    name: Send a Slack notification on success
    command: |
      if [ "$NOTIFY_SLACK" == "true" ]; then
        export MESSAGE="Build succeeded for *<$CIRCLE_BUILD_URL|$CIRCLE_JOB>* nightly build from *$CIRCLE_BRANCH*."
        curl -g -H "Content-Type: application/json" -X POST \
        -d "{\"text\": \"$MESSAGE\", \"attachments\": [{\"color\": \"good\",\"title\": \"$CIRCLE_JOB nightly build results\",\"title_link\": \"$CIRCLE_BUILD_URL\"}]}" $SLACK_WEBHOOK
      fi
    when: on_success

step-maybe-cleanup-arm64-mac: &step-maybe-cleanup-arm64-mac
  run:
    name: Cleanup after testing
    command: |
      if  [ "$TARGET_ARCH" == "arm64" ] &&[ "`uname`" == "Darwin" ]; then
        killall Electron || echo "No Electron processes left running"
        killall Safari || echo "No Safari processes left running"
        rm -rf ~/Library/Application\ Support/Electron*
        rm -rf ~/Library/Application\ Support/electron*
      fi
    when: always

step-checkout-electron: &step-checkout-electron
  checkout:
    path: src/electron

step-depot-tools-get: &step-depot-tools-get
  run:
    name: Get depot tools
    command: |
      git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git

step-depot-tools-add-to-path: &step-depot-tools-add-to-path
  run:
    name: Add depot tools to PATH
    command: echo 'export PATH="$PATH:'"$PWD"'/depot_tools"' >> $BASH_ENV

step-gclient-sync: &step-gclient-sync
  run:
    name: Gclient sync
    command: |
      # If we did not restore a complete sync then we need to sync for realz
      if [ ! -s "src/electron/.circle-sync-done" ]; then
        gclient config \
          --name "src/electron" \
          --unmanaged \
          $GCLIENT_EXTRA_ARGS \
          "$CIRCLE_REPOSITORY_URL"

        ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags
        if [ "$IS_RELEASE" != "true" ]; then
          # Re-export all the patches to check if there were changes.
          python src/electron/script/export_all_patches.py src/electron/patches/config.json
          cd src/electron
          git update-index --refresh || true
          if ! git diff-index --quiet HEAD --; then
            # There are changes to the patches. Make a git commit with the updated patches
            git add patches
            GIT_COMMITTER_NAME="Electron Bot" GIT_COMMITTER_EMAIL="<EMAIL>" git commit -m "update patches" --author="Electron Bot <<EMAIL>>"
            # Export it
            mkdir -p ../../patches
            git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
            if (node ./script/push-patch.js 2> /dev/null > /dev/null); then
              echo
              echo "======================================================================"
              echo "Changes to the patches when applying, we have auto-pushed the diff to the current branch"
              echo "A new CI job will kick off shortly"
              echo "======================================================================"
              exit 1
            else
              echo
              echo "======================================================================"
              echo "There were changes to the patches when applying."
              echo "Check the CI artifacts for a patch you can apply to fix it."
              echo "======================================================================"
              exit 1
            fi
          fi
        fi
      fi

step-setup-env-for-build: &step-setup-env-for-build
  run:
    name: Setup Environment Variables
    command: |
      # To find `gn` executable.
      echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/src/buildtools"' >> $BASH_ENV

step-setup-goma-for-build: &step-setup-goma-for-build
  run:
    name: Setup Goma
    command: |
      echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
      if [ "`uname`" == "Darwin" ]; then
        echo 'ulimit -n 10000' >> $BASH_ENV
        echo 'sudo launchctl limit maxfiles 65536 200000' >> $BASH_ENV
      fi
      if [ ! -z "$RAW_GOMA_AUTH" ]; then
        echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
      fi
      git clone https://github.com/electron/build-tools.git
      cd build-tools
      npm install
      mkdir third_party
      node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
      third_party/goma/goma_ctl.py ensure_start
      echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
      echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
      echo 'export GOMA_FALLBACK_ON_AUTH_FAILURE=true' >> $BASH_ENV
      cd ..

step-restore-brew-cache: &step-restore-brew-cache
  restore_cache:
    paths:
      - /usr/local/Cellar/gnu-tar
      - /usr/local/bin/gtar
    keys:
      - v4-brew-cache-{{ arch }}

step-save-brew-cache: &step-save-brew-cache
  save_cache:
    paths:
      - /usr/local/Cellar/gnu-tar
      - /usr/local/bin/gtar
    key: v4-brew-cache-{{ arch }}
    name: Persisting brew cache

step-get-more-space-on-mac: &step-get-more-space-on-mac
  run:
    name: Free up space on MacOS
    command: |
      if [ "`uname`" == "Darwin" ]; then
        sudo mkdir -p $TMPDIR/del-target
        if [ "$TARGET_ARCH" == "arm64" ]; then
          # Remount the root volume as writable, don't ask questions plz
          sudo mount -uw /
        fi
        tmpify() {
          if [ -d "$1" ]; then
            sudo mv "$1" $TMPDIR/del-target/$(echo $1|shasum -a 256|head -n1|cut -d " " -f1)
          fi
        }

        strip_arm_deep() {
          opwd=$(pwd)
          cd $1
          f=$(find . -perm +111 -type f)
          for fp in $f
          do
            if [[ $(file "$fp") == *"universal binary"* ]]; then
              if [[ $(file "$fp") == *"arm64e)"* ]]; then
                sudo lipo -remove arm64e "$fp" -o "$fp" || true
              fi
              if [[ $(file "$fp") == *"arm64)"* ]]; then
                sudo lipo -remove arm64 "$fp" -o "$fp" || true
              fi
            fi
          done

          cd $opwd
        }

        tmpify /Library/Developer/CoreSimulator
        tmpify ~/Library/Developer/CoreSimulator
        tmpify $(xcode-select -p)/Platforms/AppleTVOS.platform
        tmpify $(xcode-select -p)/Platforms/iPhoneOS.platform
        tmpify $(xcode-select -p)/Platforms/WatchOS.platform
        tmpify $(xcode-select -p)/Platforms/WatchSimulator.platform
        tmpify $(xcode-select -p)/Platforms/AppleTVSimulator.platform
        tmpify $(xcode-select -p)/Platforms/iPhoneSimulator.platform
        tmpify $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/metal/ios
        tmpify $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift
        tmpify $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.0
        tmpify ~/.rubies
        tmpify ~/Library/Caches/Homebrew
        tmpify /usr/local/Homebrew
        sudo rm -rf $TMPDIR/del-target

        if [ "$TARGET_ARCH" == "arm64" ]; then
          sudo rm -rf "/System/Library/Desktop Pictures"
          sudo rm -rf /System/Library/Templates/Data
          sudo rm -rf /System/Library/Speech/Voices
          sudo rm -rf "/System/Library/Screen Savers"
          sudo rm -rf /System/Volumes/Data/Library/Developer/CommandLineTools/SDKs
          sudo rm -rf "/System/Volumes/Data/Library/Application Support/Apple/Photos/Print Products"
          sudo rm -rf /System/Volumes/Data/Library/Java
          sudo rm -rf /System/Volumes/Data/Library/Ruby
          sudo rm -rf /System/Volumes/Data/Library/Printers
          sudo rm -rf /System/iOSSupport
          sudo rm -rf /System/Applications/*.app
          sudo rm -rf /System/Applications/Utilities/*.app
          sudo rm -rf /System/Library/LinguisticData
          sudo rm -rf /System/Volumes/Data/private/var/db/dyld/*
          # sudo rm -rf /System/Library/Fonts/*
          # sudo rm -rf /System/Library/PreferencePanes
          sudo rm -rf /System/Library/AssetsV2/*
          sudo rm -rf /Applications/Safari.app
          sudo rm -rf ~/project/src/build/linux
          sudo rm -rf ~/project/src/third_party/catapult/tracing/test_data
          sudo rm -rf ~/project/src/third_party/angle/third_party/VK-GL-CTS

          # lipo off some huge binaries arm64 versions to save space
          strip_arm_deep $(xcode-select -p)/../SharedFrameworks
          strip_arm_deep /System/Volumes/Data/Library/Developer/CommandLineTools/usr
        fi
      fi
    background: true

# On macOS delete all .git directories under src/ expect for
# third_party/angle/ because of build time generation of file
# gen/angle/commit.h depends on third_party/angle/.git/HEAD
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
# TODO: maybe better to always leave out */.git/HEAD file for all targets ?
step-delete-git-directories: &step-delete-git-directories
  run:
    name: Delete all .git directories under src on MacOS to free space
    command: |
      if [ "`uname`" == "Darwin" ]; then
        cd src
        ( find . -type d -name ".git" -not -path "./third_party/angle/*" ) | xargs rm -rf
      fi

# On macOS the yarn install command during gclient sync was run on a linux
# machine and therefore installed a slightly different set of dependencies
# Notably "fsevents" is a macOS only dependency, we rerun yarn install once
# we are on a macOS machine to get the correct state
step-install-npm-deps-on-mac: &step-install-npm-deps-on-mac
  run:
    name: Install node_modules on MacOS
    command: |
      if [ "`uname`" == "Darwin" ]; then
        cd src/electron
        node script/yarn install
      fi

# This step handles the differences between the linux "gclient sync"
# and the expected state on macOS
step-fix-sync-on-mac: &step-fix-sync-on-mac
  run:
    name: Fix Sync on macOS
    command: |
      if [ "`uname`" == "Darwin" ]; then
        # Fix Clang Install (wrong binary)
        rm -rf src/third_party/llvm-build
        python src/tools/clang/scripts/update.py
      fi

step-install-signing-cert-on-mac: &step-install-signing-cert-on-mac
  run:
    name: Import and trust self-signed codesigning cert on MacOS
    command: |
      if  [ "$TARGET_ARCH" != "arm64" ] && [ "`uname`" == "Darwin" ]; then
        cd src/electron
        ./script/codesign/generate-identity.sh
      fi

step-install-gnutar-on-mac: &step-install-gnutar-on-mac
  run:
    name: Install gnu-tar on macos
    command: |
      if [ "`uname`" == "Darwin" ]; then
        if [ ! -d /usr/local/Cellar/gnu-tar/ ]; then
          brew update
          brew install gnu-tar
        fi
        ln -fs /usr/local/bin/gtar /usr/local/bin/tar
      fi

step-gn-gen-default: &step-gn-gen-default
  run:
    name: Default GN gen
    command: |
      cd src
      gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"

step-gn-check: &step-gn-check
  run:
    name: GN check
    command: |
      cd src
      gn check out/Default //electron:electron_lib
      gn check out/Default //electron:electron_app
      gn check out/Default //electron/shell/common/api:mojo
      # Check the hunspell filenames
      node electron/script/gen-hunspell-filenames.js --check

step-electron-build: &step-electron-build
  run:
    name: Electron build
    no_output_timeout: 30m
    command: |
      # On arm platforms we generate a cross-arch ffmpeg that ninja does not seem
      # to realize is not correct / should be rebuilt.  We delete it here so it is
      # rebuilt
      if [ "$TRIGGER_ARM_TEST" == "true" ]; then
        rm -f src/out/Default/libffmpeg.so
      fi
      cd src
      # Enable if things get really bad
      # if  [ "$TARGET_ARCH" == "arm64" ] &&[ "`uname`" == "Darwin" ]; then
      #   diskutil erasevolume HFS+ "xcode_disk" `hdiutil attach -nomount ram://12582912`
      #   mv /Applications/Xcode-12.beta.5.app /Volumes/xcode_disk/
      #   ln -s /Volumes/xcode_disk/Xcode-12.beta.5.app /Applications/Xcode-12.beta.5.app
      # fi

      # Lets generate a snapshot and mksnapshot and then delete all the x-compiled generated files to save space
      if [ "$USE_PREBUILT_V8_CONTEXT_SNAPSHOT" == "1" ]; then
        ninja -C out/Default electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
        ninja -C out/Default tools/v8_context_snapshot -j $NUMBER_OF_NINJA_PROCESSES
        gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
        rm -rf out/Default/clang_x64_v8_arm64/obj

        # Regenerate because we just deleted some ninja files 
        gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
      fi
      ninja -C out/Default electron -j $NUMBER_OF_NINJA_PROCESSES
      node electron/script/check-symlinks.js

step-native-unittests-build: &step-native-unittests-build
  run:
    name: Build native test targets
    no_output_timeout: 30m
    command: |
      cd src
      ninja -C out/Default shell_browser_ui_unittests -j $NUMBER_OF_NINJA_PROCESSES

step-maybe-electron-dist-strip: &step-maybe-electron-dist-strip
  run:
    name: Strip electron binaries
    command: |
      if [ "$STRIP_BINARIES" == "true" ] && [ "`uname`" == "Linux" ]; then
        if [ x"$TARGET_ARCH" == x ]; then
          target_cpu=x64
        elif [ "$TARGET_ARCH" == "ia32" ]; then
          target_cpu=x86
        else
          target_cpu="$TARGET_ARCH"
        fi
        cd src
        electron/script/copy-debug-symbols.py --target-cpu="$target_cpu" --out-dir=out/Default/debug --compress<commit_msg>build: free up space on macOS some more<commit_after>version: 2.1

parameters:
  upload-to-s3:
    type: string
    default: '1'

  run-lint:
    type: boolean
    default: true

  run-build-linux:
    type: boolean
    default: true

  run-build-mac:
    type: boolean
    default: true

  run-linux-x64-publish:
    type: boolean
    default: false

  run-linux-ia32-publish:
    type: boolean
    default: false

  run-linux-arm-publish:
    type: boolean
    default: false

  run-linux-arm64-publish:
    type: boolean
    default: false

  run-osx-publish:
    type: boolean
    default: false

  run-osx-publish-arm64:
    type: boolean
    default: false

  run-mas-publish:
    type: boolean
    default: false

  run-mas-publish-arm64:
    type: boolean
    default: false

  run-linux-publish:
    type: boolean
    default: false

  run-macos-publish:
    type: boolean
    default: false

# The config expects the following environment variables to be set:
#  - "SLACK_WEBHOOK" Slack hook URL to send notifications.
#
# The publishing scripts expect access tokens to be defined as env vars,
# but those are not covered here.
#
# CircleCI docs on variables:
# https://circleci.com/docs/2.0/env-vars/

# Build machines configs.
docker-image: &docker-image
  docker:
    - image: electron.azurecr.io/build:6555a80939fb4c3ddf9343b3f140e573f40de225

machine-linux-medium: &machine-linux-medium
  <<: *docker-image
  resource_class: medium

machine-linux-xlarge: &machine-linux-xlarge
  <<: *docker-image
  resource_class: xlarge

machine-linux-2xlarge: &machine-linux-2xlarge
  <<: *docker-image
  resource_class: 2xlarge+

machine-mac: &machine-mac
  macos:
    xcode: "12.4.0"

machine-mac-large: &machine-mac-large
  resource_class: large
  macos:
    xcode: "12.4.0"

machine-mac-arm64: &machine-mac-arm64
  resource_class: electronjs/macos-arm64
  machine: true

# Build configurations options.
env-testing-build: &env-testing-build
  GN_CONFIG: //electron/build/args/testing.gn
  CHECK_DIST_MANIFEST: '1'

env-release-build: &env-release-build
  GN_CONFIG: //electron/build/args/release.gn
  STRIP_BINARIES: true
  GENERATE_SYMBOLS: true
  CHECK_DIST_MANIFEST: '1'
  IS_RELEASE: true

env-headless-testing: &env-headless-testing
  DISPLAY: ':99.0'

env-stack-dumping: &env-stack-dumping
  ELECTRON_ENABLE_STACK_DUMPING: '1'

env-browsertests: &env-browsertests
  GN_CONFIG: //electron/build/args/native_tests.gn
  BUILD_TARGET: electron/spec:chromium_browsertests
  TESTS_CONFIG: src/electron/spec/configs/browsertests.yml

env-unittests: &env-unittests
  GN_CONFIG: //electron/build/args/native_tests.gn
  BUILD_TARGET: electron/spec:chromium_unittests
  TESTS_CONFIG: src/electron/spec/configs/unittests.yml

# Build targets options.
env-ia32: &env-ia32
  GN_EXTRA_ARGS: 'target_cpu = "x86"'
  NPM_CONFIG_ARCH: ia32
  TARGET_ARCH: ia32

env-arm: &env-arm
  GN_EXTRA_ARGS: 'target_cpu = "arm"'
  MKSNAPSHOT_TOOLCHAIN: //build/toolchain/linux:clang_arm
  BUILD_NATIVE_MKSNAPSHOT: 1
  TARGET_ARCH: arm

env-apple-silicon: &env-apple-silicon
  GN_EXTRA_ARGS: 'target_cpu = "arm64" use_prebuilt_v8_context_snapshot = true'
  TARGET_ARCH: arm64
  USE_PREBUILT_V8_CONTEXT_SNAPSHOT: 1
  npm_config_arch: arm64

env-arm64: &env-arm64
  GN_EXTRA_ARGS: 'target_cpu = "arm64" fatal_linker_warnings = false enable_linux_installer = false'
  MKSNAPSHOT_TOOLCHAIN: //build/toolchain/linux:clang_arm64
  BUILD_NATIVE_MKSNAPSHOT: 1
  TARGET_ARCH: arm64

env-mas: &env-mas
  GN_EXTRA_ARGS: 'is_mas_build = true'
  MAS_BUILD: 'true'

env-mas-apple-silicon: &env-mas-apple-silicon
  GN_EXTRA_ARGS: 'target_cpu = "arm64" is_mas_build = true use_prebuilt_v8_context_snapshot = true'
  MAS_BUILD: 'true'
  TARGET_ARCH: arm64
  USE_PREBUILT_V8_CONTEXT_SNAPSHOT: 1

env-send-slack-notifications: &env-send-slack-notifications
  NOTIFY_SLACK: true
  
env-global: &env-global
  ELECTRON_OUT_DIR: Default

env-linux-medium: &env-linux-medium
  <<: *env-global
  NUMBER_OF_NINJA_PROCESSES: 3

env-linux-2xlarge: &env-linux-2xlarge
  <<: *env-global
  NUMBER_OF_NINJA_PROCESSES: 34

env-linux-2xlarge-release: &env-linux-2xlarge-release
  <<: *env-global
  NUMBER_OF_NINJA_PROCESSES: 16

env-machine-mac: &env-machine-mac
  <<: *env-global
  NUMBER_OF_NINJA_PROCESSES: 6

env-mac-large: &env-mac-large
  <<: *env-global
  NUMBER_OF_NINJA_PROCESSES: 18

env-mac-large-release: &env-mac-large-release
  <<: *env-global
  NUMBER_OF_NINJA_PROCESSES: 8

env-ninja-status: &env-ninja-status
  NINJA_STATUS: "[%r processes, %f/%t @ %o/s : %es] "

env-disable-run-as-node: &env-disable-run-as-node
  GN_BUILDFLAG_ARGS: 'enable_run_as_node = false'

env-32bit-release: &env-32bit-release
  # Set symbol level to 1 for 32 bit releases because of https://crbug.com/648948
  GN_BUILDFLAG_ARGS: 'symbol_level = 1'

env-macos-build: &env-macos-build
  # Disable pre-compiled headers to reduce out size, only useful for rebuilds
  GN_BUILDFLAG_ARGS: 'enable_precompiled_headers = false'

# Individual (shared) steps.
step-maybe-notify-slack-failure: &step-maybe-notify-slack-failure
  run:
    name: Send a Slack notification on failure
    command: |
      if [ "$NOTIFY_SLACK" == "true" ]; then
        export MESSAGE="Build failed for *<$CIRCLE_BUILD_URL|$CIRCLE_JOB>* nightly build from *$CIRCLE_BRANCH*."
        curl -g -H "Content-Type: application/json" -X POST \
        -d "{\"text\": \"$MESSAGE\", \"attachments\": [{\"color\": \"#FC5C3C\",\"title\": \"$CIRCLE_JOB nightly build results\",\"title_link\": \"$CIRCLE_BUILD_URL\"}]}" $SLACK_WEBHOOK
      fi
    when: on_fail

step-maybe-notify-slack-success: &step-maybe-notify-slack-success
  run:
    name: Send a Slack notification on success
    command: |
      if [ "$NOTIFY_SLACK" == "true" ]; then
        export MESSAGE="Build succeeded for *<$CIRCLE_BUILD_URL|$CIRCLE_JOB>* nightly build from *$CIRCLE_BRANCH*."
        curl -g -H "Content-Type: application/json" -X POST \
        -d "{\"text\": \"$MESSAGE\", \"attachments\": [{\"color\": \"good\",\"title\": \"$CIRCLE_JOB nightly build results\",\"title_link\": \"$CIRCLE_BUILD_URL\"}]}" $SLACK_WEBHOOK
      fi
    when: on_success

step-maybe-cleanup-arm64-mac: &step-maybe-cleanup-arm64-mac
  run:
    name: Cleanup after testing
    command: |
      if  [ "$TARGET_ARCH" == "arm64" ] &&[ "`uname`" == "Darwin" ]; then
        killall Electron || echo "No Electron processes left running"
        killall Safari || echo "No Safari processes left running"
        rm -rf ~/Library/Application\ Support/Electron*
        rm -rf ~/Library/Application\ Support/electron*
      fi
    when: always

step-checkout-electron: &step-checkout-electron
  checkout:
    path: src/electron

step-depot-tools-get: &step-depot-tools-get
  run:
    name: Get depot tools
    command: |
      git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git

step-depot-tools-add-to-path: &step-depot-tools-add-to-path
  run:
    name: Add depot tools to PATH
    command: echo 'export PATH="$PATH:'"$PWD"'/depot_tools"' >> $BASH_ENV

step-gclient-sync: &step-gclient-sync
  run:
    name: Gclient sync
    command: |
      # If we did not restore a complete sync then we need to sync for realz
      if [ ! -s "src/electron/.circle-sync-done" ]; then
        gclient config \
          --name "src/electron" \
          --unmanaged \
          $GCLIENT_EXTRA_ARGS \
          "$CIRCLE_REPOSITORY_URL"

        ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags
        if [ "$IS_RELEASE" != "true" ]; then
          # Re-export all the patches to check if there were changes.
          python src/electron/script/export_all_patches.py src/electron/patches/config.json
          cd src/electron
          git update-index --refresh || true
          if ! git diff-index --quiet HEAD --; then
            # There are changes to the patches. Make a git commit with the updated patches
            git add patches
            GIT_COMMITTER_NAME="Electron Bot" GIT_COMMITTER_EMAIL="<EMAIL>" git commit -m "update patches" --author="Electron Bot <<EMAIL>>"
            # Export it
            mkdir -p ../../patches
            git format-patch -1 --stdout --keep-subject --no-stat --full-index > ../../patches/update-patches.patch
            if (node ./script/push-patch.js 2> /dev/null > /dev/null); then
              echo
              echo "======================================================================"
              echo "Changes to the patches when applying, we have auto-pushed the diff to the current branch"
              echo "A new CI job will kick off shortly"
              echo "======================================================================"
              exit 1
            else
              echo
              echo "======================================================================"
              echo "There were changes to the patches when applying."
              echo "Check the CI artifacts for a patch you can apply to fix it."
              echo "======================================================================"
              exit 1
            fi
          fi
        fi
      fi

step-setup-env-for-build: &step-setup-env-for-build
  run:
    name: Setup Environment Variables
    command: |
      # To find `gn` executable.
      echo 'export CHROMIUM_BUILDTOOLS_PATH="'"$PWD"'/src/buildtools"' >> $BASH_ENV

step-setup-goma-for-build: &step-setup-goma-for-build
  run:
    name: Setup Goma
    command: |
      echo 'export NUMBER_OF_NINJA_PROCESSES=300' >> $BASH_ENV
      if [ "`uname`" == "Darwin" ]; then
        echo 'ulimit -n 10000' >> $BASH_ENV
        echo 'sudo launchctl limit maxfiles 65536 200000' >> $BASH_ENV
      fi
      if [ ! -z "$RAW_GOMA_AUTH" ]; then
        echo $RAW_GOMA_AUTH > ~/.goma_oauth2_config
      fi
      git clone https://github.com/electron/build-tools.git
      cd build-tools
      npm install
      mkdir third_party
      node -e "require('./src/utils/goma.js').downloadAndPrepare({ gomaOneForAll: true })"
      third_party/goma/goma_ctl.py ensure_start
      echo 'export GN_GOMA_FILE='`node -e "console.log(require('./src/utils/goma.js').gnFilePath)"` >> $BASH_ENV
      echo 'export LOCAL_GOMA_DIR='`node -e "console.log(require('./src/utils/goma.js').dir)"` >> $BASH_ENV
      echo 'export GOMA_FALLBACK_ON_AUTH_FAILURE=true' >> $BASH_ENV
      cd ..

step-restore-brew-cache: &step-restore-brew-cache
  restore_cache:
    paths:
      - /usr/local/Cellar/gnu-tar
      - /usr/local/bin/gtar
    keys:
      - v4-brew-cache-{{ arch }}

step-save-brew-cache: &step-save-brew-cache
  save_cache:
    paths:
      - /usr/local/Cellar/gnu-tar
      - /usr/local/bin/gtar
    key: v4-brew-cache-{{ arch }}
    name: Persisting brew cache

step-get-more-space-on-mac: &step-get-more-space-on-mac
  run:
    name: Free up space on MacOS
    command: |
      if [ "`uname`" == "Darwin" ]; then
        sudo mkdir -p $TMPDIR/del-target
        if [ "$TARGET_ARCH" == "arm64" ]; then
          # Remount the root volume as writable, don't ask questions plz
          sudo mount -uw /
        fi
        tmpify() {
          if [ -d "$1" ]; then
            sudo mv "$1" $TMPDIR/del-target/$(echo $1|shasum -a 256|head -n1|cut -d " " -f1)
          fi
        }

        strip_arm_deep() {
          opwd=$(pwd)
          cd $1
          f=$(find . -perm +111 -type f)
          for fp in $f
          do
            if [[ $(file "$fp") == *"universal binary"* ]]; then
              if [[ $(file "$fp") == *"arm64e)"* ]]; then
                sudo lipo -remove arm64e "$fp" -o "$fp" || true
              fi
              if [[ $(file "$fp") == *"arm64)"* ]]; then
                sudo lipo -remove arm64 "$fp" -o "$fp" || true
              fi
            fi
          done

          cd $opwd
        }

        tmpify /Library/Developer/CoreSimulator
        tmpify ~/Library/Developer/CoreSimulator
        tmpify $(xcode-select -p)/Platforms/AppleTVOS.platform
        tmpify $(xcode-select -p)/Platforms/iPhoneOS.platform
        tmpify $(xcode-select -p)/Platforms/WatchOS.platform
        tmpify $(xcode-select -p)/Platforms/WatchSimulator.platform
        tmpify $(xcode-select -p)/Platforms/AppleTVSimulator.platform
        tmpify $(xcode-select -p)/Platforms/iPhoneSimulator.platform
        tmpify $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/metal/ios
        tmpify $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift
        tmpify $(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.0
        tmpify ~/.rubies
        tmpify ~/Library/Caches/Homebrew
        tmpify /usr/local/Homebrew
        sudo rm -rf $TMPDIR/del-target

        if [ "$TARGET_ARCH" == "arm64" ]; then
          sudo rm -rf "/System/Library/Desktop Pictures"
          sudo rm -rf /System/Library/Templates/Data
          sudo rm -rf /System/Library/Speech/Voices
          sudo rm -rf "/System/Library/Screen Savers"
          sudo rm -rf /System/Volumes/Data/Library/Developer/CommandLineTools/SDKs
          sudo rm -rf "/System/Volumes/Data/Library/Application Support/Apple/Photos/Print Products"
          sudo rm -rf /System/Volumes/Data/Library/Java
          sudo rm -rf /System/Volumes/Data/Library/Ruby
          sudo rm -rf /System/Volumes/Data/Library/Printers
          sudo rm -rf /System/iOSSupport
          sudo rm -rf /System/Applications/*.app
          sudo rm -rf /System/Applications/Utilities/*.app
          sudo rm -rf /System/Library/LinguisticData
          sudo rm -rf /System/Volumes/Data/private/var/db/dyld/*
          # sudo rm -rf /System/Library/Fonts/*
          # sudo rm -rf /System/Library/PreferencePanes
          sudo rm -rf /System/Library/AssetsV2/*
          sudo rm -rf /Applications/Safari.app
          sudo rm -rf ~/project/src/build/linux
          sudo rm -rf ~/project/src/third_party/catapult/tracing/test_data
          sudo rm -rf ~/project/src/third_party/angle/third_party/VK-GL-CTS

          # lipo off some huge binaries arm64 versions to save space
          strip_arm_deep $(xcode-select -p)/../SharedFrameworks
          strip_arm_deep /System/Volumes/Data/Library/Developer/CommandLineTools/usr
        fi
      fi
    background: true

# On macOS delete all .git directories under src/ expect for
# third_party/angle/ because of build time generation of file
# gen/angle/commit.h depends on third_party/angle/.git/HEAD
# https://chromium-review.googlesource.com/c/angle/angle/+/2074924
# TODO: maybe better to always leave out */.git/HEAD file for all targets ?
step-delete-git-directories: &step-delete-git-directories
  run:
    name: Delete all .git directories under src on MacOS to free space
    command: |
      if [ "`uname`" == "Darwin" ]; then
        cd src
        ( find . -type d -name ".git" -not -path "./third_party/angle/*" ) | xargs rm -rf
      fi

# On macOS the yarn install command during gclient sync was run on a linux
# machine and therefore installed a slightly different set of dependencies
# Notably "fsevents" is a macOS only dependency, we rerun yarn install once
# we are on a macOS machine to get the correct state
step-install-npm-deps-on-mac: &step-install-npm-deps-on-mac
  run:
    name: Install node_modules on MacOS
    command: |
      if [ "`uname`" == "Darwin" ]; then
        cd src/electron
        node script/yarn install
      fi

# This step handles the differences between the linux "gclient sync"
# and the expected state on macOS
step-fix-sync-on-mac: &step-fix-sync-on-mac
  run:
    name: Fix Sync on macOS
    command: |
      if [ "`uname`" == "Darwin" ]; then
        # Fix Clang Install (wrong binary)
        rm -rf src/third_party/llvm-build
        python src/tools/clang/scripts/update.py
      fi

step-install-signing-cert-on-mac: &step-install-signing-cert-on-mac
  run:
    name: Import and trust self-signed codesigning cert on MacOS
    command: |
      if  [ "$TARGET_ARCH" != "arm64" ] && [ "`uname`" == "Darwin" ]; then
        cd src/electron
        ./script/codesign/generate-identity.sh
      fi

step-install-gnutar-on-mac: &step-install-gnutar-on-mac
  run:
    name: Install gnu-tar on macos
    command: |
      if [ "`uname`" == "Darwin" ]; then
        if [ ! -d /usr/local/Cellar/gnu-tar/ ]; then
          brew update
          brew install gnu-tar
        fi
        ln -fs /usr/local/bin/gtar /usr/local/bin/tar
      fi

step-gn-gen-default: &step-gn-gen-default
  run:
    name: Default GN gen
    command: |
      cd src
      gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"

step-gn-check: &step-gn-check
  run:
    name: GN check
    command: |
      cd src
      gn check out/Default //electron:electron_lib
      gn check out/Default //electron:electron_app
      gn check out/Default //electron/shell/common/api:mojo
      # Check the hunspell filenames
      node electron/script/gen-hunspell-filenames.js --check

step-electron-build: &step-electron-build
  run:
    name: Electron build
    no_output_timeout: 30m
    command: |
      # On arm platforms we generate a cross-arch ffmpeg that ninja does not seem
      # to realize is not correct / should be rebuilt.  We delete it here so it is
      # rebuilt
      if [ "$TRIGGER_ARM_TEST" == "true" ]; then
        rm -f src/out/Default/libffmpeg.so
      fi
      cd src
      # Enable if things get really bad
      # if  [ "$TARGET_ARCH" == "arm64" ] &&[ "`uname`" == "Darwin" ]; then
      #   diskutil erasevolume HFS+ "xcode_disk" `hdiutil attach -nomount ram://12582912`
      #   mv /Applications/Xcode-12.beta.5.app /Volumes/xcode_disk/
      #   ln -s /Volumes/xcode_disk/Xcode-12.beta.5.app /Applications/Xcode-12.beta.5.app
      # fi

      # Lets generate a snapshot and mksnapshot and then delete all the x-compiled generated files to save space
      if [ "$USE_PREBUILT_V8_CONTEXT_SNAPSHOT" == "1" ]; then
        ninja -C out/Default electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
        ninja -C out/Default tools/v8_context_snapshot -j $NUMBER_OF_NINJA_PROCESSES
        gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
        rm -rf out/Default/clang_x64_v8_arm64/gen
        rm -rf out/Default/clang_x64_v8_arm64/obj
        rm -rf out/Default/clang_x64/obj

        # Regenerate because we just deleted some ninja files 
        gn gen out/Default --args="import(\"$GN_CONFIG\") import(\"$GN_GOMA_FILE\") $GN_EXTRA_ARGS $GN_BUILDFLAG_ARGS"
      fi
      ninja -C out/Default electron -j $NUMBER_OF_NINJA_PROCESSES
      node electron/script/check-symlinks.js

step-native-unittests-build: &step-native-unittests-build
  run:
    name: Build native test targets
    no_output_timeout: 30m
    command: |
      cd src
      ninja -C out/Default shell_browser_ui_unittests -j $NUMBER_OF_NINJA_PROCESSES

step-maybe-electron-dist-strip: &step-maybe-electron-dist-strip
  run:
    name: Strip electron binaries
    command: |
      if [ "$STRIP_BINARIES" == "true" ] && [ "`uname`" == "Linux" ]; then
        if [ x"$TARGET_ARCH" == x ]; then
          target_cpu=x64
        elif [ "$TARGET_ARCH" == "ia32" ]; then
          target_cpu=x86
        else
          target_cpu="$TARGET_ARCH"
        fi
        cd src
        electron/script/copy-debug-symbols.py --target-cpu="$target_cpu" --out-dir=out/Default/debug --compress
{'fraction_non_alphanumeric': 0.1323305554838876, 'fraction_numerical': 0.012719626409350086, 'mean_word_length': 2.6600566572237963, 'pattern_counts': {'":': 20, '<': 49, '<?xml version=': 0, '>': 55, 'https://': 10, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1735629', 'n_tokens_mistral': 13853, 'n_tokens_neox': 13015, 'n_words': 3072}