From da41154dbce1e0715fd5ef0d54724049400aa9a4 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 24 Nov 2025 19:46:13 -0800 Subject: [PATCH] ci: add pipeline segment to run clang-tidy --- .github/actions/build-electron/action.yml | 9 + .github/workflows/build.yml | 4 +- ...ectron-build-and-tidy-and-test-and-nan.yml | 124 ++++++++++++++ ...eline-electron-build-and-tidy-and-test.yml | 121 +++++++++++++ .../pipeline-segment-electron-build.yml | 6 + .../pipeline-segment-electron-clang-tidy.yml | 159 ++++++++++++++++++ 6 files changed, 422 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/pipeline-electron-build-and-tidy-and-test-and-nan.yml create mode 100644 .github/workflows/pipeline-electron-build-and-tidy-and-test.yml create mode 100644 .github/workflows/pipeline-segment-electron-clang-tidy.yml diff --git a/.github/actions/build-electron/action.yml b/.github/actions/build-electron/action.yml index 36f5d2c27c..49ddef70b5 100644 --- a/.github/actions/build-electron/action.yml +++ b/.github/actions/build-electron/action.yml @@ -26,6 +26,9 @@ inputs: is-asan: description: 'The ASan Linux build' required: false + upload-out-gen-artifacts: + description: 'Whether to upload the out/${dir}/gen artifacts' + required: false runs: using: "composite" steps: @@ -250,3 +253,9 @@ runs: with: name: src_artifacts_${{ env.ARTIFACT_KEY }} path: ./src_artifacts_${{ inputs.artifact-platform }}_${{ inputs.target-arch }} + - name: Upload Out Gen Artifacts ${{ inputs.step-suffix }} + if: ${{ inputs.upload-out-gen-artifacts == 'true' }} + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + with: + name: out_gen_artifacts_${{ env.ARTIFACT_KEY }} + path: ./src/out/Default/gen diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4ad96a6437..f0a8785063 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -283,13 +283,15 @@ jobs: contents: read issues: read pull-requests: read - uses: ./.github/workflows/pipeline-electron-build-and-test-and-nan.yml + uses: ./.github/workflows/pipeline-electron-build-and-tidy-and-test-and-nan.yml needs: checkout-linux if: ${{ needs.setup.outputs.src == 'true' }} with: build-runs-on: electron-arc-centralus-linux-amd64-32core + clang-tidy-runs-on: electron-arc-centralus-linux-amd64-8core test-runs-on: electron-arc-centralus-linux-amd64-4core build-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}' + clang-tidy-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root","volumes":["/mnt/cross-instance-cache:/mnt/cross-instance-cache"]}' test-container: '{"image":"ghcr.io/electron/build:${{ needs.checkout-linux.outputs.build-image-sha }}","options":"--user root --privileged --init"}' target-platform: linux target-arch: x64 diff --git a/.github/workflows/pipeline-electron-build-and-tidy-and-test-and-nan.yml b/.github/workflows/pipeline-electron-build-and-tidy-and-test-and-nan.yml new file mode 100644 index 0000000000..2cbe33ec7b --- /dev/null +++ b/.github/workflows/pipeline-electron-build-and-tidy-and-test-and-nan.yml @@ -0,0 +1,124 @@ +name: Electron Build & Clang Tidy & Test (+ Node + NaN) Pipeline + +on: + workflow_call: + inputs: + target-platform: + type: string + description: 'Platform to run on, can be macos, win 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 + clang-tidy-runs-on: + type: string + description: 'What host to run clang-tidy on' + 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}' + clang-tidy-container: + type: string + description: 'JSON container information to run clang-tidy on' + required: false + default: '{"image":null}' + test-container: + type: string + description: 'JSON container information for testing' + required: false + default: '{"image":null}' + is-release: + description: 'Whether this build job is a release job' + required: true + type: boolean + default: false + gn-build-type: + description: 'The gn build type - testing or release' + required: true + type: string + default: testing + generate-symbols: + description: 'Whether or not to generate symbols' + required: true + type: boolean + default: false + upload-to-storage: + description: 'Whether or not to upload build artifacts to external storage' + required: true + type: string + default: '0' + is-asan: + description: 'Building the Address Sanitizer (ASan) Linux build' + required: false + type: boolean + default: false + +permissions: {} + +concurrency: + group: electron-build-and-test-and-nan-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref_protected == true && github.run_id || github.ref }} + cancel-in-progress: ${{ github.ref_protected != true }} + +jobs: + build: + uses: ./.github/workflows/pipeline-segment-electron-build.yml + permissions: + contents: read + 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 }} + upload-out-gen-artifacts: true + secrets: inherit + clang-tidy: + uses: ./.github/workflows/pipeline-segment-electron-clang-tidy.yml + permissions: + contents: read + needs: build + with: + clang-tidy-runs-on: ${{ inputs.clang-tidy-runs-on }} + clang-tidy-container: ${{ inputs.clang-tidy-container }} + target-platform: ${{ inputs.target-platform }} + target-arch: ${{ inputs.target-arch }} + secrets: inherit + test: + uses: ./.github/workflows/pipeline-segment-electron-test.yml + permissions: + contents: read + issues: read + pull-requests: read + 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 + permissions: + contents: read + 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 diff --git a/.github/workflows/pipeline-electron-build-and-tidy-and-test.yml b/.github/workflows/pipeline-electron-build-and-tidy-and-test.yml new file mode 100644 index 0000000000..103aafaa04 --- /dev/null +++ b/.github/workflows/pipeline-electron-build-and-tidy-and-test.yml @@ -0,0 +1,121 @@ +name: Electron Build & Clang Tidy & Test Pipeline + +on: + workflow_call: + inputs: + target-platform: + type: string + description: 'Platform to run on, can be macos, win 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 + clang-tidy-runs-on: + type: string + description: 'What host to run clang-tidy on' + 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}' + clang-tidy-container: + type: string + description: 'JSON container information to run clang-tidy on' + required: false + default: '{"image":null}' + test-container: + type: string + description: 'JSON container information for testing' + required: false + default: '{"image":null}' + is-release: + description: 'Whether this build job is a release job' + required: true + type: boolean + default: false + gn-build-type: + description: 'The gn build type - testing or release' + required: true + type: string + default: testing + generate-symbols: + description: 'Whether or not to generate symbols' + required: true + type: boolean + default: false + upload-to-storage: + description: 'Whether or not to upload build artifacts to external storage' + required: true + type: string + default: '0' + is-asan: + description: 'Building the Address Sanitizer (ASan) Linux build' + required: false + type: boolean + default: false + enable-ssh: + description: 'Enable SSH debugging' + required: false + type: boolean + default: false + +concurrency: + group: electron-build-and-tidy-and-test-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref_protected == true && github.run_id || github.ref }} + cancel-in-progress: ${{ github.ref_protected != true }} + +permissions: {} + +jobs: + build: + uses: ./.github/workflows/pipeline-segment-electron-build.yml + permissions: + contents: read + with: + build-runs-on: ${{ inputs.build-runs-on }} + build-container: ${{ inputs.build-container }} + target-platform: ${{ inputs.target-platform }} + target-arch: ${{ inputs.target-arch }} + is-release: ${{ inputs.is-release }} + gn-build-type: ${{ inputs.gn-build-type }} + generate-symbols: ${{ inputs.generate-symbols }} + upload-to-storage: ${{ inputs.upload-to-storage }} + is-asan: ${{ inputs.is-asan }} + enable-ssh: ${{ inputs.enable-ssh }} + upload-out-gen-artifacts: true + secrets: inherit + clang-tidy: + uses: ./.github/workflows/pipeline-segment-electron-clang-tidy.yml + permissions: + contents: read + needs: build + with: + clang-tidy-runs-on: ${{ inputs.clang-tidy-runs-on }} + clang-tidy-container: ${{ inputs.clang-tidy-container }} + target-platform: ${{ inputs.target-platform }} + target-arch: ${{ inputs.target-arch }} + secrets: inherit + test: + uses: ./.github/workflows/pipeline-segment-electron-test.yml + permissions: + contents: read + issues: read + pull-requests: read + needs: build + with: + target-arch: ${{ inputs.target-arch }} + target-platform: ${{ inputs.target-platform }} + test-runs-on: ${{ inputs.test-runs-on }} + test-container: ${{ inputs.test-container }} + is-asan: ${{ inputs.is-asan }} + enable-ssh: ${{ inputs.enable-ssh }} + secrets: inherit diff --git a/.github/workflows/pipeline-segment-electron-build.yml b/.github/workflows/pipeline-segment-electron-build.yml index e5311bcc83..ec83d93a69 100644 --- a/.github/workflows/pipeline-segment-electron-build.yml +++ b/.github/workflows/pipeline-segment-electron-build.yml @@ -53,6 +53,11 @@ on: required: false type: boolean default: false + upload-out-gen-artifacts: + description: 'Whether to upload the src/gen artifacts' + required: false + type: boolean + default: false enable-ssh: description: 'Enable SSH debugging' required: false @@ -201,6 +206,7 @@ jobs: generate-symbols: '${{ inputs.generate-symbols }}' upload-to-storage: '${{ inputs.upload-to-storage }}' is-asan: '${{ inputs.is-asan }}' + upload-out-gen-artifacts: '${{ inputs.upload-out-gen-artifacts }}' - name: Set GN_EXTRA_ARGS for MAS Build if: ${{ inputs.target-platform == 'macos' && (inputs.target-variant == 'all' || inputs.target-variant == 'mas') }} run: | diff --git a/.github/workflows/pipeline-segment-electron-clang-tidy.yml b/.github/workflows/pipeline-segment-electron-clang-tidy.yml new file mode 100644 index 0000000000..08a5d5dc5f --- /dev/null +++ b/.github/workflows/pipeline-segment-electron-clang-tidy.yml @@ -0,0 +1,159 @@ +name: Pipeline Segment - Electron Clang-Tidy + +on: + workflow_call: + inputs: + target-platform: + type: string + description: 'Platform to run on, can be macos, win or linux' + required: true + target-arch: + type: string + description: 'Arch to build for, can be x64, arm64 or arm' + required: true + clang-tidy-runs-on: + type: string + description: 'What host to run clang-tidy on' + required: true + clang-tidy-container: + type: string + description: 'JSON container information for aks runs-on' + required: false + default: '{"image":null}' + +permissions: {} + +concurrency: + group: electron-clang-tidy-${{ inputs.target-platform }}-${{ inputs.target-arch }}-${{ github.ref }} + cancel-in-progress: true + +env: + GCLIENT_EXTRA_ARGS: ${{ inputs.target-platform == 'macos' && '--custom-var=checkout_mac=True --custom-var=host_os=mac' || (inputs.target-platform == 'linux' && '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True' || '--custom-var=checkout_win=True') }} + ELECTRON_OUT_DIR: Default + +jobs: + clang-tidy: + defaults: + run: + shell: bash + runs-on: ${{ inputs.clang-tidy-runs-on }} + permissions: + contents: read + container: ${{ fromJSON(inputs.clang-tidy-container) }} + env: + BUILD_TYPE: ${{ inputs.target-platform == 'macos' && 'darwin' || inputs.target-platform }} + TARGET_ARCH: ${{ inputs.target-arch }} + TARGET_PLATFORM: ${{ inputs.target-platform }} + ARTIFACT_KEY: ${{ inputs.target-platform == 'macos' && 'darwin' || inputs.target-platform }}_${{ inputs.target-arch }} + steps: + - name: Checkout Electron + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd + with: + path: src/electron + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + - name: Cleanup disk space on macOS + if: ${{ inputs.target-platform == '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 + } + tmpify /Library/Developer/CoreSimulator + tmpify ~/Library/Developer/CoreSimulator + sudo rm -rf $TMPDIR/del-target + - name: Check disk space after freeing up space + if: ${{ inputs.target-platform == 'macos' }} + run: df -h + - name: Set Chromium Git Cookie + uses: ./src/electron/.github/actions/set-chromium-cookie + - name: Install Build Tools + uses: ./src/electron/.github/actions/install-build-tools + - name: Enable windows toolchain + if: ${{ inputs.target-platform == 'win' }} + run: | + echo "ELECTRON_DEPOT_TOOLS_WIN_TOOLCHAIN=1" >> $GITHUB_ENV + - name: Generate DEPS Hash + run: | + node src/electron/script/generate-deps-hash.js + DEPSHASH=v1-src-cache-$(cat src/electron/.depshash) + 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 + with: + target-platform: ${{ inputs.target-platform }} + - name: Restore src cache via AKS + if: ${{ inputs.target-platform == 'linux' || inputs.target-platform == 'win' }} + uses: ./src/electron/.github/actions/restore-cache-aks + with: + target-platform: ${{ inputs.target-platform }} + - name: Run Electron Only Hooks + run: | + echo "solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False},'managed':False}]" > tmpgclient + if [ "${{ inputs.target-platform }}" = "win" ]; then + echo "solutions=[{'name':'src/electron','url':None,'deps_file':'DEPS','custom_vars':{'process_deps':False,'install_sysroot':False,'checkout_win':True},'managed':False}]" > tmpgclient + echo "target_os=['win']" >> tmpgclient + fi + e d gclient runhooks --gclientfile=tmpgclient + + # Fix VS Toolchain + if [ "${{ inputs.target-platform }}" = "win" ]; then + rm -rf src/third_party/depot_tools/win_toolchain/vs_files + e d python3 src/build/vs_toolchain.py update --force + fi + - name: Regenerate DEPS Hash + run: | + (cd src/electron && git checkout .) && node src/electron/script/generate-deps-hash.js + echo "DEPSHASH=$(cat src/electron/.depshash)" >> $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@93cb6efe18208431cddfb8368fd83d5badbf9bfd + with: + path: src/electron + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + - name: Install Dependencies + uses: ./src/electron/.github/actions/install-dependencies + - name: Default GN gen + run: | + cd src/electron + git pack-refs + - name: Download Out Gen Artifacts + uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 + with: + name: out_gen_artifacts_${{ env.ARTIFACT_KEY }} + path: ./src/out/${{ env.ELECTRON_OUT_DIR }}/gen + - name: Add Clang problem matcher + shell: bash + run: echo "::add-matcher::src/electron/.github/problem-matchers/clang.json" + - name: Run Clang-Tidy + run: | + e init -f --root=$(pwd) --out=${ELECTRON_OUT_DIR} testing --target-cpu ${TARGET_ARCH} + + export GN_EXTRA_ARGS="target_cpu=\"${TARGET_ARCH}\"" + if [ "${{ inputs.target-platform }}" = "win" ]; then + export GN_EXTRA_ARGS="$GN_EXTRA_ARGS use_v8_context_snapshot=true target_os=\"win\"" + fi + + e build --only-gen + + cd src/electron + node script/yarn.js lint:clang-tidy --jobs 8 --out-dir ../out/${ELECTRON_OUT_DIR} + - name: Remove Clang problem matcher + shell: bash + run: echo "::remove-matcher owner=clang::" + - name: Wait for active SSH sessions + if: always() && !cancelled() + shell: bash + run: | + while [ -f /var/.ssh-lock ] + do + sleep 60 + done