From 4aa89b9c3cd3e1716667372872231a1e2f623dbd Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 26 Jan 2026 11:37:01 -0800 Subject: [PATCH] ci: add pipeline segment to run clang-tidy (#49072) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ci: add pipeline segment to run clang-tidy * chore: set -header-filter='' for clang-tidy Breaking change in `clang-tidy` 22.0.0: > clang-tidy now displays warnings from all non-system headers by default. > Previously, users had to explicitly opt-in to header warnings using > -header-filter=’.*’. To disable warnings from non-system, set > -header-filter to an empty string. --- .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 ++++++++++++++++++ script/run-clang-tidy.ts | 2 +- 7 files changed, 423 insertions(+), 2 deletions(-) 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 26e79025f4..ba5bef4f3f 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: @@ -274,3 +277,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@65462800fd760344b1a7b4382951275a0abb4808 + 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 2ee7847b42..a039b74a24 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -284,13 +284,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 2d46f54d3a..278834a448 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..90b42ecc37 --- /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@8e8c483db84b4bee98b60c0593521ed34d9990e8 + 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@8e8c483db84b4bee98b60c0593521ed34d9990e8 + 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@37930b1c2abaa49bbe596cd826c3c89aef350131 + 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 diff --git a/script/run-clang-tidy.ts b/script/run-clang-tidy.ts index ea8a0a0bf7..ab3ad9efe8 100644 --- a/script/run-clang-tidy.ts +++ b/script/run-clang-tidy.ts @@ -118,7 +118,7 @@ async function runClangTidy ( fix: boolean = false ): Promise { const cmd = path.resolve(LLVM_BIN, 'clang-tidy'); - const args = [`-p=${outDir}`]; + const args = [`-p=${outDir}`, "-header-filter=''"]; if (!process.env.CI) args.push('--use-color'); if (fix) args.push('--fix');