Merge branch 'main' into roller/chromium/main

This commit is contained in:
Alice Zhao
2024-06-18 16:27:47 -07:00
78 changed files with 2606 additions and 1120 deletions

View File

@@ -0,0 +1,198 @@
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
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: Build Electron dist.zip ${{ inputs.step-suffix }}
shell: bash
run: |
cd src
e build electron:electron_dist_zip -j $NUMBER_OF_NINJA_PROCESSES
if [ "${{ env.CHECK_DIST_MANIFEST }}" = "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
# TODO(vertedinde): These uploads currently point to a different Azure bucket & GitHub Repo
- 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
# 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_${{ inputs.artifact-platform }}_${{ env.TARGET_ARCH }}
path: ./generated_artifacts_${{ inputs.artifact-platform }}_${{ env.TARGET_ARCH }}
- name: Upload Src Artifacts ${{ inputs.step-suffix }}
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
with:
name: src_artifacts_${{ inputs.artifact-platform }}_${{ env.TARGET_ARCH }}
path: ./src_artifacts_${{ inputs.artifact-platform }}_${{ env.TARGET_ARCH }}

154
.github/actions/checkout/action.yml vendored Normal file
View File

@@ -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=true" >> $GITHUB_OUTPUT
echo "Cache Already Exists for $DEPSHASH, Skipping.."
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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,51 @@
name: 'Restore Cache AZCopy'
description: 'Restores Electron src cache via AZCopy'
runs:
using: "composite"
steps:
- name: Obtain SAS Key
uses: actions/cache/restore@v4
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)
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

View File

@@ -0,0 +1,24 @@
name: Auto Close Pull Request
on:
pull_request_target:
paths:
- 'yarn.lock'
- 'spec/yarn.lock'
permissions: {}
jobs:
auto-close-dependency-pull-request:
name: Auto close non-maintainer dependency pull request
if: ${{ !contains(fromJSON('["MEMBER", "OWNER"]'), github.event.pull_request.author_association) && github.event.pull_request.user.type != 'Bot' && !github.event.pull_request.draft }}
permissions:
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Close pull request
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{ github.event.pull_request.html_url }}
run: |
gh pr close $PR_URL --comment 'Hello @${{ github.event.pull_request.user.login }}! It looks like this pull request touches one of our dependency files, and per [our contribution policy](https://github.com/electron/electron/blob/main/CONTRIBUTING.md#dependencies-upgrades-policy) we do not accept these types of PRs, so this PR will be closed.'

205
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,205 @@
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:
# pull_request:
jobs:
changes:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
docs: ${{ steps.filter.outputs.docs }}
src: ${{ steps.filter.outputs.src }}
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.0.2
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
id: filter
with:
filters: |
docs:
- 'docs/**'
src:
- '!docs/**'
# Lint Jobs
lint:
if: ${{ !inputs.skip-lint }}
uses: ./.github/workflows/pipeline-electron-lint.yml
with:
container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root"}'
secrets: inherit
# Docs Only Jobs
docs-only:
needs: changes
if: ${{ needs.changes.outputs.docs == 'true' && needs.changes.outputs.src == 'false'}}
uses: ./.github/workflows/pipeline-electron-docs-only.yml
with:
container: '{"image":"ghcr.io/electron/build:${{ inputs.build-image-sha }}","options":"--user root"}'
secrets: inherit
# Checkout Jobs
checkout-macos:
needs: changes
if: ${{ needs.changes.outputs.src == 'true' && !inputs.skip-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'
checkout-linux:
needs: changes
if: ${{ needs.changes.outputs.src == 'true' && !inputs.skip-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
# 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:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/build:${{ inputs.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-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:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/test:arm32v7-${{ inputs.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:${{ inputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}'
test-container: '{"image":"ghcr.io/electron/test:arm64v8-${{ inputs.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

View File

@@ -1,26 +0,0 @@
{
"root": "/Users/runner/work/electron/electron/",
"remotes": {
"electron": {
"origin": "https://github.com/electron/electron.git"
}
},
"gen": {
"args": [
"import(\"//electron/build/args/release.gn\")",
"use_remoteexec = true",
"target_cpu = \"arm64\"",
"is_mas_build = true"
],
"out": "Default"
},
"env": {
"CHROMIUM_BUILDTOOLS_PATH": "/Users/runner/work/electron/electron/src/buildtools",
"GIT_CACHE_PATH": "/Users/runner/work/electron/electron/.git-cache"
},
"$schema": "file:///home/builduser/.electron_build_tools/evm-config.schema.json",
"configValidationLevel": "strict",
"reclient": "remote_exec",
"goma": "none",
"preserveXcode": 5
}

View File

@@ -1,26 +0,0 @@
{
"root": "/Users/runner/work/electron/electron/",
"remotes": {
"electron": {
"origin": "https://github.com/electron/electron.git"
}
},
"gen": {
"args": [
"import(\"//electron/build/args/release.gn\")",
"use_remoteexec = true",
"target_cpu = \"x64\"",
"is_mas_build = true"
],
"out": "Default"
},
"env": {
"CHROMIUM_BUILDTOOLS_PATH": "/Users/runner/work/electron/electron/src/buildtools",
"GIT_CACHE_PATH": "/Users/runner/work/electron/electron/.git-cache"
},
"$schema": "file:///home/builduser/.electron_build_tools/evm-config.schema.json",
"configValidationLevel": "strict",
"reclient": "remote_exec",
"goma": "none",
"preserveXcode": 5
}

View File

@@ -1,25 +0,0 @@
{
"root": "/Users/runner/work/electron/electron/",
"remotes": {
"electron": {
"origin": "https://github.com/electron/electron.git"
}
},
"gen": {
"args": [
"import(\"//electron/build/args/testing.gn\")",
"use_remoteexec = true",
"is_mas_build = true"
],
"out": "Default"
},
"env": {
"CHROMIUM_BUILDTOOLS_PATH": "/Users/runner/work/electron/electron/src/buildtools",
"GIT_CACHE_PATH": "/Users/runner/work/electron/electron/.git-cache"
},
"$schema": "file:///home/builduser/.electron_build_tools/evm-config.schema.json",
"configValidationLevel": "strict",
"reclient": "remote_exec",
"goma": "none",
"preserveXcode": 5
}

View File

@@ -1,25 +0,0 @@
{
"root": "/Users/runner/work/electron/electron/",
"remotes": {
"electron": {
"origin": "https://github.com/electron/electron.git"
}
},
"gen": {
"args": [
"import(\"//electron/build/args/testing.gn\")",
"use_remoteexec = true",
"is_mas_build = true"
],
"out": "Default"
},
"env": {
"CHROMIUM_BUILDTOOLS_PATH": "/Users/runner/work/electron/electron/src/buildtools",
"GIT_CACHE_PATH": "/Users/runner/work/electron/electron/.git-cache"
},
"$schema": "file:///home/builduser/.electron_build_tools/evm-config.schema.json",
"configValidationLevel": "strict",
"reclient": "remote_exec",
"goma": "none",
"preserveXcode": 5
}

83
.github/workflows/linux-publish.yml vendored Normal file
View File

@@ -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_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
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

View File

@@ -1,765 +0,0 @@
name: Build MacOS
# TODO: change to 'pull_request' and 'push'
# when we are ready to enable this for PRs.
on:
workflow_call:
inputs:
IS_RELEASE:
required: true
type: boolean
default: false
GN_CONFIG:
required: false
type: string
default: //electron/build/args/testing.gn
GN_BUILD_TYPE:
required: false
type: string
default: release
GENERATE_SYMBOLS:
required: false
type: boolean
default: false
UPLOAD_TO_STORAGE:
required: false
type: string
default: '0'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
AZURE_STORAGE_ACCOUNT: ${{ secrets.AZURE_STORAGE_ACCOUNT }}
AZURE_STORAGE_KEY: ${{ secrets.AZURE_STORAGE_KEY }}
AZURE_STORAGE_CONTAINER_NAME: ${{ secrets.AZURE_STORAGE_CONTAINER_NAME }}
ELECTRON_ARTIFACTS_BLOB_STORAGE: ${{ secrets.ELECTRON_ARTIFACTS_BLOB_STORAGE }}
ELECTRON_RBE_JWT: ${{ secrets.ELECTRON_RBE_JWT }}
ELECTRON_GITHUB_TOKEN: ${{ secrets.ELECTRON_GITHUB_TOKEN }}
GN_CONFIG: ${{ inputs.GN_CONFIG }}
# Disable pre-compiled headers to reduce out size - only useful for rebuilds
GN_BUILDFLAG_ARGS: 'enable_precompiled_headers = false'
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
CHECK_DIST_MANIFEST: '1'
IS_GHA_RELEASE: true
ELECTRON_OUT_DIR: Default
jobs:
checkout:
runs-on: LargeLinuxRunner
steps:
- name: Checkout Electron
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
with:
path: src/electron
fetch-depth: 0
- name: Set GIT_CACHE_PATH to make gclient to use the cache
run: |
echo "GIT_CACHE_PATH=$(pwd)/git-cache" >> $GITHUB_ENV
- name: Setup Node.js/npm
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
- 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: Generate DEPS Hash
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: Check If Cache Exists
id: check-cache
run: |
exists_json=$(az storage blob exists \
--account-name $AZURE_STORAGE_ACCOUNT \
--account-key $AZURE_STORAGE_KEY \
--container-name $AZURE_STORAGE_CONTAINER_NAME \
--name $DEPSHASH)
cache_exists=$(echo $exists_json | jq -r '.exists')
echo "cache_exists=$cache_exists" >> $GITHUB_OUTPUT
if (test "$cache_exists" = "true"); then
echo "Cache Exists for $DEPSHASH"
else
echo "Cache Does Not Exist for $DEPSHASH"
fi
- name: Gclient Sync
# If there is no existing src cache, we need to do a full gclient sync.
# TODO(codebytere): Add stale patch handling for non-release builds.
if: steps.check-cache.outputs.cache_exists == 'false'
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'
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'
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'
run: |
echo "Uncompressed src size: $(du -sh src | cut -f1 -d' ')"
tar -cvf $DEPSHASH.tar src
echo "Compressed src to $(du -sh $DEPSHASH.tar | cut -f1 -d' ')"
- name: Upload Compressed Src Cache to Azure
if: steps.check-cache.outputs.cache_exists == 'false'
run: |
az storage blob upload \
--account-name $AZURE_STORAGE_ACCOUNT \
--account-key $AZURE_STORAGE_KEY \
--container-name $AZURE_STORAGE_CONTAINER_NAME \
--file $DEPSHASH.tar \
--name $DEPSHASH \
--debug
build:
strategy:
fail-fast: false
matrix:
build-arch: [ arm64, x64 ]
# macos-large is x64, macos-xlarge is arm64
# More runner information: https://github.com/actions/runner-images/blob/main/README.md#available-images
runs-on: macos-14-xlarge
needs: checkout
steps:
- name: Load Build Tools
run: |
export BUILD_TOOLS_SHA=2bb63e2e7877491b52f972532b52adc979a6ec2f
npm i -g @electron/build-tools
e init --root=$(pwd) --out=Default ${{ inputs.GN_BUILD_TYPE }} --import ${{ inputs.GN_BUILD_TYPE }} --target-cpu ${{ matrix.build-arch}}
e use ${{ inputs.GN_BUILD_TYPE }}
- name: Checkout Electron
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
with:
path: src/electron
fetch-depth: 0
- name: Setup Node.js/npm
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
- name: Load Target Arch & CPU
run: |
echo "TARGET_ARCH=${{ matrix.build-arch }}" >> $GITHUB_ENV
echo "target_cpu=${{ matrix.build-arch }}" >> $GITHUB_ENV
echo "host_cpu=${{ matrix.build-arch }}" >> $GITHUB_ENV
- 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: Generate DEPS Hash
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: Download Src Cache
# 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: |
az storage blob download \
--account-name $AZURE_STORAGE_ACCOUNT \
--account-key $AZURE_STORAGE_KEY \
--container-name $AZURE_STORAGE_CONTAINER_NAME \
--name $DEPSHASH \
--file $DEPSHASH.tar \
- name: Unzip and Ensure Src Cache
run: |
echo "Downloaded cache is $(du -sh $DEPSHASH.tar | cut -f1)"
mkdir temp-cache
tar -xvf $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
- name: Checkout Electron
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
with:
path: src/electron
fetch-depth: 0
- name: Run Electron Only Hooks
run: |
echo "Running Electron Only Hooks"
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
# 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 [ "$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
- name: Install build-tools & Setup RBE
run: |
echo "NUMBER_OF_NINJA_PROCESSES=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 Space on MacOS
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
# the contents of build/linux/strip_binary.gni aren't used, but
# https://chromium-review.googlesource.com/c/chromium/src/+/4278307
# needs the file to exist.
# mv ~/project/src/build/linux/strip_binary.gni "${TMPDIR}"/
# tmpify ~/project/src/build/linux/
# mkdir -p ~/project/src/build/linux
# mv "${TMPDIR}/strip_binary.gni" ~/project/src/build/linux/
sudo rm -rf $TMPDIR/del-target
# sudo rm -rf "/System/Library/Desktop Pictures"
# sudo rm -rf /System/Library/Templates/Data
# sudo rm -rf /System/Library/Speech/Voices
# sudo rm -rf "/System/Library/Screen Savers"
# sudo rm -rf /System/Volumes/Data/Library/Developer/CommandLineTools/SDKs
# sudo rm -rf "/System/Volumes/Data/Library/Application Support/Apple/Photos/Print Products"
# sudo rm -rf /System/Volumes/Data/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/
# sudo rm -rf /System/Volumes/Data/Library/Java
# sudo rm -rf /System/Volumes/Data/Library/Ruby
# sudo rm -rf /System/Volumes/Data/Library/Printers
# sudo rm -rf /System/iOSSupport
# sudo rm -rf /System/Applications/*.app
# sudo rm -rf /System/Applications/Utilities/*.app
# sudo rm -rf /System/Library/LinguisticData
# sudo rm -rf /System/Volumes/Data/private/var/db/dyld/*
# sudo rm -rf /System/Library/Fonts/*
# sudo rm -rf /System/Library/PreferencePanes
# sudo rm -rf /System/Library/AssetsV2/*
sudo rm -rf /Applications/Safari.app
sudo rm -rf ~/project/src/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
- name: Build Electron (darwin)
run: |
cd src/electron
# TODO(codebytere): remove this once we figure out why .git/packed-refs is initially missing
git pack-refs
cd ..
ulimit -n 10000
sudo launchctl limit maxfiles 65536 200000
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: Build Electron dist.zip (darwin)
run: |
cd src
e build electron:electron_dist_zip -j $NUMBER_OF_NINJA_PROCESSES
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
target_os=mac
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.${{ env.TARGET_ARCH }}.manifest
fi
- name: Build Mksnapshot (darwin)
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 ''"
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
e build electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
(cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
- name: Build Chromedriver (darwin)
run: |
cd src
e build electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
e build electron:electron_chromedriver_zip
# NOTE (vertedinde): We strip binaries/symbols on the Linux job, not the Mac job
- name: Generate & Zip Symbols (darwin)
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
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
if: ${{ inputs.IS_RELEASE == true }}
run: |
cd src
autoninja -C out/Default electron:hunspell_dictionaries_zip -j $NUMBER_OF_NINJA_PROCESSES
- name: Generate TypeScript Definitions
if: ${{ inputs.IS_RELEASE == true }}
run: |
cd src/electron
node script/yarn create-typescript-definitions
# TODO(vertedinde): These uploads currently point to a different Azure bucket & GitHub Repo
- name: Publish Electron Dist
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
# 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
run: ./src/electron/script/actions/move-artifacts.sh
- name: Upload Generated Artifacts
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
with:
name: generated_artifacts_darwin_${{ env.TARGET_ARCH }}
path: ./generated_artifacts_darwin_${{ env.TARGET_ARCH }}
- name: Persist Build Artifacts
uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
with:
path: |
src/out/Default/gen/node_headers
src/out/Default/overlapped-checker
src/electron
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
key: ${{ runner.os }}-build-artifacts-darwin-${{ env.TARGET_ARCH }}-${{ github.sha }}
- name: Create MAS Config
run: |
mv src/electron/.github/workflows/config/${{ inputs.GN_BUILD_TYPE }}/${{ matrix.build-arch }}/evm.mas.json $HOME/.electron_build_tools/configs/evm.mas.json
echo "MAS_BUILD=true" >> $GITHUB_ENV
e use mas
- name: Build Electron (mas)
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 ..
ulimit -n 10000
sudo launchctl limit maxfiles 65536 200000
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: Build Electron dist.zip (mas)
run: |
cd src
e build electron:electron_dist_zip -j $NUMBER_OF_NINJA_PROCESSES
if [ "$CHECK_DIST_MANIFEST" == "1" ]; then
target_os=mac_mas
electron/script/zip_manifests/check-zip-manifest.py out/Default/dist.zip electron/script/zip_manifests/dist_zip.$target_os.${{ env.TARGET_ARCH }}.manifest
fi
- name: Build Mksnapshot (mas)
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 ''"
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
e build electron:electron_mksnapshot_zip -j $NUMBER_OF_NINJA_PROCESSES
(cd out/Default; zip mksnapshot.zip mksnapshot_args gen/v8/embedded.S)
- name: Build Chromedriver (mas)
run: |
cd src
e build electron:electron_chromedriver -j $NUMBER_OF_NINJA_PROCESSES
e build electron:electron_chromedriver_zip
- name: Build Node Headers
run: |
cd src
e build electron:node_headers
- name: Generate & Zip Symbols (mas)
run: |
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
# TODO(vertedinde): These uploads currently point to a different Azure bucket & GitHub Repo
- name: Publish Electron Dist
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: Move all Generated Artifacts to Upload Folder (mas)
run: ./src/electron/script/actions/move-artifacts.sh
- name: Upload Generated Artifacts
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808
with:
name: generated_artifacts_mas_${{ env.TARGET_ARCH }}
path: ./generated_artifacts_mas_${{ env.TARGET_ARCH }}
- name: Persist Build Artifacts
uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
with:
path: |
src/out/Default/gen/node_headers
src/out/Default/overlapped-checker
src/out/Default/ffmpeg
src/out/Default/hunspell_dictionaries
src/electron
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
key: ${{ runner.os }}-build-artifacts-mas-${{ env.TARGET_ARCH }}-${{ github.sha }}
test:
if: ${{ inputs.IS_RELEASE == false }}
runs-on: macos-14-xlarge
needs: build
strategy:
fail-fast: false
matrix:
build-type: [ darwin, mas ]
env:
BUILD_TYPE: ${{ matrix.build-type }}
steps:
- name: Load Build Tools
run: |
export BUILD_TOOLS_SHA=2bb63e2e7877491b52f972532b52adc979a6ec2f
npm i -g @electron/build-tools
e init --root=$(pwd) --out=Default ${{ inputs.GN_BUILD_TYPE }}
- name: Checkout Electron
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
with:
path: src/electron
fetch-depth: 0
- name: Setup Node.js/npm
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
- 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: Download Generated Artifacts
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
with:
name: generated_artifacts_${{ matrix.build-type }}
path: ./generated_artifacts_${{ matrix.build-type }}
- name: Restore Persisted Build Artifacts
uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
with:
path: |
src/out/Default/gen/node_headers
src/out/Default/overlapped-checker
src/electron
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
key: ${{ runner.os }}-build-artifacts-${{ matrix.build-type }}-${{ github.sha }}
- 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
run: |
sudo security authorizationdb write com.apple.trust-settings.admin allow
cd src/electron
./script/codesign/generate-identity.sh
- name: Run Electron Tests
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
run: |
cd src/electron
node script/yarn test --runners=main --trace-uncaught --enable-logging

View File

@@ -3,9 +3,14 @@ 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
required: false
default: '1'
type: string
run-macos-publish:
@@ -14,13 +19,51 @@ on:
default: false
jobs:
publish:
# TODO(vertedinde): Change this to main before merge
uses: electron/electron/.github/workflows/macos-build.yml@gh-actions-mac-publish
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:
IS_RELEASE: true
GN_CONFIG: //electron/build/args/release.gn
GN_BUILD_TYPE: release
GENERATE_SYMBOLS: true
UPLOAD_TO_STORAGE: ${{ inputs.upload-to-storage }}
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

View File

@@ -0,0 +1,97 @@
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'
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 }}
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

View File

@@ -0,0 +1,92 @@
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'
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 }}
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 }}
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

View File

@@ -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

View File

@@ -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)"
mkdir -p src/buildtools
curl -sL "https://chromium.googlesource.com/chromium/src/+/${chromium_revision}/buildtools/DEPS?format=TEXT" | base64 -d > src/buildtools/DEPS
gclient runhooks --spec="solutions=[{'name':'src/buildtools','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':True},'managed':False}]"
- 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

View File

@@ -0,0 +1,202 @@
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'
concurrency:
group: electron-build-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ 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' }}
# Only disable this in the Asan build
CHECK_DIST_MANIFEST: true
IS_GHA_RELEASE: 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'
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 }}'
- 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)'

View File

@@ -0,0 +1,138 @@
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
concurrency:
group: electron-gn-check-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ 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

View File

@@ -0,0 +1,170 @@
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}'
concurrency:
group: electron-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
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 }}
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: Download Generated Artifacts
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
with:
name: generated_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }}
path: ./generated_artifacts_${{ matrix.build-type }}_${{ inputs.target-arch }}
- name: Download Src Artifacts
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e
with:
name: src_artifacts_${{ matrix.build-type }}_${{ env.TARGET_ARCH }}
path: ./src_artifacts_${{ matrix.build-type }}_${{ env.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' }}
# 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)
runuser -u builduser -- xvfb-run script/actions/run-tests.sh script/yarn test --runners=main --trace-uncaught --enable-logging --files $tests_files
fi
- name: Wait for active SSH sessions
if: always() && !cancelled()
run: |
while [ -f /var/.ssh-lock ]
do
sleep 60
done

View File

@@ -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

View File

@@ -22,7 +22,7 @@ jobs:
steps:
- name: "Checkout code"
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
persist-credentials: false
@@ -50,6 +50,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@f079b8493333aace61c81488f8bd40919487bd9f # v3.25.7
uses: github/codeql-action/upload-sarif@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10
with:
sarif_file: results.sarif

View File

@@ -19,7 +19,7 @@ jobs:
with:
creds: ${{ secrets.APPVEYOR_UPDATER_GH_APP_CREDS }}
- name: Checkout
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
fetch-depth: 0
token: ${{ steps.generate-token.outputs.token }}
@@ -39,7 +39,7 @@ jobs:
fi
- name: (Optionally) Update Appveyor Image
if: ${{ env.APPVEYOR_IMAGE_VERSION }}
uses: mikefarah/yq@557dcb87b8efe786f89a12c09e9046b4753ab72e # v4.44.1
uses: mikefarah/yq@f15500b20a1c991c8729870ba60a4dc3524b6a94 # v4.44.2
with:
cmd: |
yq '.image = "${{ env.APPVEYOR_IMAGE_VERSION }}"' "appveyor.yml" > "appveyor2.yml"

View File

@@ -19,7 +19,8 @@
"Tabs",
"TabItem"
]
}
},
"no-newline-in-links": true
},
"customRules": [
"@electron/lint-roller/markdownlint-rules/"

15
DEPS
View File

@@ -48,6 +48,9 @@ vars = {
# It's only needed to parse the native tests configurations.
'checkout_pyyaml': False,
# Can be used to disable the sysroot hooks.
'install_sysroot': True,
'use_rts': False,
'mac_xcode_version': 'default',
@@ -164,7 +167,7 @@ hooks = [
{
'name': 'sysroot_arm',
'pattern': '.',
'condition': 'checkout_linux and checkout_arm',
'condition': 'install_sysroot and checkout_linux and checkout_arm',
'action': ['python3', 'src/build/linux/sysroot_scripts/install-sysroot.py',
'--sysroots-json-path=' + Var('sysroots_json_path'),
'--arch=arm'],
@@ -172,7 +175,7 @@ hooks = [
{
'name': 'sysroot_arm64',
'pattern': '.',
'condition': 'checkout_linux and checkout_arm64',
'condition': 'install_sysroot and checkout_linux and checkout_arm64',
'action': ['python3', 'src/build/linux/sysroot_scripts/install-sysroot.py',
'--sysroots-json-path=' + Var('sysroots_json_path'),
'--arch=arm64'],
@@ -180,7 +183,7 @@ hooks = [
{
'name': 'sysroot_x86',
'pattern': '.',
'condition': 'checkout_linux and (checkout_x86 or checkout_x64)',
'condition': 'install_sysroot and checkout_linux and (checkout_x86 or checkout_x64)',
'action': ['python3', 'src/build/linux/sysroot_scripts/install-sysroot.py',
'--sysroots-json-path=' + Var('sysroots_json_path'),
'--arch=x86'],
@@ -188,7 +191,7 @@ hooks = [
{
'name': 'sysroot_mips',
'pattern': '.',
'condition': 'checkout_linux and checkout_mips',
'condition': 'install_sysroot and checkout_linux and checkout_mips',
'action': ['python3', 'src/build/linux/sysroot_scripts/install-sysroot.py',
'--sysroots-json-path=' + Var('sysroots_json_path'),
'--arch=mips'],
@@ -196,7 +199,7 @@ hooks = [
{
'name': 'sysroot_mips64',
'pattern': '.',
'condition': 'checkout_linux and checkout_mips64',
'condition': 'install_sysroot and checkout_linux and checkout_mips64',
'action': ['python3', 'src/build/linux/sysroot_scripts/install-sysroot.py',
'--sysroots-json-path=' + Var('sysroots_json_path'),
'--arch=mips64el'],
@@ -204,7 +207,7 @@ hooks = [
{
'name': 'sysroot_x64',
'pattern': '.',
'condition': 'checkout_linux and checkout_x64',
'condition': 'install_sysroot and checkout_linux and checkout_x64',
'action': ['python3', 'src/build/linux/sysroot_scripts/install-sysroot.py',
'--sysroots-json-path=' + Var('sysroots_json_path'),
'--arch=x64'],

View File

@@ -29,7 +29,7 @@
version: 1.0.{build}
build_cloud: electronhq-16-core
image: e-126.0.6445.0
image: e-127.0.6521.0
environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default

View File

@@ -29,7 +29,7 @@
version: 1.0.{build}
build_cloud: electronhq-16-core
image: e-126.0.6445.0
image: e-127.0.6521.0
environment:
GIT_CACHE_PATH: C:\Users\appveyor\libcc_cache
ELECTRON_OUT_DIR: Default

View File

@@ -1265,7 +1265,7 @@ Returns `Object`:
* `openAtLogin` boolean - `true` if the app is set to open at login.
* `openAsHidden` boolean _macOS_ _Deprecated_ - `true` if the app is set to open as hidden at login. This does not work on macOS 13 and up.
* `wasOpenedAtLogin` boolean _macOS_ _Deprecated_ - `true` if the app was opened at login automatically. This setting is not available on [MAS builds][mas-builds] or on macOS 13 and up.
* `wasOpenedAtLogin` boolean _macOS_ - `true` if the app was opened at login automatically.
* `wasOpenedAsHidden` boolean _macOS_ _Deprecated_ - `true` if the app was opened as a hidden login item. This indicates that the app should not open any windows at startup. This setting is not available on [MAS builds][mas-builds] or on macOS 13 and up.
* `restoreState` boolean _macOS_ _Deprecated_ - `true` if the app was opened as a login item that should restore the state from the previous session. This indicates that the app should restore the windows that were open the last time the app was closed. This setting is not available on [MAS builds][mas-builds] or on macOS 13 and up.
* `status` string _macOS_ - can be one of `not-registered`, `enabled`, `requires-approval`, or `not-found`.

View File

@@ -279,7 +279,7 @@ Aliased to `--debug[=[host:]port`.
Specify ways of the inspector web socket url exposure.
By default inspector websocket url is available in stderr and under /json/list endpoint on http://host:port/json/list.
By default inspector websocket url is available in stderr and under /json/list endpoint on `http://host:port/json/list`.
### `--no-deprecation`

View File

@@ -80,4 +80,4 @@ Returns `Menu | null` - The application's [dock menu][dock-menu].
Sets the `image` associated with this dock icon.
[dock-menu]: https://developer.apple.com/macos/human-interface-guidelines/menus/dock-menus/
[dock-menu]: https://developer.apple.com/design/human-interface-guidelines/dock-menus

View File

@@ -2,6 +2,8 @@
* `percentCPUUsage` number - Percentage of CPU used since the last call to getCPUUsage.
First call returns 0.
* `cumulativeCPUUsage` number (optional) - Total seconds of CPU time used since process
startup.
* `idleWakeupsPerSecond` number - The number of average idle CPU wakeups per second
since the last call to getCPUUsage. First call returns 0. Will always return 0 on
Windows.

View File

@@ -7,8 +7,8 @@
recording buffer in events.
* `enable_argument_filter` boolean (optional) - if true, filter event data
according to a specific list of events that have been manually vetted to not
include any PII. See [the implementation in
Chromium][trace_event_args_allowlist.cc] for specifics.
include any PII. See [the implementation in Chromium][trace_event_args_allowlist.cc]
for specifics.
* `included_categories` string[] (optional) - a list of tracing categories to
include. Can include glob-like patterns using `*` at the end of the category
name. See [tracing categories][] for the list of categories.
@@ -21,8 +21,8 @@
with the trace.
* `memory_dump_config` Record\<string, any\> (optional) - if the
`disabled-by-default-memory-infra` category is enabled, this contains
optional additional configuration for data collection. See the [Chromium
memory-infra docs][memory-infra docs] for more information.
optional additional configuration for data collection. See the
[Chromium memory-infra docs][memory-infra docs] for more information.
An example TraceConfig that roughly matches what Chrome DevTools records:

View File

@@ -9,10 +9,11 @@ check out our [Electron Versioning](./electron-versioning.md) doc.
| Electron | Alpha | Beta | Stable | EOL | Chrome | Node | Supported |
| ------- | ----- | ------- | ------ | ------ | ---- | ---- | ---- |
| 31.0.0 | 2024-Apr-18 | 2024-May-15 | 2024-Jun-11 | 2025-Jan-07 | M126 | TBD | ✅ |
| 32.0.0 | 2024-Jun-14 | 2024-Jul-24 | 2024-Aug-20 | 2025-Mar-04 | M128 | TBD | ✅ |
| 31.0.0 | 2024-Apr-18 | 2024-May-15 | 2024-Jun-11 | 2025-Jan-07 | M126 | v20.14 | ✅ |
| 30.0.0 | 2024-Feb-22 | 2024-Mar-20 | 2024-Apr-16 | 2024-Oct-15 | M124 | v20.11 | ✅ |
| 29.0.0 | 2023-Dec-07 | 2024-Jan-24 | 2024-Feb-20 | 2024-Aug-20 | M122 | v20.9 | ✅ |
| 28.0.0 | 2023-Oct-11 | 2023-Nov-06 | 2023-Dec-05 | 2024-Jun-11 | M120 | v18.18 | |
| 28.0.0 | 2023-Oct-11 | 2023-Nov-06 | 2023-Dec-05 | 2024-Jun-11 | M120 | v18.18 | 🚫 |
| 27.0.0 | 2023-Aug-17 | 2023-Sep-13 | 2023-Oct-10 | 2024-Apr-16 | M118 | v18.17 | 🚫 |
| 26.0.0 | 2023-Jun-01 | 2023-Jun-27 | 2023-Aug-15 | 2024-Feb-20 | M116 | v18.16 | 🚫 |
| 25.0.0 | 2023-Apr-10 | 2023-May-02 | 2023-May-30 | 2023-Dec-05 | M114 | v18.15 | 🚫 |

View File

@@ -20,7 +20,7 @@ You also have to register an Apple Developer account and join the
Electron apps can be distributed through Mac App Store or outside it. Each way
requires different ways of signing and testing. This guide focuses on
distribution via Mac App Store, but will also mention other methods.
distribution via Mac App Store.
The following steps describe how to get the certificates from Apple, how to sign
Electron apps, and how to test them.
@@ -104,26 +104,15 @@ the App Sandbox. The standard darwin build of Electron will fail to launch
when run under App Sandbox.
When signing the app with `@electron/osx-sign`, it will automatically add the
necessary entitlements to your app's entitlements, but if you are using custom
entitlements, you must ensure App Sandbox capacity is added:
necessary entitlements to your app's entitlements.
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
</dict>
</plist>
```
#### Extra steps without `electron-osx-sign`
<details>
<summary>Extra steps without `electron-osx-sign`</summary>
If you are signing your app without using `@electron/osx-sign`, you must ensure
the app bundle's entitlements have at least following keys:
```xml
```xml title='entitlements.plist'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
@@ -174,6 +163,7 @@ When using `@electron/osx-sign` the `ElectronTeamID` key will be added
automatically by extracting the Team ID from the certificate's name. You may
need to manually add this key if `@electron/osx-sign` could not find the correct
Team ID.
</details>
### Sign apps for development
@@ -181,8 +171,14 @@ To sign an app that can run on your development machine, you must sign it with
the "Apple Development" certificate and pass the provisioning profile to
`@electron/osx-sign`.
```bash
electron-osx-sign YourApp.app --identity='Apple Development' --provisioning-profile=/path/to/yourapp.provisionprofile
```js @ts-nocheck
const { signAsync } = require('@electron/osx-sign')
signAsync({
app: '/path/to/your.app',
identity: 'Apple Development',
provisioningProfile: '/path/to/your.provisionprofile'
})
```
If you are signing without `@electron/osx-sign`, you must place the provisioning
@@ -198,30 +194,16 @@ To sign an app that will be submitted to Mac App Store, you must sign it with
the "Apple Distribution" certificate. Note that apps signed with this
certificate will not run anywhere, unless it is downloaded from Mac App Store.
```bash
electron-osx-sign YourApp.app --identity='Apple Distribution'
```js @ts-nocheck
const { signAsync } = require('@electron/osx-sign')
signAsync({
app: 'path/to/your.app',
identity: 'Apple Distribution'
})
```
### Sign apps for distribution outside the Mac App Store
If you don't plan to submit the app to Mac App Store, you can sign it the
"Developer ID Application" certificate. In this way there is no requirement on
App Sandbox, and you should use the normal darwin build of Electron if you don't
use App Sandbox.
```bash
electron-osx-sign YourApp.app --identity='Developer ID Application' --no-gatekeeper-assess
```
By passing `--no-gatekeeper-assess`, `@electron/osx-sign` will skip the macOS
GateKeeper check as your app usually has not been notarized yet by this step.
<!-- TODO(zcbenz): Add a chapter about App Notarization -->
This guide does not cover [App Notarization][app-notarization], but you might
want to do it otherwise Apple may prevent users from using your app outside Mac
App Store.
## Submit Apps to the Mac App Store
## Submit apps to the Mac App Store
After signing the app with the "Apple Distribution" certificate, you can
continue to submit it to Mac App Store.
@@ -263,10 +245,43 @@ more information.
### Additional entitlements
Every app running under the App Sandbox will run under a limited set of permissions,
which limits potential damage from malicious code.
Depending on which Electron APIs your app uses, you may need to add additional
entitlements to your app's entitlements file. Otherwise, the App Sandbox may
prevent you from using them.
Entitlements are specified using a file with format like
property list (`.plist`) or XML. You must provide an entitlement file for the
application bundle itself and a child entitlement file which basically describes
an inheritance of properties, specified for all other enclosing executable files
like binaries, frameworks (`.framework`), and dynamically linked libraries (`.dylib`).
A full list of entitlements is available in the [App Sandbox][app-sandboxing]
documentation, but below are a few entitlements you might need for your
MAS app.
With `@electron/osx-sign`, you can set custom entitlements per file as such:
```js @ts-nocheck
const { signAsync } = require('@electron/osx-sign')
function getEntitlementsForFile (filePath) {
if (filePath.startsWith('my-path-1')) {
return './my-path-1.plist'
} else {
return './alternate.plist'
}
}
signAsync({
optionsForFile: (filePath) => ({
// Ensure you return the right entitlements path here based on the file being signed.
entitlements: getEntitlementsForFile(filePath)
})
})
```
#### Network access
Enable outgoing network connections to allow your app to connect to a server:
@@ -342,12 +357,11 @@ Electron uses following cryptographic algorithms:
[developer-program]: https://developer.apple.com/support/compare-memberships/
[@electron/osx-sign]: https://github.com/electron/osx-sign
[app-sandboxing]: https://developer.apple.com/app-sandboxing/
[app-notarization]: https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution
[submitting-your-app]: https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/AppDistributionGuide/SubmittingYourApp/SubmittingYourApp.html
[create-record]: https://help.apple.com/app-store-connect/#/dev2cd126805
[app-sandboxing]: https://developer.apple.com/documentation/security/app_sandbox
[submitting-your-app]: https://help.apple.com/xcode/mac/current/#/dev067853c94
[create-record]: https://developer.apple.com/help/app-store-connect/create-an-app-record/add-a-new-app
[apple-transporter]: https://help.apple.com/itc/transporteruserguide/en.lproj/static.html
[submit-for-review]: https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/SubmittingTheApp.html
[submit-for-review]: https://developer.apple.com/help/app-store-connect/manage-submissions-to-app-review/submit-for-review
[export-compliance]: https://help.apple.com/app-store-connect/#/devc3f64248f
[user-selected]: https://developer.apple.com/library/mac/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW6
[network-access]: https://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html#//apple_ref/doc/uid/TP40011195-CH4-SW9

View File

@@ -121,8 +121,8 @@ To automate the detection of misconfigurations and insecure patterns, it is
possible to use
[Electronegativity](https://github.com/doyensec/electronegativity). For
additional details on potential weaknesses and implementation bugs when
developing applications using Electron, please refer to this [guide for
developers and auditors](https://doyensec.com/resources/us-17-Carettoni-Electronegativity-A-Study-Of-Electron-Security-wp.pdf).
developing applications using Electron, please refer to this
[guide for developers and auditors](https://doyensec.com/resources/us-17-Carettoni-Electronegativity-A-Study-Of-Electron-Security-wp.pdf).
### 1. Only load secure content
@@ -246,7 +246,7 @@ and prevent the use of Node primitives `contextIsolation` **must** also be used.
:::info
For more information on what `contextIsolation` is and how to enable it please
see our dedicated [Context Isolation](context-isolation.md) document.
:::info
:::
### 4. Enable process sandboxing
@@ -259,7 +259,7 @@ content in an unsandboxed process, including the main process, is not advised.
:::info
For more information on what Process Sandboxing is and how to enable it please
see our dedicated [Process Sandboxing](sandbox.md) document.
:::info
:::
### 5. Handle session permission requests from remote content
@@ -644,8 +644,8 @@ windows at runtime.
#### How?
[`webContents`][web-contents] will delegate to its [window open
handler][window-open-handler] before creating new windows. The handler will
[`webContents`][web-contents] will delegate to its
[window open handler][window-open-handler] before creating new windows. The handler will
receive, amongst other parameters, the `url` the window was requested to open
and the options used to create it. We recommend that you register a handler to
monitor the creation of windows, and deny any unexpected window creation.

View File

@@ -40,8 +40,8 @@ npm install --save-dev @electron/rebuild
.\node_modules\.bin\electron-rebuild.cmd
```
For more information on usage and integration with other tools such as [Electron
Packager][electron-packager], consult the project's README.
For more information on usage and integration with other tools such as
[Electron Packager][electron-packager], consult the project's README.
### Using `npm`
@@ -108,8 +108,8 @@ the following things:
On Windows, by default, `node-gyp` links native modules against `node.dll`.
However, in Electron 4.x and higher, the symbols needed by native modules are
exported by `electron.exe`, and there is no `node.dll`. In order to load native
modules on Windows, `node-gyp` installs a [delay-load
hook](https://learn.microsoft.com/en-us/cpp/build/reference/error-handling-and-notification?view=msvc-170#notification-hooks) that triggers
modules on Windows, `node-gyp` installs a
[delay-load hook](https://learn.microsoft.com/en-us/cpp/build/reference/error-handling-and-notification?view=msvc-170#notification-hooks) that triggers
when the native module is loaded, and redirects the `node.dll` reference to use
the loading executable instead of looking for `node.dll` in the library search
path (which would turn up nothing). As such, on Electron 4.x and higher,

View File

@@ -23,8 +23,8 @@ and only allow the capabilities you want to support.
[we do not recommend you to use WebViews](../api/webview-tag.md#warning),
as this tag undergoes dramatic architectural changes that may affect stability
of your application. Consider switching to alternatives, like `iframe` and
Electron's `BrowserView`, or an architecture that avoids embedded content
by design.
Electron's [`WebContentsView`](../api/web-contents-view.md), or an architecture
that avoids embedded content by design.
[WebViews](../api/webview-tag.md) are based on Chromium's WebViews and are not
explicitly supported by Electron. We do not guarantee that the WebView API will

View File

@@ -3,8 +3,11 @@ import { wrapFsWithAsar } from './asar-fs-wrapper';
wrapFsWithAsar(require('fs'));
// See ElectronRendererClient::DidCreateScriptContext.
if ((globalThis as any).blinkFetch) {
globalThis.fetch = (globalThis as any).blinkFetch;
if ((globalThis as any).blinkfetch) {
const keys = ['fetch', 'Response', 'FormData', 'Request', 'Headers'];
for (const key of keys) {
(globalThis as any)[key] = (globalThis as any)[`blink${key}`];
}
}
// Hook child_process.fork.

View File

@@ -9,7 +9,7 @@
"@electron/docs-parser": "^1.2.0",
"@electron/fiddle-core": "^1.0.4",
"@electron/github-app-auth": "^2.0.0",
"@electron/lint-roller": "^2.1.0",
"@electron/lint-roller": "^2.2.0",
"@electron/typescript-definitions": "^8.15.2",
"@octokit/rest": "^19.0.7",
"@primer/octicons": "^10.0.0",
@@ -20,7 +20,6 @@
"@types/dirty-chai": "^2.0.2",
"@types/express": "^4.17.13",
"@types/fs-extra": "^9.0.1",
"@types/klaw": "^3.0.1",
"@types/minimist": "^1.2.0",
"@types/mocha": "^7.0.2",
"@types/node": "^20.9.0",
@@ -54,7 +53,6 @@
"fs-extra": "^9.0.1",
"got": "^11.8.5",
"husky": "^8.0.1",
"klaw": "^3.0.0",
"lint": "^1.1.2",
"lint-staged": "^10.2.11",
"markdownlint-cli2": "^0.13.0",

View File

@@ -129,3 +129,4 @@ feat_add_support_for_missing_dialog_features_to_shell_dialogs.patch
fix_font_face_resolution_when_renderer_is_blocked.patch
feat_enable_passing_exit_code_on_service_process_crash.patch
chore_remove_reference_to_chrome_browser_themes.patch
x11_use_localized_display_label_only_for_browser_process.patch

View File

@@ -186,24 +186,10 @@ index 129979e844581e68fdecde87bd52f3344f88022a..5e02a36e5e9eb4db84700dd9a0b8765d
}
diff --git a/ui/gtk/select_file_dialog_linux_gtk.h b/ui/gtk/select_file_dialog_linux_gtk.h
index 53ae15f14c45ee72abdae172fc4555c9e4b3ff9a..af181afd9db1351cd886ba24dd651c7bf2f8a716 100644
index 53ae15f14c45ee72abdae172fc4555c9e4b3ff9a..ee19c3f399a1d060d5e9bd0dc5f1b3828381e8df 100644
--- a/ui/gtk/select_file_dialog_linux_gtk.h
+++ b/ui/gtk/select_file_dialog_linux_gtk.h
@@ -15,6 +15,13 @@
namespace gtk {
+struct ExtraSettings {
+ std::string button_label;
+ bool show_overwrite_confirmation = true;
+ bool show_hidden = false;
+ bool allow_multiple_selection = false;
+};
+
// Implementation of SelectFileDialog that shows a Gtk common dialog for
// choosing a file or folder. This acts as a modal dialog.
class SelectFileDialogLinuxGtk : public ui::SelectFileDialogLinux,
@@ -90,19 +97,23 @@ class SelectFileDialogLinuxGtk : public ui::SelectFileDialogLinux,
@@ -90,19 +90,23 @@ class SelectFileDialogLinuxGtk : public ui::SelectFileDialogLinux,
GtkWidget* CreateSelectFolderDialog(Type type,
const std::string& title,
const base::FilePath& default_path,
@@ -231,7 +217,7 @@ index 53ae15f14c45ee72abdae172fc4555c9e4b3ff9a..af181afd9db1351cd886ba24dd651c7b
// Removes and returns the |params| associated with |dialog| from
// |params_map_|.
@@ -121,7 +132,8 @@ class SelectFileDialogLinuxGtk : public ui::SelectFileDialogLinux,
@@ -121,7 +125,8 @@ class SelectFileDialogLinuxGtk : public ui::SelectFileDialogLinux,
// Common function for CreateFileOpenDialog and CreateMultiFileOpenDialog.
GtkWidget* CreateFileOpenHelper(const std::string& title,
const base::FilePath& default_path,
@@ -241,3 +227,176 @@ index 53ae15f14c45ee72abdae172fc4555c9e4b3ff9a..af181afd9db1351cd886ba24dd651c7b
// Callback for when the user responds to a Save As or Open File dialog.
void OnSelectSingleFileDialogResponse(GtkWidget* dialog, int response_id);
diff --git a/ui/shell_dialogs/select_file_dialog_linux.h b/ui/shell_dialogs/select_file_dialog_linux.h
index 20ad001988831afca73315c577f90c824a36e282..57a8d35ace583eaafb526f70935d21c0f8fd1078 100644
--- a/ui/shell_dialogs/select_file_dialog_linux.h
+++ b/ui/shell_dialogs/select_file_dialog_linux.h
@@ -26,6 +26,13 @@ class SHELL_DIALOGS_EXPORT SelectFileDialogLinux : public SelectFileDialog {
SelectFileDialogLinux(const SelectFileDialogLinux&) = delete;
SelectFileDialogLinux& operator=(const SelectFileDialogLinux&) = delete;
+ struct ExtraSettings {
+ std::string button_label;
+ bool show_overwrite_confirmation = true;
+ bool show_hidden = false;
+ bool allow_multiple_selection = false;
+ };
+
// Returns true if the SelectFileDialog class returned by
// NewSelectFileDialogImplKDE will actually work.
static bool CheckKDEDialogWorksOnUIThread(std::string& kdialog_version);
diff --git a/ui/shell_dialogs/select_file_dialog_linux_kde.cc b/ui/shell_dialogs/select_file_dialog_linux_kde.cc
index c79fb47bfba9233da7d2c1438d1e26600684fc78..d7cc7cd70653aaa5b628ef456dcb48a2eef5ec5e 100644
--- a/ui/shell_dialogs/select_file_dialog_linux_kde.cc
+++ b/ui/shell_dialogs/select_file_dialog_linux_kde.cc
@@ -480,6 +480,9 @@ void SelectFileDialogLinuxKde::CreateSelectFolderDialog(
int title_message_id = (type == SELECT_UPLOAD_FOLDER)
? IDS_SELECT_UPLOAD_FOLDER_DIALOG_TITLE
: IDS_SELECT_FOLDER_DIALOG_TITLE;
+ ExtraSettings extra_settings;
+ if (params)
+ extra_settings = *(static_cast<ExtraSettings*>(params));
pipe_task_runner_->PostTaskAndReplyWithResult(
FROM_HERE,
base::BindOnce(
@@ -487,7 +490,7 @@ void SelectFileDialogLinuxKde::CreateSelectFolderDialog(
KDialogParams(
"--getexistingdirectory", GetTitle(title, title_message_id),
default_path.empty() ? *last_opened_path() : default_path, parent,
- false, false)),
+ false, extra_settings.allow_multiple_selection)),
base::BindOnce(
&SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse, this,
parent, params));
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.cc b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
index 65727489ddecb755eeabbd194ce843ca9eaa59c9..b15bace56639d2f914f8f76edfa1b28e33165b48 100644
--- a/ui/shell_dialogs/select_file_dialog_linux_portal.cc
+++ b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
@@ -219,6 +219,10 @@ void SelectFileDialogLinuxPortal::SelectFileImpl(
info_->main_task_runner = base::SequencedTaskRunner::GetCurrentDefault();
listener_params_ = params;
+ ExtraSettings extra_settings;
+ if (params)
+ extra_settings = *(static_cast<ExtraSettings*>(params));
+
if (owning_window) {
if (auto* root = owning_window->GetRootWindow()) {
if (auto* host = root->GetNativeWindowProperty(
@@ -246,7 +250,7 @@ void SelectFileDialogLinuxPortal::SelectFileImpl(
host_->GetAcceleratedWidget(),
base::BindOnce(
&SelectFileDialogLinuxPortal::SelectFileImplWithParentHandle,
- this, title, default_path, filter_set, default_extension))) {
+ this, title, default_path, filter_set, default_extension, extra_settings))) {
// Return early to skip the fallback below.
return;
} else {
@@ -256,7 +260,7 @@ void SelectFileDialogLinuxPortal::SelectFileImpl(
// No parent, so just use a blank parent handle.
SelectFileImplWithParentHandle(title, default_path, filter_set,
- default_extension, "");
+ default_extension, extra_settings, "");
}
bool SelectFileDialogLinuxPortal::HasMultipleFileTypeChoicesImpl() {
@@ -453,6 +457,7 @@ void SelectFileDialogLinuxPortal::SelectFileImplWithParentHandle(
base::FilePath default_path,
PortalFilterSet filter_set,
base::FilePath::StringType default_extension,
+ const ExtraSettings& settings,
std::string parent_handle) {
bool default_path_exists = CallDirectoryExistsOnUIThread(default_path);
dbus_thread_linux::GetTaskRunner()->PostTask(
@@ -461,7 +466,7 @@ void SelectFileDialogLinuxPortal::SelectFileImplWithParentHandle(
&SelectFileDialogLinuxPortal::DialogInfo::SelectFileImplOnBusThread,
info_, std::move(title), std::move(default_path), default_path_exists,
std::move(filter_set), std::move(default_extension),
- std::move(parent_handle)));
+ std::move(parent_handle), std::move(settings)));
}
void SelectFileDialogLinuxPortal::DialogInfo::SelectFileImplOnBusThread(
@@ -470,7 +475,8 @@ void SelectFileDialogLinuxPortal::DialogInfo::SelectFileImplOnBusThread(
const bool default_path_exists,
PortalFilterSet filter_set,
base::FilePath::StringType default_extension,
- std::string parent_handle) {
+ std::string parent_handle,
+ const ExtraSettings& settings) {
DCHECK(dbus_thread_linux::GetTaskRunner()->RunsTasksInCurrentSequence());
dbus::Bus* bus = AcquireBusOnBusThread();
if (!bus->Connect())
@@ -516,7 +522,7 @@ void SelectFileDialogLinuxPortal::DialogInfo::SelectFileImplOnBusThread(
base::StringPrintf("handle_%d", handle_token_counter_++);
AppendOptions(&writer, response_handle_token, default_path,
- default_path_exists, filter_set);
+ default_path_exists, filter_set, settings);
// The sender part of the handle object contains the D-Bus connection name
// without the prefix colon and with all dots replaced with underscores.
@@ -546,7 +552,8 @@ void SelectFileDialogLinuxPortal::DialogInfo::AppendOptions(
const std::string& response_handle_token,
const base::FilePath& default_path,
const bool default_path_exists,
- const SelectFileDialogLinuxPortal::PortalFilterSet& filter_set) {
+ const SelectFileDialogLinuxPortal::PortalFilterSet& filter_set,
+ const ExtraSettings& settings) {
dbus::MessageWriter options_writer(nullptr);
writer->OpenArray("{sv}", &options_writer);
@@ -554,8 +561,10 @@ void SelectFileDialogLinuxPortal::DialogInfo::AppendOptions(
response_handle_token);
if (type == SelectFileDialog::Type::SELECT_UPLOAD_FOLDER) {
- AppendStringOption(&options_writer, kFileChooserOptionAcceptLabel,
- l10n_util::GetStringUTF8(
+ const std::string accept_label = settings.button_label.empty()
+ ? kFileChooserOptionAcceptLabel
+ : settings.button_label;
+ AppendStringOption(&options_writer, accept_label, l10n_util::GetStringUTF8(
IDS_SELECT_UPLOAD_FOLDER_DIALOG_UPLOAD_BUTTON));
}
@@ -563,6 +572,7 @@ void SelectFileDialogLinuxPortal::DialogInfo::AppendOptions(
type == SelectFileDialog::Type::SELECT_UPLOAD_FOLDER ||
type == SelectFileDialog::Type::SELECT_EXISTING_FOLDER) {
AppendBoolOption(&options_writer, kFileChooserOptionDirectory, true);
+ AppendBoolOption(&options_writer, kFileChooserOptionMultiple, settings.allow_multiple_selection);
} else if (type == SelectFileDialog::Type::SELECT_OPEN_MULTI_FILE) {
AppendBoolOption(&options_writer, kFileChooserOptionMultiple, true);
}
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.h b/ui/shell_dialogs/select_file_dialog_linux_portal.h
index c487f7da19e2d05696a8eb72f2fa3e12972149f3..02a40c571570974dcc61e1b1f7ed95fbfc2bedf2 100644
--- a/ui/shell_dialogs/select_file_dialog_linux_portal.h
+++ b/ui/shell_dialogs/select_file_dialog_linux_portal.h
@@ -115,7 +115,8 @@ class SelectFileDialogLinuxPortal : public SelectFileDialogLinux {
const bool default_path_exists,
PortalFilterSet filter_set,
base::FilePath::StringType default_extension,
- std::string parent_handle);
+ std::string parent_handle,
+ const ExtraSettings& settings);
Type type;
// The task runner the SelectFileImpl method was called on.
scoped_refptr<base::SequencedTaskRunner> main_task_runner;
@@ -143,7 +144,8 @@ class SelectFileDialogLinuxPortal : public SelectFileDialogLinux {
const std::string& response_handle_token,
const base::FilePath& default_path,
const bool derfault_path_exists,
- const PortalFilterSet& filter_set);
+ const PortalFilterSet& filter_set,
+ const ExtraSettings& settings);
void AppendFilterStruct(dbus::MessageWriter* writer,
const PortalFilter& filter);
std::vector<base::FilePath> ConvertUrisToPaths(
@@ -190,6 +192,7 @@ class SelectFileDialogLinuxPortal : public SelectFileDialogLinux {
base::FilePath default_path,
PortalFilterSet filter_set,
base::FilePath::StringType default_extension,
+ const ExtraSettings& settings,
std::string parent_handle);
void DialogCreatedOnMainThread();

View File

@@ -0,0 +1,62 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: deepak1556 <hop2deep@gmail.com>
Date: Mon, 17 Jun 2024 18:05:47 +0000
Subject: Use localized display label only for browser process
With https://crrev.com/c/5098130, GetPrimaryDisplayRefreshIntervalFromXrandr uses BuildDisplaysFromXRandRInfo
to calculate the primary display frequency. In software compositing mode --disable-gpu-compositing,
this code path will be called from the gpu process via SoftwareOutputSurface::SwapBuffers and
can trigger a crash when attempting to set localized string. This is because on linux,
gpu process does not have access to the resource bundle.
Bug: none
Change-Id: I9d66b98c07a1a8671369546d4fc685213904a84f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5631219
Auto-Submit: Deepak Mohan (Robo) <hop2deep@gmail.com>
Reviewed-by: Thomas Anderson <thomasanderson@chromium.org>
Reviewed-by: Scott Violet <sky@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1315980}
diff --git a/ui/base/x/x11_display_util.cc b/ui/base/x/x11_display_util.cc
index ffaea4fef9931050f1c1888674bf2f7498c578da..faf59929eb7e291502c449631e54f3841582bd9e 100644
--- a/ui/base/x/x11_display_util.cc
+++ b/ui/base/x/x11_display_util.cc
@@ -299,6 +299,7 @@ std::vector<display::Display> BuildDisplaysFromXRandRInfo(
const display::DisplayConfig& display_config,
size_t* primary_display_index_out) {
DCHECK(primary_display_index_out);
+ auto* command_line = base::CommandLine::ForCurrentProcess();
const float primary_scale = display_config.primary_scale;
auto* connection = x11::Connection::Get();
@@ -348,7 +349,7 @@ std::vector<display::Display> BuildDisplaysFromXRandRInfo(
connection->Flush();
std::vector<x11::Future<x11::GetPropertyReply>> icc_futures{n_iccs};
- if (!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kHeadless)) {
+ if (!command_line->HasSwitch(switches::kHeadless)) {
for (size_t monitor = 0; monitor < n_iccs; ++monitor) {
icc_futures[monitor] = GetIccProfileFuture(connection, monitor);
}
@@ -446,11 +447,18 @@ std::vector<display::Display> BuildDisplaysFromXRandRInfo(
}
const std::string name(output_info->name.begin(), output_info->name.end());
+ auto process_type =
+ command_line->GetSwitchValueASCII("type");
if (base::StartsWith(name, "eDP") || base::StartsWith(name, "LVDS")) {
display::SetInternalDisplayIds({display_id});
- // Use localized variant of "Built-in display" for internal displays.
+ // For browser process which has access to resource bundle,
+ // use localized variant of "Built-in display" for internal displays.
// This follows the ozone DRM behavior (i.e. ChromeOS).
- display.set_label(l10n_util::GetStringUTF8(IDS_DISPLAY_NAME_INTERNAL));
+ if (process_type.empty()) {
+ display.set_label(l10n_util::GetStringUTF8(IDS_DISPLAY_NAME_INTERNAL));
+ } else {
+ display.set_label("Built-in display");
+ }
} else {
display.set_label(edid_parser.display_name());
}

View File

@@ -1256,10 +1256,10 @@ index 0000000000000000000000000000000000000000..af9cbada10203b387fb9732b346583b1
+}
diff --git a/filenames.json b/filenames.json
new file mode 100644
index 0000000000000000000000000000000000000000..1a9cba024f1762b0dfe31da92213b51e112101ec
index 0000000000000000000000000000000000000000..fd42e2a5e6163ff70db0f716d2f9a32f13cdf668
--- /dev/null
+++ b/filenames.json
@@ -0,0 +1,739 @@
@@ -0,0 +1,734 @@
+// This file is automatically generated by generate_gn_filenames_json.py
+// DO NOT EDIT
+{
@@ -1292,7 +1292,7 @@ index 0000000000000000000000000000000000000000..1a9cba024f1762b0dfe31da92213b51e
+ ]
+ },
+ {
+ "dest_dir": "include/node//",
+ "dest_dir": "include/node/./",
+ "files": [
+ "//v8/include/v8-array-buffer.h",
+ "//v8/include/v8-callbacks.h",
@@ -1346,11 +1346,12 @@ index 0000000000000000000000000000000000000000..1a9cba024f1762b0dfe31da92213b51e
+ "//v8/include/v8-wasm.h",
+ "//v8/include/v8-weak-callback-info.h",
+ "//v8/include/v8.h",
+ "//v8/include/v8config.h"
+ "//v8/include/v8config.h",
+ "deps/uv/include/uv.h"
+ ]
+ },
+ {
+ "dest_dir": "include/node//libplatform/",
+ "dest_dir": "include/node/libplatform/",
+ "files": [
+ "//v8/include/libplatform/libplatform-export.h",
+ "//v8/include/libplatform/libplatform.h",
@@ -1358,7 +1359,7 @@ index 0000000000000000000000000000000000000000..1a9cba024f1762b0dfe31da92213b51e
+ ]
+ },
+ {
+ "dest_dir": "include/node//cppgc/",
+ "dest_dir": "include/node/cppgc/",
+ "files": [
+ "//v8/include/cppgc/allocation.h",
+ "//v8/include/cppgc/common.h",
@@ -1391,7 +1392,7 @@ index 0000000000000000000000000000000000000000..1a9cba024f1762b0dfe31da92213b51e
+ ]
+ },
+ {
+ "dest_dir": "include/node//cppgc/internal/",
+ "dest_dir": "include/node/cppgc/internal/",
+ "files": [
+ "//v8/include/cppgc/internal/api-constants.h",
+ "//v8/include/cppgc/internal/atomic-entry-flag.h",
@@ -1410,13 +1411,7 @@ index 0000000000000000000000000000000000000000..1a9cba024f1762b0dfe31da92213b51e
+ ]
+ },
+ {
+ "dest_dir": "include/node//",
+ "files": [
+ "deps/uv/include/uv.h"
+ ]
+ },
+ {
+ "dest_dir": "include/node//uv/",
+ "dest_dir": "include/node/uv/",
+ "files": [
+ "deps/uv/include/uv/aix.h",
+ "deps/uv/include/uv/bsd.h",
@@ -1891,7 +1886,7 @@ index 0000000000000000000000000000000000000000..1a9cba024f1762b0dfe31da92213b51e
+ "src/dataqueue/queue.h",
+ "src/debug_utils.h",
+ "src/debug_utils-inl.h",
+ "src/embeded_data.h",
+ "src/embedded_data.h",
+ "src/encoding_binding.h",
+ "src/env_properties.h",
+ "src/env.h",
@@ -2243,10 +2238,10 @@ index 75a7f3dd89e096d13ad7d70ed29d301cd56315b5..9a20a275fbe5df9f384b7b1d1d26806e
// bootstrap scripts, whose source are bundled into the binary as static data.
diff --git a/tools/generate_gn_filenames_json.py b/tools/generate_gn_filenames_json.py
new file mode 100755
index 0000000000000000000000000000000000000000..7848ddb1841b6d4f36e9376c73564eb4ff6d7c08
index 0000000000000000000000000000000000000000..37c16859003e61636fe2f1a4040b1e904c472d0b
--- /dev/null
+++ b/tools/generate_gn_filenames_json.py
@@ -0,0 +1,90 @@
@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+import json
+import os
@@ -2276,6 +2271,14 @@ index 0000000000000000000000000000000000000000..7848ddb1841b6d4f36e9376c73564eb4
+// DO NOT EDIT
+'''.lstrip()
+
+SRC_DIR = os.path.abspath(os.path.join(__file__, '..', '..', '..', '..'))
+
+def get_out_dir():
+ out_dir = 'Testing'
+ override = os.environ.get('ELECTRON_OUT_DIR')
+ if override is not None:
+ out_dir = override
+ return os.path.join(SRC_DIR, 'out', out_dir)
+
+if __name__ == '__main__':
+ node_root_dir = os.path.dirname(os.path.dirname(__file__))
@@ -2294,18 +2297,25 @@ index 0000000000000000000000000000000000000000..7848ddb1841b6d4f36e9376c73564eb4
+ }
+
+ def filter_v8_files(files):
+ if any(f.startswith('deps/v8/') for f in files):
+ files = [f.replace('deps/v8/', '../../v8/', 1) if f.endswith('js') else f.replace('deps/v8/', '//v8/') for f in files]
+ v8_files = [f for f in files if f.startswith('deps/v8/')]
+ other_files = [f for f in files if not f.startswith('deps/v8/')]
+
+ if any(f == '<@(node_builtin_shareable_builtins)' for f in files):
+ files.remove('<@(node_builtin_shareable_builtins)')
+ for i, f in enumerate(v8_files):
+ if not f.startswith('deps/v8/tools'):
+ if f.endswith('js'):
+ v8_files[i] = f.replace('deps/v8/', '../../v8/', 1)
+ else:
+ v8_files[i] = f.replace('deps/v8/', '//v8/')
+
+ if any(f == '<@(node_builtin_shareable_builtins)' for f in other_files):
+ other_files.remove('<@(node_builtin_shareable_builtins)')
+ shared_builtins = ['deps/cjs-module-lexer/lexer.js', 'deps/cjs-module-lexer/dist/lexer.js', 'deps/undici/undici.js']
+ files.extend(shared_builtins)
+ other_files.extend(shared_builtins)
+
+ return files
+ return v8_files + other_files
+
+ def filter_fs_files(files):
+ return [f for f in files if f.startswith('lib/internal/fs/')] + ['lib/fs.js']
+ return [f for f in files if f.startswith('lib/internal/fs/')] + ['lib/fs.js'] + ['lib/fs/promises.js']
+
+ lib_files = SearchFiles('lib', 'js')
+ out['library_files'] = filter_v8_files(lib_files)
@@ -2322,17 +2332,29 @@ index 0000000000000000000000000000000000000000..7848ddb1841b6d4f36e9376c73564eb4
+ out['node_sources'] += filter_v8_files(blocklisted_sources)
+
+ out['headers'] = []
+ def add_headers(files, dest_dir):
+ def add_headers(options, files, dest_dir):
+ if 'src/node.h' in files:
+ files = [f for f in files if f.endswith('.h') and f != 'src/node_version.h']
+ elif any(f.startswith('../../v8/') for f in files):
+ files = [f.replace('../../v8/', '//v8/', 1) for f in files]
+ if files:
+ hs = {'files': sorted(files), 'dest_dir': dest_dir}
+ out['headers'].append(hs)
+ dir_index = next((i for i, d in enumerate(out['headers']) if d['dest_dir'] == dest_dir), -1)
+ if (dir_index != -1):
+ out['headers'][dir_index]['files'] += sorted(files)
+ else:
+ hs = {'files': sorted(files), 'dest_dir': dest_dir}
+ out['headers'].append(hs)
+
+ install.variables = {'node_shared_libuv': 'false'}
+ install.headers(add_headers)
+ config_gypi_path = os.path.join(get_out_dir(), 'gen', 'config.gypi')
+ root_gen_dir = os.path.join(node_root_dir, 'out', 'Release', 'gen')
+
+ options = install.parse_options(['install', '--v8-dir', '../../v8', '--config-gypi-path', config_gypi_path, '--headers-only'])
+ options.variables['node_use_openssl'] = 'false'
+ options.variables['node_shared_libuv'] = 'false'
+ # We generate zlib headers in Electron's BUILD.gn.
+ options.variables['node_shared_zlib'] = ''
+
+ install.headers(options, add_headers)
+ with open(os.path.join(node_root_dir, 'filenames.json'), 'w') as f:
+ f.write(FILENAMES_JSON_HEADER)
+ f.write(json.dumps(out, sort_keys=True, indent=2, separators=(',', ': ')))
@@ -2363,18 +2385,27 @@ index 0000000000000000000000000000000000000000..9be3ac447f9a4dde23fefc26e0b922b4
+ transformed_f.write(transformed_contents)
+
diff --git a/tools/install.py b/tools/install.py
index b132c7bf26c02886a7ab341a1973bf449744ba0f..171b383a4b6c2528d11dd5f89a6837fd071bcf4b 100755
index b132c7bf26c02886a7ab341a1973bf449744ba0f..757e3e60a7be01fac55c5fbb010dbbae00b1bfca 100755
--- a/tools/install.py
+++ b/tools/install.py
@@ -284,6 +284,7 @@ def headers(options, action):
@@ -264,6 +264,7 @@ def headers(options, action):
'include/v8-forward.h',
'include/v8-function-callback.h',
'include/v8-function.h',
+ 'include/v8-handle-base.h',
'include/v8-initialization.h',
'include/v8-internal.h',
'include/v8-isolate.h',
@@ -284,6 +285,8 @@ def headers(options, action):
'include/v8-promise.h',
'include/v8-proxy.h',
'include/v8-regexp.h',
+ "include/v8-sandbox.h",
+ "include/v8-source-location.h",
'include/v8-script.h',
'include/v8-snapshot.h',
'include/v8-statistics.h',
@@ -390,7 +391,7 @@ def parse_options(args):
@@ -390,7 +393,7 @@ def parse_options(args):
parser.add_argument('--build-dir', help='the location of built binaries',
default='out/Release')
parser.add_argument('--v8-dir', help='the location of V8',

View File

@@ -1,34 +1,82 @@
#!/bin/sh
#!/bin/bash
set -eo pipefail
if [ -z "$MAS_BUILD" ]; then
BUILD_TYPE="darwin"
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
BUILD_TYPE="mas"
echo "Unsupported platform"
exit 1
fi
echo Creating generated_artifacts_${BUILD_TYPE}_${TARGET_ARCH}...
rm -rf generated_artifacts_${BUILD_TYPE}_${TARGET_ARCH}
mkdir generated_artifacts_${BUILD_TYPE}_${TARGET_ARCH}
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_${BUILD_TYPE}_${TARGET_ARCH}
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_${BUILD_TYPE}_${TARGET_ARCH}
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
@@ -39,3 +87,5 @@ 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

View File

@@ -1,17 +1,30 @@
#!/bin/bash
set -eo pipefail
GENERATED_ARTIFACTS="generated_artifacts_${BUILD_TYPE}_${TARGET_ARCH}"
SRC_ARTIFACTS="src_artifacts_${BUILD_TYPE}_${TARGET_ARCH}"
mv_if_exist() {
if [ -f "generated_artifacts_${BUILD_TYPE}_${TARGET_ARCH}/$1" ] || [ -d "generated_artifacts_${BUILD_TYPE}_${TARGET_ARCH}/$1" ]; then
if [ -f "${GENERATED_ARTIFACTS}/$1" ] || [ -d "${GENERATED_ARTIFACTS}/$1" ]; then
echo Restoring $1 to $2
mkdir -p $2
mv generated_artifacts_${BUILD_TYPE_${TARGET_ARCH}}/$1 $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
@@ -19,4 +32,9 @@ 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
mv_if_exist cross-arch-snapshots src
echo Restoring artifacts from $SRC_ARTIFACTS
# Restore src artifacts
untar_if_exist src_artifacts.tar

7
script/actions/run-tests.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
set -euo pipefail
export DISPLAY=:99
Xvfb :99 -screen 0 1024x768x16 -ac &
XVFB_PID=$!
node "$@"

View File

@@ -36,12 +36,10 @@ addAllFiles(path.resolve(__dirname, '../patches'));
// Create Hash
const hasher = crypto.createHash('SHA256');
const addToHashAndLog = (s) => {
console.log('Hashing:', s);
return hasher.update(s);
};
addToHashAndLog(`HASH_VERSION:${HASH_VERSIONS[process.platform] || FALLBACK_HASH_VERSION}`);
for (const file of filesToHash) {
console.log('Hashing Content:', file, crypto.createHash('SHA256').update(fs.readFileSync(file)).digest('hex'));
hasher.update(fs.readFileSync(file));
}

View File

@@ -4,6 +4,7 @@ import contextlib
import errno
import json
import os
import platform
import shutil
import subprocess
import sys
@@ -158,7 +159,7 @@ def azput(prefix, key_prefix, files):
print(output)
def get_out_dir():
out_dir = 'Debug'
out_dir = 'Default'
override = os.environ.get('ELECTRON_OUT_DIR')
if override is not None:
out_dir = override
@@ -184,13 +185,16 @@ def get_electron_exec():
def get_buildtools_executable(name):
buildtools = os.path.realpath(os.path.join(ELECTRON_DIR, '..', 'buildtools'))
chromium_platform = {
'darwin': 'mac',
'linux': 'linux64',
'linux2': 'linux64',
'win32': 'win',
'cygwin': 'win',
}[sys.platform]
if sys.platform == 'darwin':
chromium_platform = 'mac_arm64' if platform.machine() == 'arm64' else 'mac'
elif sys.platform in ['win32', 'cygwin']:
chromium_platform = 'win'
elif sys.platform in ['linux', 'linux2']:
chromium_platform = 'linux64'
else:
raise Exception(f"Unsupported platform: {sys.platform}")
if name == 'clang-format':
path = os.path.join(buildtools, f"{chromium_platform}-format", name)
else:

View File

@@ -1,6 +1,5 @@
const { GitProcess } = require('dugite');
const fs = require('node:fs');
const klaw = require('klaw');
const os = require('node:os');
const path = require('node:path');
@@ -130,18 +129,13 @@ function chunkFilenames (filenames, offset = 0) {
* @returns {Promise<string[]>}
*/
async function findMatchingFiles (top, test) {
return new Promise(resolve => {
const matches = [];
klaw(top, {
filter: f => path.basename(f) !== '.bin'
})
.on('end', () => resolve(matches))
.on('data', item => {
if (test(item.path)) {
matches.push(item.path);
}
});
});
return fs.promises.readdir(top, { encoding: 'utf8', recursive: true })
.then(files => {
return files
.filter(name => path.basename(name) !== '.bin')
.filter(name => test(name))
.map(name => path.join(top, name));
});
}
module.exports = {

View File

@@ -90,16 +90,16 @@ async function main () {
env.LDFLAGS = ldflags;
}
const { status: buildStatus } = cp.spawnSync(NPX_CMD, ['node-gyp', 'rebuild', '--verbose', '--directory', 'test', '-j', 'max'], {
const { status: buildStatus, signal } = cp.spawnSync(NPX_CMD, ['node-gyp', 'rebuild', '--verbose', '--directory', 'test', '-j', 'max'], {
env,
cwd: NAN_DIR,
stdio: 'inherit',
shell: process.platform === 'win32'
});
if (buildStatus !== 0) {
if (buildStatus !== 0 || signal != null) {
console.error('Failed to build nan test modules');
return process.exit(buildStatus);
return process.exit(buildStatus !== 0 ? buildStatus : signal);
}
const { status: installStatus } = cp.spawnSync(NPX_CMD, [`yarn@${YARN_VERSION}`, 'install'], {
@@ -108,9 +108,10 @@ async function main () {
stdio: 'inherit',
shell: process.platform === 'win32'
});
if (installStatus !== 0) {
if (installStatus !== 0 || signal != null) {
console.error('Failed to install nan node_modules');
return process.exit(installStatus);
return process.exit(installStatus !== 0 ? installStatus : signal);
}
const onlyTests = args.only && args.only.split(',');

View File

@@ -4,6 +4,8 @@
"parallel/test-bootstrap-modules",
"parallel/test-child-process-fork-exec-path",
"parallel/test-code-cache",
"parallel/test-cluster-primary-error",
"parallel/test-cluster-primary-kill",
"parallel/test-crypto-aes-wrap",
"parallel/test-crypto-authenticated-stream",
"parallel/test-crypto-des3-wrap",

View File

@@ -33,6 +33,7 @@ const circleCIPublishIndividualArches = {
};
const ghActionsPublishWorkflows = [
'linux-publish',
'macos-publish'
];
@@ -92,7 +93,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
},

View File

@@ -158,9 +158,10 @@ async function pushRelease (branch) {
}
}
async function runReleaseBuilds (branch) {
async function runReleaseBuilds (branch, newVersion) {
await ciReleaseBuild(branch, {
ghRelease: true
ghRelease: true,
newVersion
});
}
@@ -190,6 +191,8 @@ async function verifyNewVersion () {
console.log(`${fail} Aborting release of ${newVersion}`);
process.exit();
}
return newVersion;
}
async function promptForVersion (version) {
@@ -225,10 +228,10 @@ async function prepareRelease (isBeta, notesOnly) {
} else {
const changes = await changesToRelease();
if (changes) {
await verifyNewVersion();
const newVersion = await verifyNewVersion();
await createRelease(currentBranch, isBeta);
await pushRelease(currentBranch);
await runReleaseBuilds(currentBranch);
await runReleaseBuilds(currentBranch, newVersion);
} else {
console.log('There are no new changes to this branch since the last release, aborting release.');
process.exit(1);

32
script/split-tests.js Normal file
View File

@@ -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(' '));

View File

@@ -1270,10 +1270,17 @@ std::vector<gin_helper::Dictionary> App::GetAppMetrics(v8::Isolate* isolate) {
auto pid_dict = gin_helper::Dictionary::CreateEmpty(isolate);
auto cpu_dict = gin_helper::Dictionary::CreateEmpty(isolate);
double usage =
process_metric.second->metrics->GetPlatformIndependentCPUUsage()
.value_or(0);
cpu_dict.Set("percentCPUUsage", usage / processor_count);
// Default usage percentage to 0 for compatibility
double usagePercent = 0;
if (auto usage = process_metric.second->metrics->GetCumulativeCPUUsage();
usage.has_value()) {
cpu_dict.Set("cumulativeCPUUsage", usage->InSecondsF());
usagePercent =
process_metric.second->metrics->GetPlatformIndependentCPUUsage(
*usage);
}
cpu_dict.Set("percentCPUUsage", usagePercent / processor_count);
#if !BUILDFLAG(IS_WIN)
cpu_dict.Set("idleWakeupsPerSecond",

View File

@@ -1893,6 +1893,8 @@ void WebContents::OnFirstNonEmptyLayout(
}
}
namespace {
// This object wraps the InvokeCallback so that if it gets GC'd by V8, we can
// still call the callback and send an error. Not doing so causes a Mojo DCHECK,
// since Mojo requires callbacks to be called before they are destroyed.
@@ -1949,6 +1951,8 @@ class ReplyChannel : public gin::Wrappable<ReplyChannel> {
gin::WrapperInfo ReplyChannel::kWrapperInfo = {gin::kEmbedderNativeGin};
} // namespace
gin::Handle<gin_helper::internal::Event> WebContents::MakeEventWithSender(
v8::Isolate* isolate,
content::RenderFrameHost* frame,

View File

@@ -236,6 +236,10 @@ class Browser : private WindowListObserver {
// Set docks' icon.
void DockSetIcon(v8::Isolate* isolate, v8::Local<v8::Value> icon);
void SetLaunchedAtLogin(bool launched_at_login) {
was_launched_at_login_ = launched_at_login;
}
#endif // BUILDFLAG(IS_MAC)
void ShowAboutPanel();
@@ -370,6 +374,7 @@ class Browser : private WindowListObserver {
#if BUILDFLAG(IS_MAC)
std::unique_ptr<ui::ScopedPasswordInputEnabler> password_input_enabler_;
base::Time last_dock_show_;
bool was_launched_at_login_;
#endif
base::Value::Dict about_panel_options_;

View File

@@ -25,6 +25,8 @@
namespace electron {
namespace {
const char kXdgSettings[] = "xdg-settings";
const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler";
@@ -84,6 +86,8 @@ bool SetDefaultWebClient(const std::string& protocol) {
return ran_ok && exit_code == EXIT_SUCCESS;
}
} // namespace
void Browser::AddRecentDocument(const base::FilePath& path) {}
void Browser::ClearRecentDocuments() {}

View File

@@ -392,6 +392,7 @@ v8::Local<v8::Value> Browser::GetLoginItemSettings(
platform_util::GetLoginItemEnabled(options.type, options.service_name);
settings.open_at_login =
status == "enabled" || status == "enabled-deprecated";
settings.opened_at_login = was_launched_at_login_;
if (@available(macOS 13, *))
settings.status = status;
#else
@@ -405,6 +406,7 @@ v8::Local<v8::Value> Browser::GetLoginItemSettings(
settings = settings_deprecated;
} else {
settings.open_at_login = status == "enabled";
settings.opened_at_login = was_launched_at_login_;
settings.status = status;
}
} else {

View File

@@ -18,6 +18,10 @@
#include "shell/common/thread_restrictions.h"
#endif
namespace electron {
namespace {
constexpr std::string_view kElectronOzonePlatformHint{
"ELECTRON_OZONE_PLATFORM_HINT"};
@@ -55,10 +59,6 @@ bool HasWaylandDisplay(base::Environment* env) {
constexpr char kPlatformX11[] = "x11";
#endif
namespace electron {
namespace {
// Evaluates the environment and returns the effective platform name for the
// given |ozone_platform_hint|.
// For the "auto" value, returns "wayland" if the XDG session type is "wayland",

View File

@@ -46,8 +46,8 @@ class ElectronHidDelegate::ContextObservation
ContextObservation(ElectronHidDelegate* parent,
content::BrowserContext* browser_context)
: parent_(parent), browser_context_(browser_context) {
auto* chooser_context = GetChooserContext(browser_context_);
device_observation_.Observe(chooser_context);
if (auto* chooser_context = GetChooserContext(browser_context_))
device_observation_.Observe(chooser_context);
}
ContextObservation(ContextObservation&) = delete;

View File

@@ -124,13 +124,10 @@ JavascriptEnvironment::~JavascriptEnvironment() {
v8::Isolate* JavascriptEnvironment::Initialize(uv_loop_t* event_loop,
bool setup_wasm_streaming) {
auto* cmd = base::CommandLine::ForCurrentProcess();
// --js-flags.
std::string js_flags =
cmd->GetSwitchValueASCII(blink::switches::kJavaScriptFlags);
js_flags.append(" --no-freeze-flags-after-init");
if (!js_flags.empty())
v8::V8::SetFlagsFromString(js_flags.c_str(), js_flags.size());
std::string js_flags = "--no-freeze-flags-after-init ";
js_flags.append(cmd->GetSwitchValueASCII(blink::switches::kJavaScriptFlags));
v8::V8::SetFlagsFromString(js_flags.c_str(), js_flags.size());
// The V8Platform of gin relies on Chromium's task schedule, which has not
// been started at this point, so we have to rely on Node's V8Platform.

View File

@@ -84,6 +84,14 @@ static NSDictionary* UNNotificationResponseToNSDictionary(
}
}
NSAppleEventDescriptor* event =
NSAppleEventManager.sharedAppleEventManager.currentAppleEvent;
BOOL launched_as_login_item =
(event.eventID == kAEOpenApplication &&
[event paramDescriptorForKeyword:keyAEPropData].enumCodeValue ==
keyAELaunchedAsLogInItem);
electron::Browser::Get()->SetLaunchedAtLogin(launched_as_login_item);
electron::Browser::Get()->DidFinishLaunching(
electron::NSDictionaryToValue(notification_info));
}

View File

@@ -67,8 +67,9 @@ class FileChooserDialog : public ui::SelectFileDialog::Listener {
~FileChooserDialog() override = default;
gtk::ExtraSettings GetExtraSettings(const DialogSettings& settings) {
gtk::ExtraSettings extra;
ui::SelectFileDialogLinux::ExtraSettings GetExtraSettings(
const DialogSettings& settings) {
ui::SelectFileDialogLinux::ExtraSettings extra;
extra.button_label = settings.button_label;
extra.show_overwrite_confirmation =
settings.properties & SAVE_DIALOG_SHOW_OVERWRITE_CONFIRMATION;

View File

@@ -94,7 +94,8 @@ class ElectronUsbDelegate::ContextObservation
content::BrowserContext* browser_context)
: parent_(parent), browser_context_(browser_context) {
auto* chooser_context = GetChooserContext(browser_context_);
device_observation_.Observe(chooser_context);
if (chooser_context)
device_observation_.Observe(chooser_context);
}
ContextObservation(ContextObservation&) = delete;
ContextObservation& operator=(ContextObservation&) = delete;

View File

@@ -274,8 +274,15 @@ v8::Local<v8::Value> ElectronBindings::GetCPUUsage(
v8::Isolate* isolate) {
auto dict = gin_helper::Dictionary::CreateEmpty(isolate);
int processor_count = base::SysInfo::NumberOfProcessors();
double usage = metrics->GetPlatformIndependentCPUUsage().value_or(0);
dict.Set("percentCPUUsage", usage / processor_count);
// Default usage percentage to 0 for compatibility
double usagePercent = 0;
if (auto usage = metrics->GetCumulativeCPUUsage(); usage.has_value()) {
dict.Set("cumulativeCPUUsage", usage->InSecondsF());
usagePercent = metrics->GetPlatformIndependentCPUUsage(*usage);
}
dict.Set("percentCPUUsage", usagePercent / processor_count);
// NB: This will throw NOTIMPLEMENTED() on Windows
// For backwards compatibility, we'll return 0

View File

@@ -250,6 +250,8 @@ bool Converter<net::HttpRequestHeaders>::FromV8(v8::Isolate* isolate,
return true;
}
namespace {
class ChunkedDataPipeReadableStream
: public gin::Wrappable<ChunkedDataPipeReadableStream> {
public:
@@ -489,9 +491,12 @@ class ChunkedDataPipeReadableStream
v8::Global<v8::ArrayBufferView> buf_;
gin_helper::Promise<int> promise_;
};
gin::WrapperInfo ChunkedDataPipeReadableStream::kWrapperInfo = {
gin::kEmbedderNativeGin};
} // namespace
// static
v8::Local<v8::Value> Converter<network::ResourceRequestBody>::ToV8(
v8::Isolate* isolate,

View File

@@ -111,7 +111,7 @@ std::string GetLaunchStringForError(NSError* error) {
return "The specified path doesn't exist or the helper tool at the "
"specified path isn't valid";
default:
return "Failed to register the login item";
return base::SysNSStringToUTF8([error localizedDescription]);
}
}

View File

@@ -110,19 +110,25 @@ void ElectronRendererClient::DidCreateScriptContext(
base::BindRepeating(&ElectronRendererClient::UndeferLoad,
base::Unretained(this), render_frame));
v8::Local<v8::Object> global = renderer_context->Global();
v8::MaybeLocal<v8::Value> fetch =
global->Get(renderer_context, gin::StringToV8(env->isolate(), "fetch"));
// We need to use the Blink implementation of fetch in the renderer process
// Node.js deletes the global fetch function when their fetch implementation
// is disabled, so we need to save and re-add it after the Node.js environment
// is loaded. See corresponding change in node/init.ts.
if (!fetch.IsEmpty()) {
global
->Set(renderer_context, gin::StringToV8(env->isolate(), "blinkFetch"),
fetch.ToLocalChecked())
.Check();
v8::Isolate* isolate = env->isolate();
v8::Local<v8::Object> global = renderer_context->Global();
std::vector<std::string> keys = {"fetch", "Response", "FormData", "Request",
"Headers"};
for (const auto& key : keys) {
v8::MaybeLocal<v8::Value> value =
global->Get(renderer_context, gin::StringToV8(isolate, key.c_str()));
if (!value.IsEmpty()) {
std::string blink_key = "blink" + key;
global
->Set(renderer_context, gin::StringToV8(isolate, blink_key.c_str()),
value.ToLocalChecked())
.Check();
}
}
// If we have disabled the site instance overrides we should prevent loading

View File

@@ -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';
@@ -1442,6 +1442,7 @@ describe('app module', () => {
types.push(entry.type);
expect(entry.cpu).to.have.ownProperty('percentCPUUsage').that.is.a('number');
expect(entry.cpu).to.have.ownProperty('cumulativeCPUUsage').that.is.a('number');
expect(entry.cpu).to.have.ownProperty('idleWakeupsPerSecond').that.is.a('number');
expect(entry.memory).to.have.property('workingSetSize').that.is.greaterThan(0);

View File

@@ -25,7 +25,12 @@ ifdescribe(!(['arm', 'arm64'].includes(process.arch)) || (process.platform !== '
});
describe('startRecording', function () {
this.timeout(5e3);
if (process.platform === 'win32' && process.arch === 'arm64') {
// WOA needs more time
this.timeout(10e3);
} else {
this.timeout(5e3);
}
const getFileSizeInKiloBytes = (filePath: string) => {
const stats = fs.statSync(filePath);
@@ -84,7 +89,12 @@ ifdescribe(!(['arm', 'arm64'].includes(process.arch)) || (process.platform !== '
});
describe('stopRecording', function () {
this.timeout(5e3);
if (process.platform === 'win32' && process.arch === 'arm64') {
// WOA needs more time
this.timeout(10e3);
} else {
this.timeout(5e3);
}
it('does not crash on empty string', async () => {
const options = {

View File

@@ -26,6 +26,7 @@ describe('process module', () => {
it('returns a cpu usage object', async () => {
const cpuUsage = await w.webContents.executeJavaScript('process.getCPUUsage()');
expect(cpuUsage.percentCPUUsage).to.be.a('number');
expect(cpuUsage.cumulativeCPUUsage).to.be.a('number');
expect(cpuUsage.idleWakeupsPerSecond).to.be.a('number');
});
});
@@ -124,6 +125,7 @@ describe('process module', () => {
it('returns a cpu usage object', () => {
const cpuUsage = process.getCPUUsage();
expect(cpuUsage.percentCPUUsage).to.be.a('number');
expect(cpuUsage.cumulativeCPUUsage).to.be.a('number');
expect(cpuUsage.idleWakeupsPerSecond).to.be.a('number');
});
});

View File

@@ -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);
});
});
});

View File

@@ -8,7 +8,7 @@ const fixturesPath = path.resolve(__dirname, '..', 'fixtures');
export const shouldRunCodesignTests =
process.platform === 'darwin' &&
!(process.env.CI && process.arch === 'arm64') &&
!process.env.CI &&
!process.mas &&
!features.isComponentBuild();

View File

@@ -199,10 +199,10 @@
"@octokit/auth-app" "^4.0.13"
"@octokit/rest" "^19.0.11"
"@electron/lint-roller@^2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@electron/lint-roller/-/lint-roller-2.1.0.tgz#984ec017c8d512e77e34749e7f6dc965aec8de06"
integrity sha512-Oxt7CHq7FNujOi5g0nYq3hwVvspnDk/DCp7C+52pHi3Ez7P85K8dY3QlGtm9Dpswm3t7SJmk6m1pfFzXWre1dg==
"@electron/lint-roller@^2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@electron/lint-roller/-/lint-roller-2.2.0.tgz#3390ea37868b1ac35863cd393ddf776d049a2e3c"
integrity sha512-gYOwL7p3vXJjzndzW0ewnYuBz+WcNOGCbqNBJLmoVwimHGdNJ7cdh9/AwAggcjHEPO/zpRMfpfhUM7shNPagCQ==
dependencies:
"@dsanders11/vscode-markdown-languageservice" "^0.3.0"
balanced-match "^2.0.0"
@@ -880,13 +880,6 @@
dependencies:
"@types/node" "*"
"@types/klaw@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/klaw/-/klaw-3.0.1.tgz#29f90021c0234976aa4eb97efced9cb6db9fa8b3"
integrity sha512-acnF3n9mYOr1aFJKFyvfNX0am9EtPUsYPq22QUCGdJE+MVt6UyAN1jwo+PmOPqXD4K7ZS9MtxDEp/un0lxFccA==
dependencies:
"@types/node" "*"
"@types/linkify-it@*":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-2.1.0.tgz#ea3dd64c4805597311790b61e872cbd1ed2cd806"
@@ -3348,7 +3341,7 @@ got@^11.8.5:
p-cancelable "^2.0.0"
responselike "^2.0.0"
graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9:
graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9:
version "4.2.10"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
@@ -4016,13 +4009,6 @@ kind-of@^6.0.2:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
klaw@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146"
integrity sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==
dependencies:
graceful-fs "^4.1.9"
kleur@^4.0.3:
version "4.1.5"
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780"
@@ -6609,7 +6595,7 @@ stringify-object@^3.3.0:
is-obj "^1.0.1"
is-regexp "^1.0.0"
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -6630,6 +6616,13 @@ strip-ansi@^6.0.0:
dependencies:
ansi-regex "^5.0.0"
strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.0.tgz#1dc49b980c3a4100366617adac59327eefdefcb0"