From ba9b3d4421dc16e2beee8014ac701c1bcb0eef29 Mon Sep 17 00:00:00 2001
From: Keeley Hammond <vertedinde@electronjs.org>
Date: Mon, 1 Jul 2024 03:33:12 -0700
Subject: [PATCH] build: migrate to GitHub Actions (#42720)

* build: migrate to GitHub Actions

* build: use old clang-format binary path

* debug (do not merge): intentionally bust Linux cache

* build: unskip cache creation
---
 .github/actions/build-electron/action.yml     | 217 ++++++++++++++++
 .github/actions/checkout/action.yml           | 154 +++++++++++
 .github/actions/fix-sync-macos/action.yml     |  61 +++++
 .github/actions/free-space-macos/action.yml   |  65 +++++
 .../actions/install-build-tools/action.yml    |  11 +
 .github/actions/restore-cache-aks/action.yml  |  36 +++
 .../actions/restore-cache-azcopy/action.yml   |  63 +++++
 .github/workflows/build.yml                   | 245 ++++++++++++++++++
 .github/workflows/config/gclient.diff         |  14 +
 .github/workflows/linux-publish.yml           |  83 ++++++
 .github/workflows/macos-publish.yml           |  69 +++++
 ...peline-electron-build-and-test-and-nan.yml | 103 ++++++++
 .../pipeline-electron-build-and-test.yml      | 100 +++++++
 .../workflows/pipeline-electron-docs-only.yml |  43 +++
 .github/workflows/pipeline-electron-lint.yml  |  77 ++++++
 .../pipeline-segment-electron-build.yml       | 207 +++++++++++++++
 .../pipeline-segment-electron-gn-check.yml    | 143 ++++++++++
 .../pipeline-segment-electron-test.yml        | 196 ++++++++++++++
 .../pipeline-segment-node-nan-test.yml        | 165 ++++++++++++
 script/actions/move-artifacts.sh              |  91 +++++++
 script/actions/restore-artifacts.sh           |  40 +++
 script/actions/run-tests.sh                   |   7 +
 script/release/ci-release-build.js            | 190 +-------------
 script/split-tests.js                         |  32 +++
 spec/api-app-spec.ts                          |   2 +-
 spec/api-protocol-spec.ts                     |   2 +-
 26 files changed, 2229 insertions(+), 187 deletions(-)
 create mode 100644 .github/actions/build-electron/action.yml
 create mode 100644 .github/actions/checkout/action.yml
 create mode 100644 .github/actions/fix-sync-macos/action.yml
 create mode 100644 .github/actions/free-space-macos/action.yml
 create mode 100644 .github/actions/install-build-tools/action.yml
 create mode 100644 .github/actions/restore-cache-aks/action.yml
 create mode 100644 .github/actions/restore-cache-azcopy/action.yml
 create mode 100644 .github/workflows/build.yml
 create mode 100644 .github/workflows/config/gclient.diff
 create mode 100644 .github/workflows/linux-publish.yml
 create mode 100644 .github/workflows/macos-publish.yml
 create mode 100644 .github/workflows/pipeline-electron-build-and-test-and-nan.yml
 create mode 100644 .github/workflows/pipeline-electron-build-and-test.yml
 create mode 100644 .github/workflows/pipeline-electron-docs-only.yml
 create mode 100644 .github/workflows/pipeline-electron-lint.yml
 create mode 100644 .github/workflows/pipeline-segment-electron-build.yml
 create mode 100644 .github/workflows/pipeline-segment-electron-gn-check.yml
 create mode 100644 .github/workflows/pipeline-segment-electron-test.yml
 create mode 100644 .github/workflows/pipeline-segment-node-nan-test.yml
 create mode 100755 script/actions/move-artifacts.sh
 create mode 100755 script/actions/restore-artifacts.sh
 create mode 100755 script/actions/run-tests.sh
 create mode 100755 script/split-tests.js

diff --git a/.github/actions/build-electron/action.yml b/.github/actions/build-electron/action.yml
new file mode 100644
index 000000000000..91896502a2cb
--- /dev/null
+++ b/.github/actions/build-electron/action.yml
@@ -0,0 +1,217 @@
+name: 'Build Electron'
+description: 'Builds Electron & Friends'
+inputs:
+  target-arch:
+    description: 'Target arch'
+    required: true
+  target-platform:
+    description: 'Target platform'
+    required: true
+  artifact-platform:
+    description: 'Artifact platform, should be linux, darwin or mas'
+    required: true
+  step-suffix:
+    description: 'Suffix for build steps'
+    required: false
+    default: ''
+  is-release:
+    description: 'Is release build'
+    required: true
+  generate-symbols:
+    description: 'Generate symbols'
+    required: true
+  upload-to-storage:
+    description: 'Upload to storage'
+    required: true
+  is-asan:
+    description: 'The ASan Linux build'
+    required: false
+runs:
+  using: "composite"
+  steps:
+    - name: Set GN_EXTRA_ARGS for MacOS x64 Builds
+      shell: bash
+      if: ${{ inputs.target-arch == 'x64' && inputs.target-platform == 'macos' }}
+      run: |
+        GN_APPENDED_ARGS="$GN_EXTRA_ARGS v8_snapshot_toolchain=\"//build/toolchain/mac:clang_x64\""
+        echo "GN_EXTRA_ARGS=$GN_APPENDED_ARGS" >> $GITHUB_ENV
+    - name: Build Electron ${{ inputs.step-suffix }}
+      shell: bash
+      run: |
+        rm -rf "src/out/Default/Electron Framework.framework"
+        rm -rf src/out/Default/Electron*.app
+
+        cd src/electron
+        # TODO(codebytere): remove this once we figure out why .git/packed-refs is initially missing
+        git pack-refs
+        cd ..
+
+        if [ "`uname`" = "Darwin" ]; then
+          ulimit -n 10000
+          sudo launchctl limit maxfiles 65536 200000
+        fi
+
+        NINJA_SUMMARIZE_BUILD=1 e build -j $NUMBER_OF_NINJA_PROCESSES
+        cp out/Default/.ninja_log out/electron_ninja_log
+        node electron/script/check-symlinks.js
+    - name: Strip Electron Binaries ${{ inputs.step-suffix }}
+      shell: bash
+      if: ${{ inputs.strip-binaries == 'true' }}
+      run: |
+        cd src
+        electron/script/copy-debug-symbols.py --target-cpu="${{ inputs.target-arch }}" --out-dir=out/Default/debug --compress
+        electron/script/strip-binaries.py --target-cpu="${{ inputs.target-arch }}"
+        electron/script/add-debug-link.py --target-cpu="${{ inputs.target-arch }}" --debug-dir=out/Default/debug
+    - name: Build Electron dist.zip ${{ inputs.step-suffix }}
+      shell: bash
+      run: |
+        cd src
+        e build electron:electron_dist_zip -j $NUMBER_OF_NINJA_PROCESSES
+        if [ "${{ inputs.is-asan }}" != "true" ]; then
+          target_os=${{ inputs.target-platform == 'linux' && 'linux' || 'mac'}}
+          if [ "${{ inputs.artifact-platform }}" = "mas" ]; then
+            target_os="${target_os}_mas"
+          fi
+          electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.${{ inputs.target-arch }}.manifest
+        fi
+    - name: Build Mksnapshot ${{ inputs.step-suffix }}
+      shell: bash
+      run: |
+        cd src
+        e build electron:electron_mksnapshot -j $NUMBER_OF_NINJA_PROCESSES
+        gn desc out/Default v8:run_mksnapshot_default args > out/Default/mksnapshot_args
+        # Remove unused args from mksnapshot_args
+        SEDOPTION="-i"
+        if [ "`uname`" = "Darwin" ]; then
+          SEDOPTION="-i ''"
+        fi
+        sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
+        sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
+        sed $SEDOPTION '/The gn arg use_goma=true .*/d' out/Default/mksnapshot_args
+
+        if [ "`uname`" = "Linux" ]; then
+          if [ "${{ inputs.target-arch }}" = "arm" ]; then
+            electron/script/strip-binaries.py --file $PWD/out/Default/clang_x86_v8_arm/mksnapshot
+            electron/script/strip-binaries.py --file $PWD/out/Default/clang_x86_v8_arm/v8_context_snapshot_generator
+          elif [ "${{ inputs.target-arch }}" = "arm64" ]; then
+            electron/script/strip-binaries.py --file $PWD/out/Default/clang_x64_v8_arm64/mksnapshot
+            electron/script/strip-binaries.py --file $PWD/out/Default/clang_x64_v8_arm64/v8_context_snapshot_generator
+          else
+            electron/script/strip-binaries.py --file $PWD/out/Default/mksnapshot
+            electron/script/strip-binaries.py --file $PWD/out/Default/v8_context_snapshot_generator
+          fi
+        fi
+
+        e build electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
+        (cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
+    - name: Generate Cross-Arch Snapshot (arm/arm64)  ${{ inputs.step-suffix }}
+      shell: bash
+      if: ${{ (inputs.target-arch == 'arm' || inputs.target-arch == 'arm64') && inputs.target-platform == 'linux' }}
+      run: |
+        cd src
+        if [ "${{ inputs.target-arch }}" = "arm" ]; then
+          MKSNAPSHOT_PATH="clang_x86_v8_arm"
+        elif [ "${{ inputs.target-arch }}" = "arm64" ]; then
+          MKSNAPSHOT_PATH="clang_x64_v8_arm64"
+        fi
+
+        cp "out/Default/$MKSNAPSHOT_PATH/mksnapshot" out/Default
+        cp "out/Default/$MKSNAPSHOT_PATH/v8_context_snapshot_generator" out/Default
+        cp "out/Default/$MKSNAPSHOT_PATH/libffmpeg.so" out/Default
+
+        python3 electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --create-snapshot-only
+        mkdir cross-arch-snapshots
+        cp out/Default-mksnapshot-test/*.bin cross-arch-snapshots
+        # Clean up so that ninja does not get confused
+        rm -f out/Default/libffmpeg.so
+    - name: Build Chromedriver ${{ inputs.step-suffix }}
+      shell: bash
+      run: |
+        cd src
+        e build electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
+        e build electron:electron_chromedriver_zip
+    - name: Build Node.js headers ${{ inputs.step-suffix }}
+      shell: bash
+      run: |
+        cd src
+        e build electron:node_headers
+    - name: Generate & Zip Symbols ${{ inputs.step-suffix }}
+      shell: bash
+      run: |
+        # Generate breakpad symbols on release builds
+        if [ "${{ inputs.generate-symbols }}" = "true" ]; then
+          e build electron:electron_symbols
+        fi
+        cd src
+        export BUILD_PATH="$(pwd)/out/Default"
+        e build electron:licenses
+        e build electron:electron_version_file
+        if [ "${{ inputs.is-release }}" = "true" ]; then
+          DELETE_DSYMS_AFTER_ZIP=1 electron/script/zip-symbols.py -b $BUILD_PATH
+        else
+          electron/script/zip-symbols.py -b $BUILD_PATH
+        fi
+    - name: Generate FFMpeg ${{ inputs.step-suffix }}
+      shell: bash
+      if: ${{ inputs.is-release == 'true' }}
+      run: |
+        cd src
+        gn gen out/ffmpeg --args="import(\"//electron/build/args/ffmpeg.gn\") use_remoteexec=true $GN_EXTRA_ARGS"
+        autoninja -C out/ffmpeg electron:electron_ffmpeg_zip -j $NUMBER_OF_NINJA_PROCESSES
+    - name: Generate Hunspell Dictionaries ${{ inputs.step-suffix }}
+      shell: bash
+      if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'linux' }}
+      run: |
+        cd src
+        autoninja -C out/Default electron:hunspell_dictionaries_zip -j $NUMBER_OF_NINJA_PROCESSES
+    - name: Generate Libcxx ${{ inputs.step-suffix }}
+      shell: bash
+      if: ${{ inputs.is-release == 'true' && inputs.target-platform == 'linux' }}
+      run: |
+        cd src
+        autoninja -C out/Default electron:libcxx_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
+        autoninja -C out/Default electron:libcxxabi_headers_zip -j $NUMBER_OF_NINJA_PROCESSES
+        autoninja -C out/Default electron:libcxx_objects_zip -j $NUMBER_OF_NINJA_PROCESSES
+    - name: Generate TypeScript Definitions ${{ inputs.step-suffix }}
+      if: ${{ inputs.is-release == 'true' }}
+      shell: bash
+      run: |
+        cd src/electron
+        node script/yarn create-typescript-definitions
+    - name: Publish Electron Dist ${{ inputs.step-suffix }}
+      if: ${{ inputs.is-release == 'true' }}
+      shell: bash
+      run: |
+        rm -rf src/out/Default/obj
+        cd src/electron
+        if [ "${{ inputs.upload-to-storage }}" = "1" ]; then
+          echo 'Uploading Electron release distribution to Azure'
+          script/release/uploaders/upload.py --verbose --upload_to_storage
+        else
+          echo 'Uploading Electron release distribution to GitHub releases'
+          script/release/uploaders/upload.py --verbose
+        fi
+    - name: Generate Artifact Key
+      shell: bash
+      run: |
+        if [ "${{ inputs.is-asan }}" = "true" ]; then 
+          ARTIFACT_KEY=${{ inputs.artifact-platform }}_${{ inputs.target-arch }}_asan
+        else
+          ARTIFACT_KEY=${{ inputs.artifact-platform }}_${{ inputs.target-arch }}
+        fi
+        echo "ARTIFACT_KEY=$ARTIFACT_KEY" >> $GITHUB_ENV
+    # The current generated_artifacts_<< artifact.key >> name was taken from CircleCI
+    # to ensure we don't break anything, but we may be able to improve that.
+    - name: Move all Generated Artifacts to Upload Folder ${{ inputs.step-suffix }}
+      shell: bash
+      run: ./src/electron/script/actions/move-artifacts.sh
+    - name: Upload Generated Artifacts ${{ inputs.step-suffix }}
+      uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
+      with:
+        name: generated_artifacts_${{ env.ARTIFACT_KEY }}
+        path: ./generated_artifacts_${{ inputs.artifact-platform }}_${{ inputs.target-arch }}
+    - name: Upload Src Artifacts ${{ inputs.step-suffix }}
+      uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
+      with:
+        name: src_artifacts_${{ env.ARTIFACT_KEY }}
+        path: ./src_artifacts_${{ inputs.artifact-platform }}_${{ inputs.target-arch }}
\ No newline at end of file
diff --git a/.github/actions/checkout/action.yml b/.github/actions/checkout/action.yml
new file mode 100644
index 000000000000..f57d945fc1f4
--- /dev/null
+++ b/.github/actions/checkout/action.yml
@@ -0,0 +1,154 @@
+name: 'Checkout'
+description: 'Checks out Electron and stores it in the AKS Cache'
+inputs:
+  generate-sas-token:
+    description: 'Whether to generate and persist a SAS token for the item in the cache'
+    required: false
+    default: 'false'
+runs:
+  using: "composite"
+  steps:
+  - name: Set GIT_CACHE_PATH to make gclient to use the cache
+    shell: bash
+    run: |
+      echo "GIT_CACHE_PATH=$(pwd)/git-cache" >> $GITHUB_ENV
+  - name: Install Dependencies
+    shell: bash
+    run: |
+      cd src/electron
+      node script/yarn install --frozen-lockfile
+  - name: Get Depot Tools
+    shell: bash
+    run: |
+      git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
+
+      sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
+      # Remove swift-format dep from cipd on macOS until we send a patch upstream.
+      cd depot_tools
+      git apply --3way ../src/electron/.github/workflows/config/gclient.diff
+
+      # Ensure depot_tools does not update.
+      test -d depot_tools && cd depot_tools
+      touch .disable_auto_update
+  - name: Add Depot Tools to PATH
+    shell: bash
+    run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
+  - name: Generate DEPS Hash
+    shell: bash
+    run: |
+      node src/electron/script/generate-deps-hash.js && cat src/electron/.depshash-target
+      echo "DEPSHASH=v1-src-cache-$(shasum src/electron/.depshash | cut -f1 -d' ')" >> $GITHUB_ENV
+  - name: Generate SAS Key
+    if: ${{ inputs.generate-sas-token == 'true' }}
+    shell: bash
+    run: |
+      curl --unix-socket /var/run/sas/sas.sock --fail "http://foo/$DEPSHASH.tar" > sas-token
+  - name: Save SAS Key
+    if: ${{ inputs.generate-sas-token == 'true' }}
+    uses: actions/cache/save@v4
+    with:
+      path: |
+        sas-token
+      key: sas-key-${{ github.run_number }}-${{ github.run_attempt }}
+  - name: Check If Cache Exists
+    id: check-cache
+    shell: bash
+    run: |
+      cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
+      echo "Using cache key: $DEPSHASH"
+      echo "Checking for cache in: $cache_path"
+      if [ ! -f "$cache_path" ]; then
+        echo "cache_exists=false" >> $GITHUB_OUTPUT
+        echo "Cache Does Not Exist for $DEPSHASH"
+      else
+        echo "cache_exists=false" >> $GITHUB_OUTPUT
+        echo "Cache Already Exists for $DEPSHASH, Busting cache.."
+      fi
+  - name: Gclient Sync
+    if: steps.check-cache.outputs.cache_exists == 'false'
+    shell: bash
+    run: |
+      gclient config \
+        --name "src/electron" \
+        --unmanaged \
+        ${GCLIENT_EXTRA_ARGS} \
+        "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY"
+
+      ELECTRON_USE_THREE_WAY_MERGE_FOR_PATCHES=1 gclient sync --with_branch_heads --with_tags -vvvvv
+      if [ "${{ inputs.is-release }}" != "true" ]; then
+        # Re-export all the patches to check if there were changes.
+        python3 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="PatchUp" GIT_COMMITTER_EMAIL="73610968+patchup[bot]@users.noreply.github.com" git commit -m "chore: update patches" --author="PatchUp <73610968+patchup[bot]@users.noreply.github.com>"
+          # 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
+
+  # delete all .git directories under src/ except for
+  # third_party/angle/ and third_party/dawn/ because of build time generation of files
+  # gen/angle/commit.h depends on third_party/angle/.git/HEAD
+  # https://chromium-review.googlesource.com/c/angle/angle/+/2074924
+  # and dawn/common/Version_autogen.h depends on  third_party/dawn/.git/HEAD
+  # https://dawn-review.googlesource.com/c/dawn/+/83901
+  # TODO: maybe better to always leave out */.git/HEAD file for all targets ?
+  - name: Delete .git directories under src to free space
+    if: steps.check-cache.outputs.cache_exists == 'false'
+    shell: bash
+    run: |
+      cd src
+      ( find . -type d -name ".git" -not -path "./third_party/angle/*" -not -path "./third_party/dawn/*" -not -path "./electron/*" ) | xargs rm -rf
+  - name: Minimize Cache Size for Upload
+    if: steps.check-cache.outputs.cache_exists == 'false'
+    shell: bash
+    run: |
+      rm -rf src/android_webview
+      rm -rf src/ios/chrome
+      rm -rf src/third_party/blink/web_tests
+      rm -rf src/third_party/blink/perf_tests
+      rm -rf src/chrome/test/data/xr/webvr_info
+      rm -rf src/third_party/angle/third_party/VK-GL-CTS/src
+      rm -rf src/third_party/swift-toolchain
+      rm -rf src/third_party/swiftshader/tests/regres/testlists
+      rm -rf src/electron
+  - name: Compress Src Directory
+    if: steps.check-cache.outputs.cache_exists == 'false'
+    shell: bash
+    run: |
+      echo "Uncompressed src size: $(du -sh src | cut -f1 -d' ')"
+      tar -cf $DEPSHASH.tar src
+      echo "Compressed src to $(du -sh $DEPSHASH.tar | cut -f1 -d' ')"
+      cp ./$DEPSHASH.tar /mnt/cross-instance-cache/
+  - name: Persist Src Cache
+    if: steps.check-cache.outputs.cache_exists == 'false'
+    shell: bash
+    run: |
+      final_cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
+      echo "Using cache key: $DEPSHASH"
+      echo "Checking path: $final_cache_path"
+      if [ ! -f "$final_cache_path" ]; then
+        echo "Cache key not found"
+        exit 1
+      else
+        echo "Cache key persisted in $final_cache_path"
+      fi
\ No newline at end of file
diff --git a/.github/actions/fix-sync-macos/action.yml b/.github/actions/fix-sync-macos/action.yml
new file mode 100644
index 000000000000..13f54d90a611
--- /dev/null
+++ b/.github/actions/fix-sync-macos/action.yml
@@ -0,0 +1,61 @@
+name: 'Fix Sync macOS'
+description: 'Checks out Electron and stores it in the AKS Cache'
+runs:
+  using: "composite"
+  steps:
+    - name: Fix Sync
+      shell: bash
+      # This step is required to correct for differences between "gclient sync"
+      # on Linux and the expected state on macOS. This requires:
+      # 1. Fixing Clang Install (wrong binary)
+      # 2. Fixing esbuild (wrong binary)
+      # 3. Fixing rustc (wrong binary)
+      # 4. Fixing gn (wrong binary)
+      # 5. Fix reclient (wrong binary)
+      # 6. Fixing dsymutil (wrong binary)
+      # 7. Ensuring we are using the correct ninja and adding it to PATH
+      # 8. Fixing angle (wrong remote)
+      run : |
+        SEDOPTION="-i ''"
+        rm -rf src/third_party/llvm-build
+        python3 src/tools/clang/scripts/update.py
+
+        echo 'infra/3pp/tools/esbuild/${platform}' `gclient getdep --deps-file=src/third_party/devtools-frontend/src/DEPS -r 'third_party/esbuild:infra/3pp/tools/esbuild/${platform}'` > esbuild_ensure_file
+        # Remove extra output from calling gclient getdep which always calls update_depot_tools
+        sed -i '' "s/Updating depot_tools... //g" esbuild_ensure_file
+        cipd ensure --root src/third_party/devtools-frontend/src/third_party/esbuild -ensure-file esbuild_ensure_file
+
+        rm -rf src/third_party/rust-toolchain
+        python3 src/tools/rust/update_rust.py
+        
+        # Prevent calling gclient getdep which always calls update_depot_tools
+        echo 'gn/gn/mac-${arch}' `gclient getdep --deps-file=src/DEPS -r 'src/buildtools/mac:gn/gn/mac-${arch}'` > gn_ensure_file
+        sed -i '' "s/Updating depot_tools... //g" gn_ensure_file
+        cipd ensure --root src/buildtools/mac -ensure-file gn_ensure_file
+
+        # Prevent calling gclient getdep which always calls update_depot_tools
+        echo 'infra/rbe/client/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/buildtools/reclient:infra/rbe/client/${platform}'` > gn_ensure_file
+        sed -i '' "s/Updating depot_tools... //g" gn_ensure_file
+        cipd ensure --root src/buildtools/reclient -ensure-file gn_ensure_file
+        python3 src/buildtools/reclient_cfgs/configure_reclient_cfgs.py --rbe_instance "projects/rbe-chrome-untrusted/instances/default_instance" --reproxy_cfg_template reproxy.cfg.template --rewrapper_cfg_project "" --skip_remoteexec_cfg_fetch
+
+        if  [ "${{ env.TARGET_ARCH }}" == "arm64" ]; then
+          DSYM_SHA_FILE=src/tools/clang/dsymutil/bin/dsymutil.arm64.sha1
+        else
+          DSYM_SHA_FILE=src/tools/clang/dsymutil/bin/dsymutil.x64.sha1
+        fi
+        python3 src/third_party/depot_tools/download_from_google_storage.py --no_resume --no_auth --bucket chromium-browser-clang -s $DSYM_SHA_FILE -o src/tools/clang/dsymutil/bin/dsymutil
+
+        echo 'infra/3pp/tools/ninja/${platform}' `gclient getdep --deps-file=src/DEPS -r 'src/third_party/ninja:infra/3pp/tools/ninja/${platform}'` > ninja_ensure_file
+        sed $SEDOPTION "s/Updating depot_tools... //g" ninja_ensure_file
+        cipd ensure --root src/third_party/ninja -ensure-file ninja_ensure_file
+
+        echo "$(pwd)/src/third_party/ninja" >> $GITHUB_PATH
+
+        cd src/third_party/angle
+        rm -f .git/objects/info/alternates
+        git remote set-url origin https://chromium.googlesource.com/angle/angle.git
+        cp .git/config .git/config.backup
+        git remote remove origin
+        mv .git/config.backup .git/config
+        git fetch
\ No newline at end of file
diff --git a/.github/actions/free-space-macos/action.yml b/.github/actions/free-space-macos/action.yml
new file mode 100644
index 000000000000..75350ca796ba
--- /dev/null
+++ b/.github/actions/free-space-macos/action.yml
@@ -0,0 +1,65 @@
+name: 'Free Space macOS'
+description: 'Checks out Electron and stores it in the AKS Cache'
+runs:
+  using: "composite"
+  steps:
+    - name: Free Space on MacOS
+      shell: bash
+      run: |
+        sudo mkdir -p $TMPDIR/del-target
+
+        tmpify() {
+          if [ -d "$1" ]; then
+            sudo mv "$1" $TMPDIR/del-target/$(echo $1|shasum -a 256|head -n1|cut -d " " -f1)
+          fi
+        }
+
+        strip_universal_deep() {
+          opwd=$(pwd)
+          cd $1
+          f=$(find . -perm +111 -type f)
+          for fp in $f
+          do
+            if [[ $(file "$fp") == *"universal binary"* ]]; then
+              if [ "`arch`" == "arm64" ]; then
+                if [[ $(file "$fp") == *"x86_64"* ]]; then
+                  sudo lipo -remove x86_64 "$fp" -o "$fp" || true
+                fi
+              else
+                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
+            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
+
+        sudo rm -rf /Applications/Safari.app
+        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_universal_deep $(xcode-select -p)/../SharedFrameworks
+        # strip_arm_deep /System/Volumes/Data/Library/Developer/CommandLineTools/usr
\ No newline at end of file
diff --git a/.github/actions/install-build-tools/action.yml b/.github/actions/install-build-tools/action.yml
new file mode 100644
index 000000000000..cc2050f53252
--- /dev/null
+++ b/.github/actions/install-build-tools/action.yml
@@ -0,0 +1,11 @@
+name: 'Install Build Tools'
+description: 'Installs an exact SHA of build tools'
+runs:
+  using: "composite"
+  steps:
+  - name: Install Build Tools
+    shell: bash
+    run: |
+      export BUILD_TOOLS_SHA=ff3e40a9a2ebb735c18b6450ecd5ddaa8bb364a9
+      npm i -g @electron/build-tools
+      e auto-update disable
\ No newline at end of file
diff --git a/.github/actions/restore-cache-aks/action.yml b/.github/actions/restore-cache-aks/action.yml
new file mode 100644
index 000000000000..6dbcd290d805
--- /dev/null
+++ b/.github/actions/restore-cache-aks/action.yml
@@ -0,0 +1,36 @@
+name: 'Restore Cache AKS'
+description: 'Restores Electron src cache via AKS'
+runs:
+  using: "composite"
+  steps:
+  - name: Restore and Ensure Src Cache
+    shell: bash
+    run: |
+      cache_path=/mnt/cross-instance-cache/$DEPSHASH.tar
+      echo "Using cache key: $DEPSHASH"
+      echo "Checking for cache in: $cache_path"
+      if [ ! -f "$cache_path" ]; then
+        echo "Cache Does Not Exist for $DEPSHASH - exiting"
+        exit 1
+      else
+        echo "Found Cache for $DEPSHASH at $cache_path"
+      fi
+
+      echo "Persisted cache is $(du -sh $cache_path | cut -f1)"
+      mkdir temp-cache
+      tar -xf $cache_path -C temp-cache
+      echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"
+
+      if [ -d "temp-cache/src" ]; then
+        echo "Relocating Cache"
+        rm -rf src
+        mv temp-cache/src src
+      fi
+
+      if [ ! -d "src/third_party/blink" ]; then
+        echo "Cache was not correctly restored - exiting"
+        exit 1
+      fi
+
+      echo "Wiping Electron Directory"
+      rm -rf src/electron
\ No newline at end of file
diff --git a/.github/actions/restore-cache-azcopy/action.yml b/.github/actions/restore-cache-azcopy/action.yml
new file mode 100644
index 000000000000..643585272a1a
--- /dev/null
+++ b/.github/actions/restore-cache-azcopy/action.yml
@@ -0,0 +1,63 @@
+name: 'Restore Cache AZCopy'
+description: 'Restores Electron src cache via AZCopy'
+runs:
+  using: "composite"
+  steps:
+  - name: Obtain SAS Key
+    continue-on-error: true
+    uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
+    with:
+      path: |
+        sas-token
+      key: sas-key-${{ github.run_number }}-1
+  - name: Obtain SAS Key
+    continue-on-error: true
+    uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
+    with:
+      path: |
+        sas-token
+      key: sas-key-${{ github.run_number }}-${{ github.run_attempt }}
+  - name: Download Src Cache from AKS
+    # The cache will always exist here as a result of the checkout job
+    # Either it was uploaded to Azure in the checkout job for this commit
+    # or it was uploaded in the checkout job for a previous commit.
+    uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e # v3.0.0
+    with:
+      timeout_minutes: 20
+      max_attempts: 3
+      retry_on: error
+      command: |
+        sas_token=$(cat sas-token)
+        if [ -z $sas-token ]; then
+          echo "SAS Token not found; exiting src cache download early..."
+          exit 1
+        fi
+        azcopy copy \
+          "https://${{ env.AZURE_AKS_CACHE_STORAGE_ACCOUNT }}.file.core.windows.net/${{ env.AZURE_AKS_CACHE_SHARE_NAME }}/${{ env.CACHE_PATH }}?$sas_token" $DEPSHASH.tar
+  - name: Clean SAS Key
+    shell: bash
+    run: rm -f sas-token
+  - name: Unzip and Ensure Src Cache
+    shell: bash
+    run: |
+      echo "Downloaded cache is $(du -sh $DEPSHASH.tar | cut -f1)"
+      mkdir temp-cache
+      tar -xf $DEPSHASH.tar -C temp-cache
+      echo "Unzipped cache is $(du -sh temp-cache/src | cut -f1)"
+
+      if [ -d "temp-cache/src" ]; then
+        echo "Relocating Cache"
+        rm -rf src
+        mv temp-cache/src src
+
+        echo "Deleting zip file"
+        rm -rf $DEPSHASH.tar
+      fi
+
+      if [ ! -d "src/third_party/blink" ]; then
+        echo "Cache was not correctly restored - exiting"
+        exit 1
+      fi
+
+      echo "Wiping Electron Directory"
+      rm -rf src/electron
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 000000000000..515ee83c895b
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,245 @@
+name: Build
+
+on:
+  workflow_dispatch:
+    inputs:
+      build-image-sha:
+        type: string
+        description: 'SHA for electron/build image'
+        default: 'cf814a4d2501e8e843caea071a6b70a48e78b855'
+        required: true
+      skip-macos:
+        type: boolean
+        description: 'Skip macOS builds'
+        default: false
+        required: false
+      skip-linux:
+        type: boolean
+        description: 'Skip Linux builds'
+        default: false
+        required: false
+      skip-lint:
+        type: boolean
+        description: 'Skip lint check'
+        default: false
+        required: false
+  push:
+    branches:
+      - main
+      - '[1-9][0-9]-x-y'
+  pull_request:
+      
+jobs:
+  setup:
+    runs-on: ubuntu-latest
+    permissions:
+      pull-requests: read
+    outputs:
+        docs: ${{ steps.filter.outputs.docs }}
+        src: ${{ steps.filter.outputs.src }}
+        build-image-sha: ${{ steps.set-output.outputs.build-image-sha }}
+        docs-only: ${{ steps.set-output.outputs.docs-only }}
+    steps:
+    - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.0.2
+    - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
+      id: filter
+      with:
+        filters: |
+          docs:
+            - 'docs/**'
+          src:
+            - '!docs/**'
+    - name: Set Outputs for Build Image SHA & Docs Only
+      id: set-output
+      run: |
+        if [ -z "${{ inputs.build-image-sha }}" ]; then
+          echo "build-image-sha=cf814a4d2501e8e843caea071a6b70a48e78b855" >> "$GITHUB_OUTPUT"
+        else
+          echo "build-image-sha=${{ inputs.build-image-sha }}" >> "$GITHUB_OUTPUT"
+        fi
+        echo "docs-only=${{ steps.filter.outputs.docs == 'true' && steps.filter.outputs.src == 'false' }}" >> "$GITHUB_OUTPUT"
+
+  # Lint Jobs
+  lint:
+    needs: setup
+    if: ${{ !inputs.skip-lint }}
+    uses: ./.github/workflows/pipeline-electron-lint.yml
+    with:
+      container: '{"image":"ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}","options":"--user root"}'
+    secrets: inherit
+
+  # Docs Only Jobs
+  docs-only:
+    needs: setup
+    if: ${{ needs.setup.outputs.docs-only == 'true' }}
+    uses: ./.github/workflows/pipeline-electron-docs-only.yml
+    with:
+      container: '{"image":"ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}","options":"--user root"}'
+    secrets: inherit
+
+  # Checkout Jobs
+  checkout-macos:
+    needs: setup
+    if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-macos}}
+    runs-on: aks-linux-large
+    container:
+      image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
+      options: --user root
+      volumes:
+        - /mnt/cross-instance-cache:/mnt/cross-instance-cache
+        - /var/run/sas:/var/run/sas
+    env:
+      GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
+    outputs:
+      build-image-sha: ${{ needs.setup.outputs.build-image-sha }}
+    steps:
+    - name: Checkout Electron
+      uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
+      with:
+        path: src/electron
+        fetch-depth: 0
+    - name: Checkout & Sync & Save
+      uses: ./src/electron/.github/actions/checkout
+      with:
+        generate-sas-token: 'true'
+
+  checkout-linux:
+    needs: setup
+    if: ${{ needs.setup.outputs.src == 'true' && !inputs.skip-linux}}
+    runs-on: aks-linux-large
+    container:
+      image: ghcr.io/electron/build:${{ needs.setup.outputs.build-image-sha }}
+      options: --user root
+      volumes:
+        - /mnt/cross-instance-cache:/mnt/cross-instance-cache
+        - /var/run/sas:/var/run/sas
+    env:
+      GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
+    outputs:
+      build-image-sha: ${{ needs.setup.outputs.build-image-sha}}
+    steps:
+    - name: Checkout Electron
+      uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
+      with:
+        path: src/electron
+        fetch-depth: 0
+    - name: Checkout & Sync & Save
+      uses: ./src/electron/.github/actions/checkout
+
+  # Build Jobs - These cascade into testing jobs
+  macos-x64:
+    permissions:
+      contents: read
+      issues: read
+      pull-requests: read
+    uses: ./.github/workflows/pipeline-electron-build-and-test.yml
+    needs: checkout-macos
+    with:
+      build-runs-on: macos-14-xlarge
+      test-runs-on: macos-13
+      target-platform: macos
+      target-arch: x64
+      is-release: false
+      gn-build-type: testing
+      generate-symbols: false
+      upload-to-storage: '0'
+    secrets: inherit
+  
+  macos-arm64:
+    permissions:
+      contents: read
+      issues: read
+      pull-requests: read
+    uses: ./.github/workflows/pipeline-electron-build-and-test.yml
+    needs: checkout-macos
+    with:
+      build-runs-on: macos-14-xlarge
+      test-runs-on: macos-14
+      target-platform: macos
+      target-arch: arm64
+      is-release: false
+      gn-build-type: testing
+      generate-symbols: false
+      upload-to-storage: '0'
+    secrets: inherit
+
+  linux-x64:
+    permissions:
+      contents: read
+      issues: read
+      pull-requests: read
+    uses: ./.github/workflows/pipeline-electron-build-and-test-and-nan.yml
+    needs: checkout-linux
+    with:
+      build-runs-on: aks-linux-large
+      test-runs-on: aks-linux-medium
+      build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
+      test-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
+      target-platform: linux
+      target-arch: x64
+      is-release: false
+      gn-build-type: testing
+      generate-symbols: false
+      upload-to-storage: '0'
+    secrets: inherit
+
+  linux-x64-asan:
+    permissions:
+      contents: read
+      issues: read
+      pull-requests: read
+    uses: ./.github/workflows/pipeline-electron-build-and-test.yml
+    needs: checkout-linux
+    with:
+      build-runs-on: aks-linux-large
+      test-runs-on: aks-linux-medium
+      build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
+      test-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
+      target-platform: linux
+      target-arch: x64
+      is-release: false
+      gn-build-type: testing
+      generate-symbols: false
+      upload-to-storage: '0'
+      is-asan: true
+    secrets: inherit
+  
+  linux-arm:
+    permissions:
+      contents: read
+      issues: read
+      pull-requests: read
+    uses: ./.github/workflows/pipeline-electron-build-and-test.yml
+    needs: checkout-linux
+    with:
+      build-runs-on: aks-linux-large
+      test-runs-on: aks-linux-arm-medium
+      build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
+      test-container: '{"image":"ghcr.io/electron/test:arm32v7-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init","volumes":["/home/runner/externals:/mnt/runner-externals"]}'
+      target-platform: linux
+      target-arch: arm
+      is-release: false
+      gn-build-type: testing
+      generate-symbols: false
+      upload-to-storage: '0'
+    secrets: inherit
+  
+  linux-arm64:
+    permissions:
+      contents: read
+      issues: read
+      pull-requests: read
+    uses: ./.github/workflows/pipeline-electron-build-and-test.yml
+    needs: checkout-linux
+    with:
+      build-runs-on: aks-linux-large
+      test-runs-on: aks-linux-arm-medium
+      build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
+      test-container: '{"image":"ghcr.io/electron/test:arm64v8-${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}'
+      target-platform: linux
+      target-arch: arm64
+      is-release: false
+      gn-build-type: testing
+      generate-symbols: false
+      upload-to-storage: '0'
+    secrets: inherit
\ No newline at end of file
diff --git a/.github/workflows/config/gclient.diff b/.github/workflows/config/gclient.diff
new file mode 100644
index 000000000000..4a035b8c991f
--- /dev/null
+++ b/.github/workflows/config/gclient.diff
@@ -0,0 +1,14 @@
+diff --git a/gclient.py b/gclient.py
+index 59e2b4c5197928bdba1ef69bdbe637d7dfe471c1..b4bae5e48c83c84bd867187afaf40eed16e69851 100755
+--- a/gclient.py
++++ b/gclient.py
+@@ -783,7 +783,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
+                         not condition or "non_git_source" not in condition):
+                     continue
+                 cipd_root = self.GetCipdRoot()
+-                for package in dep_value.get('packages', []):
++                packages = dep_value.get('packages', [])
++                for package in (x for x in packages if "infra/3pp/tools/swift-format" not in x.get('package')):
+                     deps_to_add.append(
+                         CipdDependency(parent=self,
+                                        name=name,
diff --git a/.github/workflows/linux-publish.yml b/.github/workflows/linux-publish.yml
new file mode 100644
index 000000000000..14eedbdd0891
--- /dev/null
+++ b/.github/workflows/linux-publish.yml
@@ -0,0 +1,83 @@
+name: Publish Linux
+
+on:
+  workflow_dispatch:
+    inputs:
+      build-image-sha:
+        type: string
+        description: 'SHA for electron/build image'
+        default: 'cf814a4d2501e8e843caea071a6b70a48e78b855'
+      upload-to-storage:
+        description: 'Uploads to Azure storage'
+        required: false
+        default: '1'
+        type: string
+      run-linux-publish:
+        description: 'Run the publish jobs vs just the build jobs'
+        type: boolean
+        default: false
+
+jobs:
+  checkout-linux:
+    runs-on: aks-linux-large
+    container:
+      image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
+      options: --user root
+      volumes:
+        - /mnt/cross-instance-cache:/mnt/cross-instance-cache
+        - /var/run/sas:/var/run/sas
+    env:
+      GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
+    steps:
+    - name: Checkout Electron
+      uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
+      with:
+        path: src/electron
+        fetch-depth: 0
+    - name: Checkout & Sync & Save
+      uses: ./src/electron/.github/actions/checkout
+
+  publish-x64:
+    uses: ./.github/workflows/pipeline-segment-electron-build.yml
+    needs: checkout-linux
+    with:
+      environment: production-release
+      build-runs-on: aks-linux-large
+      build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
+      target-platform: linux
+      target-arch: x64
+      is-release: true
+      gn-build-type: release
+      generate-symbols: true
+      upload-to-storage: ${{ inputs.upload-to-storage }}
+    secrets: inherit
+
+  publish-arm:
+    uses: ./.github/workflows/pipeline-segment-electron-build.yml
+    needs: checkout-linux
+    with:
+      environment: production-release
+      build-runs-on: aks-linux-large
+      build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
+      target-platform: linux
+      target-arch: arm
+      is-release: true
+      gn-build-type: release
+      generate-symbols: true
+      upload-to-storage: ${{ inputs.upload-to-storage }}
+    secrets: inherit
+
+  publish-arm64:
+    uses: ./.github/workflows/pipeline-segment-electron-build.yml
+    needs: checkout-linux
+    with:
+      environment: production-release
+      build-runs-on: aks-linux-large
+      build-container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
+      target-platform: linux
+      target-arch: arm64
+      is-release: true
+      gn-build-type: release
+      generate-symbols: true
+      upload-to-storage: ${{ inputs.upload-to-storage }}
+    secrets: inherit
\ No newline at end of file
diff --git a/.github/workflows/macos-publish.yml b/.github/workflows/macos-publish.yml
new file mode 100644
index 000000000000..274dd6b4bd8f
--- /dev/null
+++ b/.github/workflows/macos-publish.yml
@@ -0,0 +1,69 @@
+name: Publish MacOS
+
+on:
+  workflow_dispatch:
+    inputs:
+      build-image-sha:
+        type: string
+        description: 'SHA for electron/build image'
+        default: 'cf814a4d2501e8e843caea071a6b70a48e78b855'
+        required: true
+      upload-to-storage:
+        description: 'Uploads to Azure storage'
+        required: false
+        default: '1'
+        type: string
+      run-macos-publish:
+        description: 'Run the publish jobs vs just the build jobs'
+        type: boolean
+        default: false
+
+jobs:
+  checkout-macos:
+    runs-on: aks-linux-large
+    container:
+      image: ghcr.io/electron/build:${{ inputs.build-image-sha }}
+      options: --user root
+      volumes:
+        - /mnt/cross-instance-cache:/mnt/cross-instance-cache
+        - /var/run/sas:/var/run/sas
+    env:
+      GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
+    steps:
+    - name: Checkout Electron
+      uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
+      with:
+        path: src/electron
+        fetch-depth: 0
+    - name: Checkout & Sync & Save
+      uses: ./src/electron/.github/actions/checkout
+      with:
+        generate-sas-token: 'true'
+
+  publish-x64:
+    uses: ./.github/workflows/pipeline-segment-electron-build.yml
+    needs: checkout-macos
+    with:
+      environment: production-release
+      build-runs-on: macos-14-xlarge
+      target-platform: macos
+      target-arch: x64
+      is-release: true
+      gn-build-type: release
+      generate-symbols: true
+      upload-to-storage: ${{ inputs.upload-to-storage }}
+    secrets: inherit
+
+  publish-arm64:
+    uses: ./.github/workflows/pipeline-segment-electron-build.yml
+    needs: checkout-macos
+    with:
+      environment: production-release
+      build-runs-on: macos-14-xlarge
+      target-platform: macos
+      target-arch: arm64
+      is-release: true
+      gn-build-type: release
+      generate-symbols: true
+      upload-to-storage: ${{ inputs.upload-to-storage }}
+    secrets: inherit
\ No newline at end of file
diff --git a/.github/workflows/pipeline-electron-build-and-test-and-nan.yml b/.github/workflows/pipeline-electron-build-and-test-and-nan.yml
new file mode 100644
index 000000000000..f6ed1fc70648
--- /dev/null
+++ b/.github/workflows/pipeline-electron-build-and-test-and-nan.yml
@@ -0,0 +1,103 @@
+name: Electron Build & Test (+ Node + NaN) Pipeline
+
+on:
+  workflow_call:
+    inputs:
+      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
+      test-runs-on:
+        type: string
+        description: 'What host to run the tests on'
+        required: true
+      build-container:
+        type: string
+        description: 'JSON container information for aks runs-on'
+        required: false
+        default: '{"image":null}'
+      test-container:
+        type: string
+        description: 'JSON container information for testing'
+        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'
+      is-asan: 
+        description: 'Building the Address Sanitizer (ASan) Linux build'
+        required: false
+        type: boolean
+        default: false
+
+concurrency:
+  group: electron-build-and-test-and-nan-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }}
+  cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
+
+jobs:
+  build:
+    uses: ./.github/workflows/pipeline-segment-electron-build.yml
+    with:
+      build-runs-on: ${{ inputs.build-runs-on }}
+      build-container: ${{ inputs.build-container }}
+      target-platform: ${{ inputs.target-platform }}
+      target-arch: ${{ inputs.target-arch }}
+      is-release: ${{ inputs.is-release }}
+      gn-build-type: ${{ inputs.gn-build-type }}
+      generate-symbols: ${{ inputs.generate-symbols }}
+      upload-to-storage: ${{ inputs.upload-to-storage }}
+    secrets: inherit
+  gn-check:
+    uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
+    with:
+      target-platform: ${{ inputs.target-platform }}
+      target-arch: ${{ inputs.target-arch }}
+      check-runs-on: ${{ inputs.build-runs-on }}
+      check-container: ${{ inputs.build-container }}
+      gn-build-type: ${{ inputs.gn-build-type }}
+      is-asan: ${{ inputs.is-asan }}
+    secrets: inherit
+  test:
+    uses: ./.github/workflows/pipeline-segment-electron-test.yml
+    needs: build
+    with:
+      target-arch: ${{ inputs.target-arch }}
+      target-platform: ${{ inputs.target-platform }}
+      test-runs-on: ${{ inputs.test-runs-on }}
+      test-container: ${{ inputs.test-container }}
+    secrets: inherit
+  nn-test:
+    uses: ./.github/workflows/pipeline-segment-node-nan-test.yml
+    needs: build
+    with:
+      target-arch: ${{ inputs.target-arch }}
+      target-platform: ${{ inputs.target-platform }}
+      test-runs-on: ${{ inputs.test-runs-on }}
+      test-container: ${{ inputs.test-container }}
+      gn-build-type: ${{ inputs.gn-build-type }}
+    secrets: inherit
\ No newline at end of file
diff --git a/.github/workflows/pipeline-electron-build-and-test.yml b/.github/workflows/pipeline-electron-build-and-test.yml
new file mode 100644
index 000000000000..5501910ddd13
--- /dev/null
+++ b/.github/workflows/pipeline-electron-build-and-test.yml
@@ -0,0 +1,100 @@
+name: Electron Build & Test Pipeline
+
+on:
+  workflow_call:
+    inputs:
+      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
+      test-runs-on:
+        type: string
+        description: 'What host to run the tests on'
+        required: true
+      build-container:
+        type: string
+        description: 'JSON container information for aks runs-on'
+        required: false
+        default: '{"image":null}'
+      test-container:
+        type: string
+        description: 'JSON container information for testing'
+        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'
+      is-asan: 
+        description: 'Building the Address Sanitizer (ASan) Linux build'
+        required: false
+        type: boolean
+        default: false
+
+concurrency:
+  group: electron-build-and-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }}
+  cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
+
+permissions:
+  contents: read
+  issues: read
+  pull-requests: read  
+
+jobs:
+  build:
+    uses: ./.github/workflows/pipeline-segment-electron-build.yml
+    with:
+      build-runs-on: ${{ inputs.build-runs-on }}
+      build-container: ${{ inputs.build-container }}
+      target-platform: ${{ inputs.target-platform }}
+      target-arch: ${{ inputs.target-arch }}
+      is-release: ${{ inputs.is-release }}
+      gn-build-type: ${{ inputs.gn-build-type }}
+      generate-symbols: ${{ inputs.generate-symbols }}
+      upload-to-storage: ${{ inputs.upload-to-storage }}
+      is-asan: ${{ inputs.is-asan}}
+    secrets: inherit
+  gn-check:
+    uses: ./.github/workflows/pipeline-segment-electron-gn-check.yml
+    with:
+      target-platform: ${{ inputs.target-platform }}
+      target-arch: ${{ inputs.target-arch }}
+      check-runs-on: ${{ inputs.build-runs-on }}
+      check-container: ${{ inputs.build-container }}
+      gn-build-type: ${{ inputs.gn-build-type }}
+      is-asan: ${{ inputs.is-asan }}
+    secrets: inherit
+  test:
+    uses: ./.github/workflows/pipeline-segment-electron-test.yml
+    needs: build
+    with:
+      target-arch: ${{ inputs.target-arch }}
+      target-platform: ${{ inputs.target-platform }}
+      test-runs-on: ${{ inputs.test-runs-on }}
+      test-container: ${{ inputs.test-container }}
+      is-asan: ${{ inputs.is-asan}}
+    secrets: inherit
\ No newline at end of file
diff --git a/.github/workflows/pipeline-electron-docs-only.yml b/.github/workflows/pipeline-electron-docs-only.yml
new file mode 100644
index 000000000000..a4971b9babaa
--- /dev/null
+++ b/.github/workflows/pipeline-electron-docs-only.yml
@@ -0,0 +1,43 @@
+name: Electron Docs Compile
+
+on:
+  workflow_call:
+    inputs:
+      container:
+        required: true
+        description: 'Container to run the docs-only ts compile in'
+        type: string
+
+concurrency:
+  group: electron-docs-only-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  docs-only:
+    name: Docs Only Compile
+    runs-on: aks-linux-medium
+    timeout-minutes: 20
+    container: ${{ fromJSON(inputs.container) }}
+    steps:
+    - name: Checkout Electron
+      uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
+      with:
+        path: src/electron
+        fetch-depth: 0
+    - name: Install Dependencies
+      run: |
+        cd src/electron
+        node script/yarn install --frozen-lockfile
+    - name: Run TS/JS compile
+      shell: bash
+      run: |
+        cd src/electron
+        node script/yarn create-typescript-definitions
+        node script/yarn tsc -p tsconfig.default_app.json --noEmit
+        for f in build/webpack/*.js
+        do
+            out="${f:29}"
+            if [ "$out" != "base.js" ]; then
+            node script/yarn webpack --config $f --output-filename=$out --output-path=./.tmp --env mode=development
+            fi
+        done
\ No newline at end of file
diff --git a/.github/workflows/pipeline-electron-lint.yml b/.github/workflows/pipeline-electron-lint.yml
new file mode 100644
index 000000000000..c104a2aa9c75
--- /dev/null
+++ b/.github/workflows/pipeline-electron-lint.yml
@@ -0,0 +1,77 @@
+name: Electron Lint
+
+on:
+  workflow_call:
+    inputs:
+      container:
+        required: true
+        description: 'Container to run lint in'
+        type: string
+
+concurrency:
+  group: electron-lint-${{ github.ref }}
+  cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
+
+jobs:
+  lint:
+    name: Lint
+    runs-on: aks-linux-medium
+    timeout-minutes: 20
+    container: ${{ fromJSON(inputs.container) }}
+    steps:
+    - name: Checkout Electron
+      uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
+      with:
+        path: src/electron
+        fetch-depth: 0
+    - name: Install Dependencies
+      run: |
+        cd src/electron
+        node script/yarn install --frozen-lockfile
+    - name: Setup third_party Depot Tools
+      shell: bash
+      run: |
+        # "depot_tools" has to be checkout into "//third_party/depot_tools" so pylint.py can a "pylintrc" file.
+        git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git src/third_party/depot_tools
+        echo "$(pwd)/src/third_party/depot_tools" >> $GITHUB_PATH
+    - name: Download GN Binary
+      shell: bash
+      run: |
+        chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
+        gn_version="$(curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/DEPS?format=TEXT" | base64 -d | grep gn_version | head -n1 | cut -d\' -f4)"
+
+        cipd ensure -ensure-file - -root . <<-CIPD
+        \$ServiceURL https://chrome-infra-packages.appspot.com/
+        @Subdir src/buildtools/linux64
+        gn/gn/linux-amd64 $gn_version
+        CIPD
+
+        buildtools_path="$(pwd)/src/buildtools"
+        echo "CHROMIUM_BUILDTOOLS_PATH=$buildtools_path" >> $GITHUB_ENV
+    - name: Download clang-format Binary
+      shell: bash
+      run: |
+        chromium_revision="$(grep -A1 chromium_version src/electron/DEPS | tr -d '\n' | cut -d\' -f4)"
+
+        sha1_path='buildtools/linux64/clang-format.sha1'
+        curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/${sha1_path}?format=TEXT" | base64 -d > "src/${sha1_path}"
+
+        download_from_google_storage.py --no_resume --no_auth --bucket chromium-clang-format -s "src/${sha1_path}"
+    - name: Run Lint
+      shell: bash
+      run: |
+        # gn.py tries to find a gclient root folder starting from the current dir.
+        # When it fails and returns "None" path, the whole script fails. Let's "fix" it.
+        touch .gclient
+        # Another option would be to checkout "buildtools" inside the Electron checkout,
+        # but then we would lint its contents (at least gn format), and it doesn't pass it.
+
+        cd src/electron
+        node script/yarn install --frozen-lockfile
+        node script/yarn lint
+    - name: Run Script Typechecker
+      shell: bash
+      run: |
+        cd src/electron
+        node script/yarn tsc -p tsconfig.script.json
+    
\ No newline at end of file
diff --git a/.github/workflows/pipeline-segment-electron-build.yml b/.github/workflows/pipeline-segment-electron-build.yml
new file mode 100644
index 000000000000..839ed923f172
--- /dev/null
+++ b/.github/workflows/pipeline-segment-electron-build.yml
@@ -0,0 +1,207 @@
+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'
+      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:
+  AZURE_AKS_CACHE_STORAGE_ACCOUNT: ${{ secrets.AZURE_AKS_CACHE_STORAGE_ACCOUNT }}
+  AZURE_AKS_CACHE_SHARE_NAME: ${{ secrets.AZURE_AKS_CACHE_SHARE_NAME }}
+  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 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 (macOS)
+      if: ${{ inputs.target-platform == 'macos' }}
+      uses: ./src/electron/.github/actions/fix-sync-macos
+    - 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 }}'
+        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)'
\ No newline at end of file
diff --git a/.github/workflows/pipeline-segment-electron-gn-check.yml b/.github/workflows/pipeline-segment-electron-gn-check.yml
new file mode 100644
index 000000000000..101a9656670f
--- /dev/null
+++ b/.github/workflows/pipeline-segment-electron-gn-check.yml
@@ -0,0 +1,143 @@
+name: Pipeline Segment - Electron GN Check
+
+on:
+  workflow_call:
+    inputs:
+      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
+      check-runs-on:
+        type: string
+        description: 'What host to run the tests on'
+        required: true
+      check-container:
+        type: string
+        description: 'JSON container information for aks runs-on'
+        required: false
+        default: '{"image":null}'
+      gn-build-type:
+        description: 'The gn build type - testing or release'
+        required: true
+        type: string
+        default: testing
+      is-asan: 
+        description: 'Building the Address Sanitizer (ASan) Linux build'
+        required: false
+        type: boolean
+        default: false
+
+concurrency:
+  group: electron-gn-check-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref }}
+  cancel-in-progress: true
+
+env:
+  AZURE_AKS_CACHE_STORAGE_ACCOUNT: ${{ secrets.AZURE_AKS_CACHE_STORAGE_ACCOUNT }}
+  AZURE_AKS_CACHE_SHARE_NAME: ${{ secrets.AZURE_AKS_CACHE_SHARE_NAME }}
+  ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
+  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
+  TARGET_ARCH: ${{ inputs.target-arch }}
+
+jobs:
+  gn-check:
+    # TODO(codebytere): Change this to medium VM
+    runs-on: ${{ inputs.check-runs-on }}
+    container: ${{ fromJSON(inputs.check-container) }}
+    env:
+      TARGET_ARCH: ${{ inputs.target-arch }}
+    steps:
+    - 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: 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: Set GN_EXTRA_ARGS for Linux
+      if: ${{ inputs.target-platform == 'linux' }}
+      run: |
+        if [ "${{ inputs.target-arch  }}" = "arm" ]; then
+          GN_EXTRA_ARGS='build_tflite_with_xnnpack=false'
+        elif [ "${{ inputs.target-arch }}" = "arm64" ]; then
+          GN_EXTRA_ARGS='fatal_linker_warnings=false enable_linux_installer=false'
+        fi
+        echo "GN_EXTRA_ARGS=$GN_EXTRA_ARGS" >> $GITHUB_ENV
+    - 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: 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: Checkout Electron
+      uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
+      with:
+        path: src/electron
+        fetch-depth: 0
+    - name: Default GN gen
+      run: |
+        cd src/electron
+        git pack-refs
+        cd ..
+
+        e build --only-gen
+    - name: Run GN Check
+      run: |
+        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
+        node electron/script/gen-libc++-filenames.js --check
+    - name: Wait for active SSH sessions
+      if: always() && !cancelled()
+      run: |
+        while [ -f /var/.ssh-lock ]
+        do
+          sleep 60
+        done
\ No newline at end of file
diff --git a/.github/workflows/pipeline-segment-electron-test.yml b/.github/workflows/pipeline-segment-electron-test.yml
new file mode 100644
index 000000000000..fb9e6780235c
--- /dev/null
+++ b/.github/workflows/pipeline-segment-electron-test.yml
@@ -0,0 +1,196 @@
+name: Pipeline Segment - Electron Test
+
+on:
+  workflow_call:
+    inputs:
+      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
+      test-runs-on:
+        type: string
+        description: 'What host to run the tests on'
+        required: true
+      test-container:
+        type: string
+        description: 'JSON container information for aks runs-on'
+        required: false
+        default: '{"image":null}'
+      is-asan: 
+        description: 'Building the Address Sanitizer (ASan) Linux build'
+        required: false
+        type: boolean
+        default: false
+
+concurrency:
+  group: electron-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ inputs.is-asan }}-${{ github.ref }}
+  cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
+
+permissions:
+  contents: read
+  issues: read
+  pull-requests: read
+
+env:
+  ELECTRON_OUT_DIR: Default
+  ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
+  ELECTRON_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+jobs:
+  test:
+    runs-on: ${{ inputs.test-runs-on }}
+    container: ${{ fromJSON(inputs.test-container) }}
+    strategy:
+      fail-fast: false
+      matrix:
+        build-type: ${{ inputs.target-platform == 'macos' && fromJSON('["darwin","mas"]') || fromJSON('["linux"]') }}
+        shard: ${{ inputs.target-platform == 'macos' && fromJSON('[1, 2]') || fromJSON('[1, 2, 3]') }}
+    env:
+      BUILD_TYPE: ${{ matrix.build-type }}
+      TARGET_ARCH: ${{ inputs.target-arch }}
+      ARTIFACT_KEY: ${{ matrix.build-type }}_${{ inputs.target-arch }}
+    steps:
+    - name: Fix node20 on arm32 runners
+      if: ${{ inputs.target-arch == 'arm' }}
+      run: |
+        cp $(which node) /mnt/runner-externals/node20/bin/
+    - name: Add TCC permissions on macOS
+      if: ${{ inputs.target-platform == 'macos' }}
+      run: |
+        configure_user_tccdb () {
+          local values=$1
+          local dbPath="$HOME/Library/Application Support/com.apple.TCC/TCC.db"
+          local sqlQuery="INSERT OR REPLACE INTO access VALUES($values);"
+          sqlite3 "$dbPath" "$sqlQuery"
+        }
+
+        configure_sys_tccdb () {
+          local values=$1
+          local dbPath="/Library/Application Support/com.apple.TCC/TCC.db"
+          local sqlQuery="INSERT OR REPLACE INTO access VALUES($values);"
+          sudo sqlite3 "$dbPath" "$sqlQuery"
+        }
+
+        userValuesArray=(
+            "'kTCCServiceMicrophone','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
+            "'kTCCServiceCamera','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
+            "'kTCCServiceBluetoothAlways','/usr/local/opt/runner/provisioner/provisioner',1,2,4,1,NULL,NULL,0,'UNUSED',NULL,0,1687786159"
+        )
+        for values in "${userValuesArray[@]}"; do
+          # Sonoma and higher have a few extra values
+          # Ref: https://github.com/actions/runner-images/blob/main/images/macos/scripts/build/configure-tccdb-macos.sh
+          if [ "$OSTYPE" = "darwin23" ]; then
+            configure_user_tccdb "$values,NULL,NULL,'UNUSED',${values##*,}"
+            configure_sys_tccdb "$values,NULL,NULL,'UNUSED',${values##*,}"
+          else
+            configure_user_tccdb "$values"
+            configure_sys_tccdb "$values"
+          fi
+        done
+    - name: Checkout Electron
+      uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
+      with:
+        path: src/electron
+        fetch-depth: 0
+    - name: Install Dependencies
+      run: |
+        cd src/electron
+        node script/yarn install --frozen-lockfile
+    - name: Get Depot Tools
+      timeout-minutes: 5
+      run: |
+        git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
+        if [ "`uname`" = "Darwin" ]; then
+          # remove ninjalog_uploader_wrapper.py from autoninja since we don't use it and it causes problems
+          sed -i '' '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
+        else
+          sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
+          # Remove swift-format dep from cipd on macOS until we send a patch upstream.
+          cd depot_tools
+          git apply --3way ../src/electron/.github/workflows/config/gclient.diff
+        fi
+        # Ensure depot_tools does not update.
+        test -d depot_tools && cd depot_tools
+        touch .disable_auto_update
+    - name: Add Depot Tools to PATH
+      run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
+    - name: Load ASan specific environment variables
+      if: ${{ inputs.is-asan == true }}
+      run: |
+        echo "ARTIFACT_KEY=${{ matrix.build-type }}_${{ inputs.target-arch }}_asan" >> $GITHUB_ENV
+        echo "DISABLE_CRASH_REPORTER_TESTS=true" >> $GITHUB_ENV
+        echo "IS_ASAN=true" >> $GITHUB_ENV
+    - name: Download Generated Artifacts
+      uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
+      with:
+        name: generated_artifacts_${{ env.ARTIFACT_KEY }}
+        path: ./generated_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }}
+    - name: Download Src Artifacts
+      uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
+      with:
+        name: src_artifacts_${{ env.ARTIFACT_KEY }}
+        path: ./src_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }}
+    - name: Restore Generated Artifacts
+      run: ./src/electron/script/actions/restore-artifacts.sh
+    - name: Unzip Dist, Mksnapshot & Chromedriver
+      run: |
+        cd src/out/Default
+        unzip -:o dist.zip
+        unzip -:o chromedriver.zip
+        unzip -:o mksnapshot.zip
+    - name: Import & Trust Self-Signed Codesigning Cert on MacOS
+      if: ${{ inputs.target-platform == 'macos' && inputs.target-arch == 'x64' }}
+      run: |
+        sudo security authorizationdb write com.apple.trust-settings.admin allow
+        cd src/electron
+        ./script/codesign/generate-identity.sh
+    - name: Run Electron Tests
+      shell: bash
+      env:
+        MOCHA_REPORTER: mocha-multi-reporters
+        ELECTRON_TEST_RESULTS_DIR: junit
+        MOCHA_MULTI_REPORTERS: mocha-junit-reporter, tap
+        ELECTRON_DISABLE_SECURITY_WARNINGS: 1
+        ELECTRON_SKIP_NATIVE_MODULE_TESTS: true
+        DISPLAY: ':99.0'
+      run: |
+        cd src/electron
+        # Get which tests are on this shard
+        tests_files=$(node script/split-tests ${{ matrix.shard }} ${{ inputs.target-platform == 'macos' && 2 || 3 }})
+
+        # Run tests
+        if [ "`uname`" = "Darwin" ]; then
+          echo "About to start tests"
+          node script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files
+        else
+          chown :builduser .. && chmod g+w ..
+          chown -R :builduser . && chmod -R g+w .
+          chmod 4755 ../out/Default/chrome-sandbox
+          runuser -u builduser -- git config --global --add safe.directory $(pwd)
+          if [ "${{ inputs.is-asan }}" == "true" ]; then
+            cd ..
+            ASAN_SYMBOLIZE="$PWD/tools/valgrind/asan/asan_symbolize.py --executable-path=$PWD/out/Default/electron"
+            export ASAN_OPTIONS="symbolize=0 handle_abort=1"
+            export G_SLICE=always-malloc
+            export NSS_DISABLE_ARENA_FREE_LIST=1
+            export NSS_DISABLE_UNLOAD=1
+            export LLVM_SYMBOLIZER_PATH=$PWD/third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer
+            export MOCHA_TIMEOUT=180000
+            echo "Piping output to ASAN_SYMBOLIZE ($ASAN_SYMBOLIZE)"
+            cd electron
+            runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files | $ASAN_SYMBOLIZE
+          else
+            runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files
+          fi
+        fi
+    - name: Wait for active SSH sessions
+      if: always() && !cancelled()
+      run: |
+        while [ -f /var/.ssh-lock ]
+        do
+          sleep 60
+        done
\ No newline at end of file
diff --git a/.github/workflows/pipeline-segment-node-nan-test.yml b/.github/workflows/pipeline-segment-node-nan-test.yml
new file mode 100644
index 000000000000..e87759878d4e
--- /dev/null
+++ b/.github/workflows/pipeline-segment-node-nan-test.yml
@@ -0,0 +1,165 @@
+name: Pipeline Segment - Node/Nan Test
+
+on:
+  workflow_call:
+    inputs:
+      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
+      test-runs-on:
+        type: string
+        description: 'What host to run the tests on'
+        required: true
+      test-container:
+        type: string
+        description: 'JSON container information for aks runs-on'
+        required: false
+        default: '{"image":null}'
+      gn-build-type:
+        description: 'The gn build type - testing or release'
+        required: true
+        type: string
+        default: testing
+
+concurrency:
+  group: electron-node-nan-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }}
+  cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !endsWith(github.ref, '-x-y') }}
+
+env:
+  ELECTRON_OUT_DIR: Default
+  ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
+
+jobs:
+  node-tests:
+    name: Run Node.js Tests
+    runs-on: aks-linux-medium-plus
+    timeout-minutes: 20
+    env: 
+      TARGET_ARCH: ${{ inputs.target-arch }}
+      BUILD_TYPE: linux
+    container: ${{ fromJSON(inputs.test-container) }}
+    steps:
+    - 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 }}
+    - name: Install Dependencies
+      run: |
+        cd src/electron
+        node script/yarn install --frozen-lockfile
+    - name: Get Depot Tools
+      timeout-minutes: 5
+      run: |
+        git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
+        sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
+        cd depot_tools
+        git apply --3way ../src/electron/.github/workflows/config/gclient.diff
+        # Ensure depot_tools does not update.
+        test -d depot_tools && cd depot_tools
+        touch .disable_auto_update
+    - name: Add Depot Tools to PATH
+      run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
+    - name: Download Generated Artifacts
+      uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
+      with:
+        name: generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
+        path: ./generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
+    - name: Download Src Artifacts
+      uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
+      with:
+        name: src_artifacts_linux_${{ env.TARGET_ARCH }}
+        path: ./src_artifacts_linux_${{ env.TARGET_ARCH }}
+    - name: Restore Generated Artifacts
+      run: ./src/electron/script/actions/restore-artifacts.sh
+    - name: Unzip Dist
+      run: |
+        cd src/out/Default
+        unzip -:o dist.zip
+    - name: Setup Linux for Headless Testing
+      run: sh -e /etc/init.d/xvfb start
+    - name: Run Node.js Tests
+      run: |
+        cd src
+        node electron/script/node-spec-runner.js --default --jUnitDir=junit
+    - name: Wait for active SSH sessions
+      if: always() && !cancelled()
+      run: |
+        while [ -f /var/.ssh-lock ]
+        do
+          sleep 60
+        done
+  nan-tests:
+    name: Run Nan Tests
+    runs-on: aks-linux-medium
+    timeout-minutes: 20
+    env: 
+      TARGET_ARCH: ${{ inputs.target-arch }}
+      BUILD_TYPE: linux
+    container: ${{ fromJSON(inputs.test-container) }}
+    steps:
+    - 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 }}
+    - name: Install Dependencies
+      run: |
+        cd src/electron
+        node script/yarn install --frozen-lockfile
+    - name: Get Depot Tools
+      timeout-minutes: 5
+      run: |
+        git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git
+        sed -i '/ninjalog_uploader_wrapper.py/d' ./depot_tools/autoninja
+        cd depot_tools
+        git apply --3way ../src/electron/.github/workflows/config/gclient.diff
+        # Ensure depot_tools does not update.
+        test -d depot_tools && cd depot_tools
+        touch .disable_auto_update
+    - name: Add Depot Tools to PATH
+      run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
+    - name: Download Generated Artifacts
+      uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
+      with:
+        name: generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
+        path: ./generated_artifacts_${{ env.BUILD_TYPE }}_${{ env.TARGET_ARCH }}
+    - name: Download Src Artifacts
+      uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
+      with:
+        name: src_artifacts_linux_${{ env.TARGET_ARCH }}
+        path: ./src_artifacts_linux_${{ env.TARGET_ARCH }}
+    - name: Restore Generated Artifacts
+      run: ./src/electron/script/actions/restore-artifacts.sh
+    - name: Unzip Dist
+      run: |
+        cd src/out/Default
+        unzip -:o dist.zip
+    - name: Setup Linux for Headless Testing
+      run: sh -e /etc/init.d/xvfb start
+    - name: Run Node.js Tests
+      run: |
+        cd src
+        node electron/script/nan-spec-runner.js
+    - name: Wait for active SSH sessions
+      if: always() && !cancelled()
+      run: |
+        while [ -f /var/.ssh-lock ]
+        do
+          sleep 60
+        done
\ No newline at end of file
diff --git a/script/actions/move-artifacts.sh b/script/actions/move-artifacts.sh
new file mode 100755
index 000000000000..70c8f75d4c29
--- /dev/null
+++ b/script/actions/move-artifacts.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+
+if [ "`uname`" == "Darwin" ]; then
+  if [ -z "$MAS_BUILD" ]; then
+    BUILD_TYPE="darwin"
+  else
+    BUILD_TYPE="mas"
+  fi
+elif [ "`uname`" == "Linux" ]; then
+  BUILD_TYPE="linux"
+else
+  echo "Unsupported platform"
+  exit 1
+fi
+
+GENERATED_ARTIFACTS="generated_artifacts_${BUILD_TYPE}_${TARGET_ARCH}"
+
+echo Creating $GENERATED_ARTIFACTS...
+rm -rf $GENERATED_ARTIFACTS
+mkdir $GENERATED_ARTIFACTS
+
+SRC_ARTIFACTS="src_artifacts_${BUILD_TYPE}_${TARGET_ARCH}"
+
+echo Creating $SRC_ARTIFACTS...
+rm -rf $SRC_ARTIFACTS
+mkdir $SRC_ARTIFACTS
+
+mv_if_exist() {
+  if [ -f "$1" ] || [ -d "$1" ]; then
+    echo Storing $1
+    mv $1 $GENERATED_ARTIFACTS
+  else
+    echo Skipping $1 - It is not present on disk
+  fi
+}
+
+cp_if_exist() {
+  if [ -f "$1" ] || [ -d "$1" ]; then
+    echo Storing $1
+    cp $1 $GENERATED_ARTIFACTS
+  else
+    echo Skipping $1 - It is not present on disk
+  fi
+}
+
+move_src_dirs_if_exist() {
+  mkdir src_artifacts
+
+  for dir in \
+    src/out/Default/gen/node_headers \
+    src/out/Default/overlapped-checker \
+    src/out/Default/ffmpeg \
+    src/out/Default/hunspell_dictionaries \
+    src/third_party/electron_node \
+    src/third_party/nan \
+    src/cross-arch-snapshots \
+    src/third_party/llvm-build \
+    src/build/linux \
+    src/buildtools/mac \
+    src/buildtools/third_party/libc++ \
+    src/buildtools/third_party/libc++abi \
+    src/third_party/libc++ \
+    src/third_party/libc++abi \
+    src/out/Default/obj/buildtools/third_party \
+    src/v8/tools/builtins-pgo
+  do
+    if [ -d "$dir" ]; then
+      mkdir -p src_artifacts/$(dirname $dir)
+      cp -r $dir/ src_artifacts/$dir
+    fi      
+  done
+
+  tar -C src_artifacts -cf src_artifacts.tar ./
+
+  echo Storing src_artifacts.tar
+  mv src_artifacts.tar $SRC_ARTIFACTS
+}
+
+# Generated Artifacts
+mv_if_exist src/out/Default/dist.zip
+mv_if_exist src/out/Default/gen/node_headers.tar.gz
+mv_if_exist src/out/Default/symbols.zip
+mv_if_exist src/out/Default/mksnapshot.zip
+mv_if_exist src/out/Default/chromedriver.zip
+mv_if_exist src/out/ffmpeg/ffmpeg.zip
+mv_if_exist src/out/Default/hunspell_dictionaries.zip
+mv_if_exist src/cross-arch-snapshots
+cp_if_exist src/out/electron_ninja_log
+cp_if_exist src/out/Default/.ninja_log
+
+move_src_dirs_if_exist
\ No newline at end of file
diff --git a/script/actions/restore-artifacts.sh b/script/actions/restore-artifacts.sh
new file mode 100755
index 000000000000..dc70602d86bb
--- /dev/null
+++ b/script/actions/restore-artifacts.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+GENERATED_ARTIFACTS="generated_artifacts_${BUILD_TYPE}_${TARGET_ARCH}"
+SRC_ARTIFACTS="src_artifacts_${BUILD_TYPE}_${TARGET_ARCH}"
+
+mv_if_exist() {
+  if [ -f "${GENERATED_ARTIFACTS}/$1" ] || [ -d "${GENERATED_ARTIFACTS}/$1" ]; then
+    echo Restoring $1 to $2
+    mkdir -p $2
+    mv $GENERATED_ARTIFACTS/$1 $2
+  else
+    echo Skipping $1 - It is not present on disk
+  fi
+}
+
+untar_if_exist() {
+  if [ -f "${SRC_ARTIFACTS}/$1" ] || [ -d "${SRC_ARTIFACTS}/$1" ]; then
+    echo Restoring $1 to current directory
+    tar -xf ${SRC_ARTIFACTS}/$1
+  else
+    echo Skipping $1 - It is not present on disk
+  fi
+}
+
+echo Restoring artifacts from $GENERATED_ARTIFACTS
+
+# Restore generated artifacts
+mv_if_exist dist.zip src/out/Default
+mv_if_exist node_headers.tar.gz src/out/Default/gen
+mv_if_exist symbols.zip src/out/Default
+mv_if_exist mksnapshot.zip src/out/Default
+mv_if_exist chromedriver.zip src/out/Default
+mv_if_exist ffmpeg.zip src/out/ffmpeg
+mv_if_exist hunspell_dictionaries.zip src/out/Default
+mv_if_exist cross-arch-snapshots src
+
+echo Restoring artifacts from $SRC_ARTIFACTS
+
+# Restore src artifacts
+untar_if_exist src_artifacts.tar
\ No newline at end of file
diff --git a/script/actions/run-tests.sh b/script/actions/run-tests.sh
new file mode 100755
index 000000000000..7f68350bef6e
--- /dev/null
+++ b/script/actions/run-tests.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+set -euo pipefail
+
+export DISPLAY=:99
+Xvfb :99 -screen 0 1024x768x16 -ac &
+XVFB_PID=$!
+node "$@"
\ No newline at end of file
diff --git a/script/release/ci-release-build.js b/script/release/ci-release-build.js
index 9e120ce2bbc8..0ceef891d8e1 100644
--- a/script/release/ci-release-build.js
+++ b/script/release/ci-release-build.js
@@ -9,11 +9,9 @@ const octokit = new Octokit({
 });
 
 const BUILD_APPVEYOR_URL = 'https://ci.appveyor.com/api/builds';
-const CIRCLECI_PIPELINE_URL = 'https://circleci.com/api/v2/project/gh/electron/electron/pipeline';
 const GH_ACTIONS_PIPELINE_URL = 'https://github.com/electron/electron/actions';
 const GH_ACTIONS_API_URL = '/repos/electron/electron/actions';
 
-const CIRCLECI_WAIT_TIME = process.env.CIRCLECI_WAIT_TIME || 30000;
 const GH_ACTIONS_WAIT_TIME = process.env.GH_ACTIONS_WAIT_TIME || 30000;
 
 const appVeyorJobs = {
@@ -22,24 +20,11 @@ const appVeyorJobs = {
   'electron-woa': 'electron-woa-release'
 };
 
-const circleCIPublishWorkflows = [
+const ghActionsPublishWorkflows = [
   'linux-publish',
   'macos-publish'
 ];
 
-const circleCIPublishIndividualArches = {
-  'macos-publish': ['osx-x64', 'mas-x64', 'osx-arm64', 'mas-arm64'],
-  'linux-publish': ['arm', 'arm64', 'x64']
-};
-
-const ghActionsPublishWorkflows = [
-  'macos-publish'
-];
-
-const ghActionsPublishIndividualArches = {
-  'macos-publish': ['osx-x64', 'mas-x64', 'osx-arm64', 'mas-arm64']
-};
-
 let jobRequestedCount = 0;
 
 async function makeRequest ({ auth, username, password, url, headers, body, method }) {
@@ -82,11 +67,6 @@ async function githubActionsCall (targetBranch, workflowName, options) {
     buildRequest.parameters['upload-to-storage'] = '1';
   }
   buildRequest.parameters[`run-${workflowName}`] = true;
-  if (options.arch) {
-    const validArches = ghActionsPublishIndividualArches[workflowName];
-    assert(validArches.includes(options.arch), `Unknown GitHub Actions architecture "${options.arch}".  Valid values are ${JSON.stringify(validArches)}`);
-    buildRequest.parameters['macos-publish-arch-limit'] = options.arch;
-  }
 
   jobRequestedCount++;
   try {
@@ -101,7 +81,7 @@ async function githubActionsCall (targetBranch, workflowName, options) {
     }
 
     await octokit.request(`POST ${GH_ACTIONS_API_URL}/workflows/${workflowName}.yml/dispatches`, {
-      ref: buildRequest.branch,
+      ref: `refs/tags/${options.newVersion}`,
       inputs: {
         ...buildRequest.parameters
       },
@@ -129,120 +109,6 @@ async function githubActionsCall (targetBranch, workflowName, options) {
   }
 }
 
-async function circleCIcall (targetBranch, workflowName, options) {
-  console.log(`Triggering CircleCI to run build job: ${workflowName} on branch: ${targetBranch} with release flag.`);
-  const buildRequest = {
-    branch: targetBranch,
-    parameters: {}
-  };
-  if (options.ghRelease) {
-    buildRequest.parameters['upload-to-storage'] = '0';
-  } else {
-    buildRequest.parameters['upload-to-storage'] = '1';
-  }
-  buildRequest.parameters[`run-${workflowName}`] = true;
-  if (options.arch) {
-    const validArches = circleCIPublishIndividualArches[workflowName];
-    assert(validArches.includes(options.arch), `Unknown CircleCI architecture "${options.arch}".  Valid values are ${JSON.stringify(validArches)}`);
-    buildRequest.parameters['macos-publish-arch-limit'] = options.arch;
-  }
-
-  jobRequestedCount++;
-  // The logic below expects that the CircleCI workflows for releases each
-  // contain only one job in order to maintain compatibility with sudowoodo.
-  // If the workflows are changed in the CircleCI config.yml, this logic will
-  // also need to be changed as well as possibly changing sudowoodo.
-  try {
-    const circleResponse = await circleCIRequest(CIRCLECI_PIPELINE_URL, 'POST', buildRequest);
-    console.log(`CircleCI release build pipeline ${circleResponse.id} for ${workflowName} triggered.`);
-    const workflowId = await getCircleCIWorkflowId(circleResponse.id);
-    if (workflowId === -1) {
-      return;
-    }
-    const workFlowUrl = `https://circleci.com/workflow-run/${workflowId}`;
-    if (options.runningPublishWorkflows) {
-      console.log(`CircleCI release workflow request for ${workflowName} successful.  Check ${workFlowUrl} for status.`);
-    } else {
-      console.log(`CircleCI release build workflow running at https://circleci.com/workflow-run/${workflowId} for ${workflowName}.`);
-      const jobNumber = await getCircleCIJobNumber(workflowId);
-      if (jobNumber === -1) {
-        return;
-      }
-      const jobUrl = `https://circleci.com/gh/electron/electron/${jobNumber}`;
-      console.log(`CircleCI release build request for ${workflowName} successful.  Check ${jobUrl} for status.`);
-    }
-  } catch (err) {
-    console.log('Error calling CircleCI: ', err);
-  }
-}
-
-async function getCircleCIWorkflowId (pipelineId) {
-  const pipelineInfoUrl = `https://circleci.com/api/v2/pipeline/${pipelineId}`;
-  let workflowId = 0;
-  while (workflowId === 0) {
-    const pipelineInfo = await circleCIRequest(pipelineInfoUrl, 'GET');
-    switch (pipelineInfo.state) {
-      case 'created': {
-        const workflows = await circleCIRequest(`${pipelineInfoUrl}/workflow`, 'GET');
-        // The logic below expects three workflow.items: publish, lint, & setup
-        if (workflows.items.length === 3) {
-          workflowId = workflows.items.find(item => item.name.includes('publish')).id;
-          break;
-        }
-        console.log('Unexpected number of workflows, response was:', workflows);
-        workflowId = -1;
-        break;
-      }
-      case 'error': {
-        console.log('Error retrieving workflows, response was:', pipelineInfo);
-        workflowId = -1;
-        break;
-      }
-    }
-    await new Promise(resolve => setTimeout(resolve, CIRCLECI_WAIT_TIME));
-  }
-  return workflowId;
-}
-
-async function getCircleCIJobNumber (workflowId) {
-  const jobInfoUrl = `https://circleci.com/api/v2/workflow/${workflowId}/job`;
-  let jobNumber = 0;
-  while (jobNumber === 0) {
-    const jobInfo = await circleCIRequest(jobInfoUrl, 'GET');
-    if (!jobInfo.items) {
-      continue;
-    }
-    if (jobInfo.items.length !== 1) {
-      console.log('Unexpected number of jobs, response was:', jobInfo);
-      jobNumber = -1;
-      break;
-    }
-
-    switch (jobInfo.items[0].status) {
-      case 'not_running':
-      case 'queued':
-      case 'running': {
-        if (jobInfo.items[0].job_number && !isNaN(jobInfo.items[0].job_number)) {
-          jobNumber = jobInfo.items[0].job_number;
-        }
-        break;
-      }
-      case 'canceled':
-      case 'error':
-      case 'infrastructure_fail':
-      case 'timedout':
-      case 'not_run':
-      case 'failed': {
-        console.log(`Error job returned a status of ${jobInfo.items[0].status}, response was:`, jobInfo);
-        jobNumber = -1;
-        break;
-      }
-    }
-    await new Promise(resolve => setTimeout(resolve, CIRCLECI_WAIT_TIME));
-  }
-  return jobNumber;
-}
-
 async function getGitHubActionsRun (workflowId, headCommit) {
   let runNumber = 0;
   let actionRun;
@@ -296,33 +162,6 @@ async function getGitHubActionsRun (workflowId, headCommit) {
   return runNumber;
 }
 
-async function circleCIRequest (url, method, requestBody) {
-  const requestOpts = {
-    username: process.env.CIRCLE_TOKEN,
-    password: '',
-    method,
-    url,
-    headers: {
-      'Content-Type': 'application/json',
-      Accept: 'application/json'
-    }
-  };
-  if (requestBody) {
-    requestOpts.body = JSON.stringify(requestBody);
-  }
-
-  return makeRequest(requestOpts, true).catch(err => {
-    if (err.response?.body) {
-      console.error('Could not call CircleCI: ', {
-        statusCode: err.response.statusCode,
-        body: JSON.parse(err.response.body)
-      });
-    } else {
-      console.error('Error calling CircleCI:', err);
-    }
-  });
-}
-
 async function callAppVeyor (targetBranch, job, options) {
   console.log(`Triggering AppVeyor to run build job: ${job} on branch: ${targetBranch} with release flag.`);
   const environmentVariables = {
@@ -381,19 +220,6 @@ function buildAppVeyor (targetBranch, options) {
   }
 }
 
-function buildCircleCI (targetBranch, options) {
-  if (options.job) {
-    assert(circleCIPublishWorkflows.includes(options.job), `Unknown CircleCI workflow name: ${options.job}. Valid values are: ${circleCIPublishWorkflows}.`);
-    circleCIcall(targetBranch, options.job, options);
-  } else {
-    assert(!options.arch, 'Cannot provide a single architecture while building all workflows, please specify a single workflow via --workflow');
-    options.runningPublishWorkflows = true;
-    for (const job of circleCIPublishWorkflows) {
-      circleCIcall(targetBranch, job, options);
-    }
-  }
-}
-
 function buildGHActions (targetBranch, options) {
   if (options.job) {
     assert(ghActionsPublishWorkflows.includes(options.job), `Unknown GitHub Actions workflow name: ${options.job}. Valid values are: ${ghActionsPublishWorkflows}.`);
@@ -410,10 +236,6 @@ function buildGHActions (targetBranch, options) {
 function runRelease (targetBranch, options) {
   if (options.ci) {
     switch (options.ci) {
-      case 'CircleCI': {
-        buildCircleCI(targetBranch, options);
-        break;
-      }
       case 'GitHubActions': {
         buildGHActions(targetBranch, options);
         break;
@@ -428,10 +250,8 @@ function runRelease (targetBranch, options) {
       }
     }
   } else {
-    buildCircleCI(targetBranch, options);
     buildAppVeyor(targetBranch, options);
-    // TODO(vertedinde): Enable GH Actions in defaults when ready
-    // buildGHActions(targetBranch, options);
+    buildGHActions(targetBranch, options);
   }
   console.log(`${jobRequestedCount} jobs were requested.`);
 }
@@ -445,8 +265,8 @@ if (require.main === module) {
   const targetBranch = args._[0];
   if (args._.length < 1) {
     console.log(`Trigger CI to build release builds of electron.
-    Usage: ci-release-build.js [--job=CI_JOB_NAME] [--arch=INDIVIDUAL_ARCH] [--ci=CircleCI|AppVeyor|GitHubActions]
-    [--ghRelease] [--circleBuildNum=xxx] [--appveyorJobId=xxx] [--commit=sha] TARGET_BRANCH
+    Usage: ci-release-build.js [--job=CI_JOB_NAME] [--arch=INDIVIDUAL_ARCH] [--ci=AppVeyor|GitHubActions]
+    [--ghRelease] [--appveyorJobId=xxx] [--commit=sha] TARGET_BRANCH
     `);
     process.exit(0);
   }
diff --git a/script/split-tests.js b/script/split-tests.js
new file mode 100755
index 000000000000..43a039775815
--- /dev/null
+++ b/script/split-tests.js
@@ -0,0 +1,32 @@
+const fs = require('node:fs');
+const glob = require('glob');
+
+const currentShard = parseInt(process.argv[2], 10);
+const shardCount = parseInt(process.argv[3], 10);
+
+const specFiles = glob.sync('spec/*-spec.ts');
+
+const buckets = [];
+
+for (let i = 0; i < shardCount; i++) {
+  buckets.push([]);
+}
+
+const testsInSpecFile = Object.create(null);
+for (const specFile of specFiles) {
+  const testContent = fs.readFileSync(specFile, 'utf8');
+  testsInSpecFile[specFile] = testContent.split('it(').length;
+}
+
+specFiles.sort((a, b) => {
+  return testsInSpecFile[b] - testsInSpecFile[a];
+});
+
+let shard = 0;
+for (const specFile of specFiles) {
+  buckets[shard].push(specFile);
+  shard++;
+  if (shard === shardCount) shard = 0;
+}
+
+console.log(buckets[currentShard - 1].join(' '));
diff --git a/spec/api-app-spec.ts b/spec/api-app-spec.ts
index c1eb84b24718..6fd2b76406fa 100644
--- a/spec/api-app-spec.ts
+++ b/spec/api-app-spec.ts
@@ -595,7 +595,7 @@ describe('app module', () => {
     });
   });
 
-  ifdescribe(process.platform !== 'linux' && !process.mas)('app.get/setLoginItemSettings API', function () {
+  ifdescribe(process.platform !== 'linux' && !process.mas && (process.platform !== 'darwin' || process.arch === 'arm64'))('app.get/setLoginItemSettings API', function () {
     const isMac = process.platform === 'darwin';
     const isWin = process.platform === 'win32';
 
diff --git a/spec/api-protocol-spec.ts b/spec/api-protocol-spec.ts
index 122cc4e84f0d..3ba77351d839 100644
--- a/spec/api-protocol-spec.ts
+++ b/spec/api-protocol-spec.ts
@@ -1749,7 +1749,7 @@ describe('protocol module', () => {
         const end = Date.now();
         return end - begin;
       })();
-      expect(interceptedTime).to.be.lessThan(rawTime * 1.5);
+      expect(interceptedTime).to.be.lessThan(rawTime * 1.6);
     });
   });
 });