File
Blob: .github/workflows/_bazel.yml
| 1 | name: 'Run Bazel' |
| 2 | on: |
| 3 | workflow_call: |
| 4 | inputs: |
| 5 | image: |
| 6 | type: string |
| 7 | required: false |
| 8 | default: 'ubuntu-22.04-16core' |
| 9 | os_name: |
| 10 | type: string |
| 11 | required: false |
| 12 | default: 'linux' |
| 13 | |
| 14 | arch_name: |
| 15 | type: string |
| 16 | required: false |
| 17 | default: 'X64' |
| 18 | phase: |
| 19 | type: string |
| 20 | required: false |
| 21 | default: '' |
| 22 | suffix: |
| 23 | type: string |
| 24 | required: false |
| 25 | default: '' |
| 26 | run_tests: |
| 27 | type: boolean |
| 28 | required: false |
| 29 | default: true |
| 30 | test_target: |
| 31 | type: string |
| 32 | required: false |
| 33 | default: //... |
| 34 | parse_headers: |
| 35 | type: boolean |
| 36 | required: false |
| 37 | default: false |
| 38 | extra_bazel_args: |
| 39 | type: string |
| 40 | required: false |
| 41 | default: '' |
| 42 | upload_binary: |
| 43 | type: boolean |
| 44 | required: false |
| 45 | default: false |
| 46 | upload_test_logs: |
| 47 | type: boolean |
| 48 | required: false |
| 49 | default: false |
| 50 | upload_types: |
| 51 | type: boolean |
| 52 | required: false |
| 53 | default: false |
| 54 | run_coverage: |
| 55 | type: boolean |
| 56 | required: false |
| 57 | default: false |
| 58 | fetch_depth: |
| 59 | type: number |
| 60 | required: false |
| 61 | default: 1 |
| 62 | macos_use_lld: |
| 63 | type: boolean |
| 64 | required: false |
| 65 | default: false |
| 66 | build_container_images: |
| 67 | type: boolean |
| 68 | required: false |
| 69 | default: false |
| 70 | secrets: |
| 71 | BAZEL_CACHE_KEY: |
| 72 | required: true |
| 73 | WORKERS_MIRROR_URL: |
| 74 | required: true |
| 75 | CODECOV_TOKEN: |
| 76 | required: false |
| 77 | GOOGLESOURCE_COOKIE: |
| 78 | required: true |
| 79 | |
| 80 | permissions: |
| 81 | # Read repo |
| 82 | contents: read |
| 83 | # Read/write artifacts |
| 84 | actions: write |
| 85 | |
| 86 | jobs: |
| 87 | bazel: |
| 88 | runs-on: ${{ inputs.image }} |
| 89 | steps: |
| 90 | - uses: actions/checkout@v6 |
| 91 | with: |
| 92 | show-progress: false |
| 93 | fetch-depth: ${{ inputs.fetch_depth }} |
| 94 | - name: Cache |
| 95 | id: cache |
| 96 | uses: actions/cache@v5 |
| 97 | with: |
| 98 | path: ~/bazel-disk-cache |
| 99 | key: bazel-disk-cache${{ inputs.phase}}-${{ inputs.os_name }}-${{ runner.arch }}${{ inputs.suffix }}-${{ hashFiles('.bazelversion', '.bazelrc', 'MODULE.bazel') }} |
| 100 | # Intentionally not reusing an older cache entry using a key prefix, bazel frequently |
| 101 | # ends up with a larger cache at the end when starting with an available cache entry, |
| 102 | # resulting in a snowballing cache size and cache download/upload times. |
| 103 | - name: Setup Runner |
| 104 | uses: ./.github/actions/setup-runner |
| 105 | with: |
| 106 | GOOGLESOURCE_COOKIE: ${{ secrets.GOOGLESOURCE_COOKIE }} |
| 107 | - name: Setup lld on macOS |
| 108 | if: runner.os == 'macOS' && inputs.macos_use_lld |
| 109 | run: | |
| 110 | # Install lld and link it to /usr/local/bin. We overwrite any existing link, which may |
| 111 | # exist from an older pre-installed LLVM version on the runner image. |
| 112 | brew update |
| 113 | brew install lld |
| 114 | sudo ln -s -f $(brew --prefix lld)/bin/ld64.lld /usr/local/bin/ld64.lld |
| 115 | # Enable lld identical code folding to significantly reduce binary size. |
| 116 | echo "build:macos --config=macos_lld_icf" >> .bazelrc |
| 117 | - name: Configure download mirrors |
| 118 | shell: bash |
| 119 | run: | |
| 120 | if [ ! -z "${{ secrets.WORKERS_MIRROR_URL }}" ] ; then |
| 121 | # Strip comment in front of WORKERS_MIRROR_URL, then substitute secret to use it. |
| 122 | sed -e '/WORKERS_MIRROR_URL/ { s@# *@@; s@WORKERS_MIRROR_URL@${{ secrets.WORKERS_MIRROR_URL }}@; }' -i.bak build/deps/nodejs.MODULE.bazel |
| 123 | fi |
| 124 | - name: Bazel build (Windows workaround) |
| 125 | if: runner.os == 'Windows' |
| 126 | # HACK: Work around Bazel Windows bug: Some targets need to be compiled without symlink |
| 127 | # support. Since we still need symlinks to compile C++ code properly, compile these targets |
| 128 | # separately. |
| 129 | run: | |
| 130 | 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 |
| 131 | - name: Bazel build |
| 132 | run: | |
| 133 | bazel build --remote_cache=https://bazel:${{ secrets.BAZEL_CACHE_KEY }}@bazel-remote-cache.devprod.cloudflare.dev --config=ci ${{ inputs.extra_bazel_args }} //... |
| 134 | - name: Configure Docker daemon for IPv6 |
| 135 | if: inputs.build_container_images |
| 136 | run: | |
| 137 | sudo mkdir -p /etc/docker |
| 138 | echo '{"ipv6": true, "fixed-cidr-v6": "fd00::/80"}' | sudo tee /etc/docker/daemon.json |
| 139 | sudo systemctl restart docker |
| 140 | - name: Build and load container images |
| 141 | if: inputs.build_container_images |
| 142 | run: | |
| 143 | docker context use default |
| 144 | echo "Docker info:" |
| 145 | docker info |
| 146 | echo "Docker version:" |
| 147 | docker version |
| 148 | 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 |
| 149 | - name: Bazel test |
| 150 | if: inputs.run_tests |
| 151 | run: | |
| 152 | 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 }} |
| 153 | - name: Bazel coverage |
| 154 | if: inputs.run_coverage |
| 155 | run: | |
| 156 | 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 }} |
| 157 | - name: Upload coverage to Codecov |
| 158 | if: inputs.run_coverage |
| 159 | uses: codecov/codecov-action@v5 |
| 160 | with: |
| 161 | # Use bazel info to get the actual output path, avoiding symlink issues |
| 162 | files: ${{ github.workspace }}/bazel-out/_coverage/_coverage_report.dat |
| 163 | fail_ci_if_error: true |
| 164 | verbose: true |
| 165 | disable_search: true |
| 166 | root_dir: ${{ github.workspace }} |
| 167 | env: |
| 168 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} |
| 169 | - name: Parse headers |
| 170 | # TODO(cleanup): Bazel does not allow for only parsing headers in non-recursive targets, so |
| 171 | # we can't widely enable header parsing for now (dependencies like V8 do not specify |
| 172 | # dependencies of header targets properly). |
| 173 | if: inputs.parse_headers |
| 174 | run: | |
| 175 | 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 |
| 176 | - name: Upload test logs |
| 177 | if: always() && inputs.upload_test_logs |
| 178 | uses: actions/upload-artifact@v7 |
| 179 | with: |
| 180 | name: test-logs-${{ inputs.os_name }}-${{ inputs.arch_name }}${{ inputs.suffix }}.zip |
| 181 | path: bazel-testlogs/**/test.xml |
| 182 | - name: Report disk usage (in MB) |
| 183 | if: always() && runner.os != 'Windows' |
| 184 | shell: bash |
| 185 | run: | |
| 186 | BAZEL_OUTPUT_BASE=$(bazel info output_base) |
| 187 | BAZEL_REPOSITORY_CACHE=$(bazel info repository_cache) |
| 188 | echo "Bazel cache usage statistics" |
| 189 | du -ms -t 1 ~/bazel-disk-cache/* $BAZEL_REPOSITORY_CACHE |
| 190 | echo "Bazel output usage statistics" |
| 191 | du -ms -t 1 $BAZEL_OUTPUT_BASE |
| 192 | echo "Workspace usage statistics" |
| 193 | du -ms -t 1 $GITHUB_WORKSPACE |
| 194 | - name: Report disk usage (in MB) |
| 195 | if: always() && runner.os == 'Windows' |
| 196 | shell: pwsh |
| 197 | run: | |
| 198 | function Get-SizeMB($path) { |
| 199 | if (Test-Path $path) { |
| 200 | $size = (Get-ChildItem -Path $path -Recurse -Force -ErrorAction SilentlyContinue | |
| 201 | Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum |
| 202 | [math]::Round($size / 1MB) |
| 203 | } else { 0 } |
| 204 | } |
| 205 | $outputBase = bazel info output_base 2>$null |
| 206 | $repoCache = bazel info repository_cache 2>$null |
| 207 | echo "Bazel cache usage statistics" |
| 208 | echo "$(Get-SizeMB $env:USERPROFILE\bazel-disk-cache)`t$env:USERPROFILE\bazel-disk-cache" |
| 209 | echo "$(Get-SizeMB $repoCache)`t$repoCache" |
| 210 | echo "Bazel output usage statistics" |
| 211 | echo "$(Get-SizeMB $outputBase)`t$outputBase" |
| 212 | echo "Workspace usage statistics" |
| 213 | echo "$(Get-SizeMB $env:GITHUB_WORKSPACE)`t$env:GITHUB_WORKSPACE" |
| 214 | |
| 215 | - name: Upload binary |
| 216 | if: inputs.upload_binary |
| 217 | uses: actions/upload-artifact@v7 |
| 218 | with: |
| 219 | name: ${{ inputs.os_name }}-${{ inputs.arch_name }}${{ inputs.suffix }}-binary |
| 220 | path: bazel-bin/src/workerd/server/workerd${{ runner.os == 'Windows' && '.exe' || '' }} |
| 221 | if-no-files-found: error |
| 222 | - name: Upload build statistics |
| 223 | if: always() && inputs.run_tests |
| 224 | uses: actions/upload-artifact@v7 |
| 225 | with: |
| 226 | name: ${{ inputs.os_name }}${{ inputs.arch_name }}${{ inputs.suffix }}-bazel-profile |
| 227 | path: '*.bazel-profile.gz' |
| 228 | |
| 229 | - name: Drop large Bazel cache files |
| 230 | if: always() |
| 231 | # Github has a nominal 10GB of storage for all cached builds associated with a project. |
| 232 | # Drop large files (>100MB) in our cache to improve shared build cache efficiency. This is |
| 233 | # particularly helpful for asan and debug builds that produce larger executables. Also |
| 234 | # the process of saving the Bazel disk cache generates a tarball on the runners disk, and |
| 235 | # it is possible to run out of storage in that process (does not fail the workflow). |
| 236 | shell: bash |
| 237 | run: | |
| 238 | if [ -d ~/bazel-disk-cache ]; then |
| 239 | find ~/bazel-disk-cache -size +100M -type f -exec rm {} \; |
| 240 | echo "Trimmed Bazel cache usage statistics" |
| 241 | du -ms -t 1 ~/bazel-disk-cache/* |
| 242 | else |
| 243 | echo "Disk cache does not exist: ~/bazel-disk-cache" |
| 244 | fi |
| 245 | |
| 246 | - name: Bazel shutdown |
| 247 | if: always() |
| 248 | # Check that there are no .bazelrc issues that prevent shutdown. |
| 249 | run: bazel shutdown |