Skip to content
File

Blob: .github/workflows/_bazel.yml

yaml250 lines
1name: 'Run Bazel'
2on:
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 
80permissions:
81 # Read repo
82 contents: read
83 # Read/write artifacts
84 actions: write
85 
86jobs:
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