name: 'Run Bazel' on: workflow_call: inputs: image: type: string required: false default: 'ubuntu-22.04-16core' os_name: type: string required: false default: 'linux' arch_name: type: string required: false default: 'X64' phase: type: string required: false default: '' suffix: type: string required: false default: '' run_tests: type: boolean required: false default: true test_target: type: string required: false default: //... parse_headers: type: boolean required: false default: false extra_bazel_args: type: string required: false default: '' upload_binary: type: boolean required: false default: false upload_test_logs: type: boolean required: false default: false upload_types: type: boolean required: false default: false run_coverage: type: boolean required: false default: false fetch_depth: type: number required: false default: 1 macos_use_lld: type: boolean required: false default: false build_container_images: type: boolean required: false default: false secrets: BAZEL_CACHE_KEY: required: true WORKERS_MIRROR_URL: required: true CODECOV_TOKEN: required: false GOOGLESOURCE_COOKIE: required: true permissions: # Read repo contents: read # Read/write artifacts actions: write jobs: bazel: runs-on: ${{ inputs.image }} steps: - uses: actions/checkout@v6 with: show-progress: false fetch-depth: ${{ inputs.fetch_depth }} - name: Cache id: cache uses: actions/cache@v5 with: path: ~/bazel-disk-cache key: bazel-disk-cache${{ inputs.phase}}-${{ inputs.os_name }}-${{ runner.arch }}${{ inputs.suffix }}-${{ hashFiles('.bazelversion', '.bazelrc', 'MODULE.bazel') }} # Intentionally not reusing an older cache entry using a key prefix, bazel frequently # ends up with a larger cache at the end when starting with an available cache entry, # resulting in a snowballing cache size and cache download/upload times. - name: Setup Runner uses: ./.github/actions/setup-runner with: GOOGLESOURCE_COOKIE: ${{ secrets.GOOGLESOURCE_COOKIE }} - name: Setup lld on macOS if: runner.os == 'macOS' && inputs.macos_use_lld run: | # Install lld and link it to /usr/local/bin. We overwrite any existing link, which may # exist from an older pre-installed LLVM version on the runner image. brew update brew install lld sudo ln -s -f $(brew --prefix lld)/bin/ld64.lld /usr/local/bin/ld64.lld # Enable lld identical code folding to significantly reduce binary size. echo "build:macos --config=macos_lld_icf" >> .bazelrc - name: Configure download mirrors shell: bash run: | if [ ! -z "${{ secrets.WORKERS_MIRROR_URL }}" ] ; then # Strip comment in front of WORKERS_MIRROR_URL, then substitute secret to use it. sed -e '/WORKERS_MIRROR_URL/ { s@# *@@; s@WORKERS_MIRROR_URL@${{ secrets.WORKERS_MIRROR_URL }}@; }' -i.bak build/deps/nodejs.MODULE.bazel fi - name: Bazel build (Windows workaround) if: runner.os == 'Windows' # HACK: Work around Bazel Windows bug: Some targets need to be compiled without symlink # support. Since we still need symlinks to compile C++ code properly, compile these targets # separately. run: | bazel --nowindows_enable_symlinks build ${{ inputs.extra_bazel_args }} --config=ci --profile build-win-workaround.bazel-profile.gz --remote_cache=https://bazel:${{ secrets.BAZEL_CACHE_KEY }}@bazel-remote-cache.devprod.cloudflare.dev //src/wpt:wpt-all@tsproject //src/node:node@tsproject //src/pyodide:pyodide_static@tsproject - name: Bazel build run: | bazel build --remote_cache=https://bazel:${{ secrets.BAZEL_CACHE_KEY }}@bazel-remote-cache.devprod.cloudflare.dev --config=ci ${{ inputs.extra_bazel_args }} //... - name: Configure Docker daemon for IPv6 if: inputs.build_container_images run: | sudo mkdir -p /etc/docker echo '{"ipv6": true, "fixed-cidr-v6": "fd00::/80"}' | sudo tee /etc/docker/daemon.json sudo systemctl restart docker - name: Build and load container images if: inputs.build_container_images run: | docker context use default echo "Docker info:" docker info echo "Docker version:" docker version bazel run --remote_cache=https://bazel:${{ secrets.BAZEL_CACHE_KEY }}@bazel-remote-cache.devprod.cloudflare.dev --config=ci ${{ inputs.extra_bazel_args }} //images:load_all - name: Bazel test if: inputs.run_tests run: | bazel test --remote_cache=https://bazel:${{ secrets.BAZEL_CACHE_KEY }}@bazel-remote-cache.devprod.cloudflare.dev --config=ci ${{ inputs.extra_bazel_args }} ${{ inputs.test_target }} - name: Bazel coverage if: inputs.run_coverage run: | bazel coverage --remote_cache=https://bazel:${{ secrets.BAZEL_CACHE_KEY }}@bazel-remote-cache.devprod.cloudflare.dev --config=ci ${{ inputs.extra_bazel_args }} ${{ inputs.test_target }} - name: Upload coverage to Codecov if: inputs.run_coverage uses: codecov/codecov-action@v5 with: # Use bazel info to get the actual output path, avoiding symlink issues files: ${{ github.workspace }}/bazel-out/_coverage/_coverage_report.dat fail_ci_if_error: true verbose: true disable_search: true root_dir: ${{ github.workspace }} env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: Parse headers # TODO(cleanup): Bazel does not allow for only parsing headers in non-recursive targets, so # we can't widely enable header parsing for now (dependencies like V8 do not specify # dependencies of header targets properly). if: inputs.parse_headers run: | bazel build --config=parse_headers --remote_cache=https://bazel:${{ secrets.BAZEL_CACHE_KEY }}@bazel-remote-cache.devprod.cloudflare.dev --config=ci ${{ inputs.extra_bazel_args }} //src/workerd/util - name: Upload test logs if: always() && inputs.upload_test_logs uses: actions/upload-artifact@v7 with: name: test-logs-${{ inputs.os_name }}-${{ inputs.arch_name }}${{ inputs.suffix }}.zip path: bazel-testlogs/**/test.xml - name: Report disk usage (in MB) if: always() && runner.os != 'Windows' shell: bash run: | BAZEL_OUTPUT_BASE=$(bazel info output_base) BAZEL_REPOSITORY_CACHE=$(bazel info repository_cache) echo "Bazel cache usage statistics" du -ms -t 1 ~/bazel-disk-cache/* $BAZEL_REPOSITORY_CACHE echo "Bazel output usage statistics" du -ms -t 1 $BAZEL_OUTPUT_BASE echo "Workspace usage statistics" du -ms -t 1 $GITHUB_WORKSPACE - name: Report disk usage (in MB) if: always() && runner.os == 'Windows' shell: pwsh run: | function Get-SizeMB($path) { if (Test-Path $path) { $size = (Get-ChildItem -Path $path -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum [math]::Round($size / 1MB) } else { 0 } } $outputBase = bazel info output_base 2>$null $repoCache = bazel info repository_cache 2>$null echo "Bazel cache usage statistics" echo "$(Get-SizeMB $env:USERPROFILE\bazel-disk-cache)`t$env:USERPROFILE\bazel-disk-cache" echo "$(Get-SizeMB $repoCache)`t$repoCache" echo "Bazel output usage statistics" echo "$(Get-SizeMB $outputBase)`t$outputBase" echo "Workspace usage statistics" echo "$(Get-SizeMB $env:GITHUB_WORKSPACE)`t$env:GITHUB_WORKSPACE" - name: Upload binary if: inputs.upload_binary uses: actions/upload-artifact@v7 with: name: ${{ inputs.os_name }}-${{ inputs.arch_name }}${{ inputs.suffix }}-binary path: bazel-bin/src/workerd/server/workerd${{ runner.os == 'Windows' && '.exe' || '' }} if-no-files-found: error - name: Upload build statistics if: always() && inputs.run_tests uses: actions/upload-artifact@v7 with: name: ${{ inputs.os_name }}${{ inputs.arch_name }}${{ inputs.suffix }}-bazel-profile path: '*.bazel-profile.gz' - name: Drop large Bazel cache files if: always() # Github has a nominal 10GB of storage for all cached builds associated with a project. # Drop large files (>100MB) in our cache to improve shared build cache efficiency. This is # particularly helpful for asan and debug builds that produce larger executables. Also # the process of saving the Bazel disk cache generates a tarball on the runners disk, and # it is possible to run out of storage in that process (does not fail the workflow). shell: bash run: | if [ -d ~/bazel-disk-cache ]; then find ~/bazel-disk-cache -size +100M -type f -exec rm {} \; echo "Trimmed Bazel cache usage statistics" du -ms -t 1 ~/bazel-disk-cache/* else echo "Disk cache does not exist: ~/bazel-disk-cache" fi - name: Bazel shutdown if: always() # Check that there are no .bazelrc issues that prevent shutdown. run: bazel shutdown