Skip to content

Commit 43a1768

Browse files
authored
[ABLD-135] Add initial bazel jobs (#40153)
### What does this PR do? Now `bazelisk` is available on all our CI executors ([macOS](DataDog/ci-platform-machine-images#395) runners, [Linux](DataDog/datadog-agent-buildimages#951) & [Windows](DataDog/datadog-agent-buildimages#953) containers), this change secures an initial part of our `bazel` setup while providing reusable job templates to ease caching in CI. Practically, it adds a handful of jobs focusing on **building `bazel` dependencies** in the corresponding GitLab `deps_build` stage. Overall, it consists in: 1. verifying **`bazelisk` properly bootstraps `bazel` across all platforms**, (primary scope of the PR) 2. extracting initial `bazel:`-prefixed CI job templates and dogfooding them, (i.e. by building deps) 3. binding `bazelisk`/`bazel` caches to GitLab caching capabilities (runner-based as of now): installed binaries, "repository cache", "repo contents cache", and "disk cache" are all saved/restored correctly to/from GitLab while honoring OS/architecture boundaries, 4. marking in-workspace cache in both `.bazelignore` and `.gitignore`, 5. adjusting code/job ownership accordingly. ### Motivation Securing some initial `bazel` configuration in CI : - ensures all platforms are kept in the radar over next iterations, - prevents regressions over next iterations, - establishes foundations for future jobs. ### Possible Drawbacks / Trade-offs - on Windows, compilation errors made be descope dependencies being built to **only `bzip2`**. This will be of course addressed in a subsequent PR, - GitLab caching is still runner-based for the time being, which can be revisited later. (like everything) ### Additional Notes Main addressed challenges: - cache location conflicts[^1]: externalized "repo contents cache" through `tools/bazel*` wrappers: - bazelbuild/bazel#26384 - bazelbuild/bazel#26522 - bazelbuild/bazel#26773 - bazelbuild/bazel#26802 - macOS runners: - `bzip2` dependency: fetch from a reachable source: - [x] #40219 - Windows: - `bazel` spawn strategy: fallback to a permissive strategy since `sandboxed` is unsupported - [x] #40328 - `tools/bazel` wrapper: fallback to batch (`tools/bazel.bat`), since `bash` is discouraged by `bazel` in this case and `tools/bazel.ps1` poses detection problems, - long paths were supported in containers but not on runners: - [x] DataDog/ci-platform-machine-images#429 - recursive symlinks: use `robocopy` instead of `copy`/`move`/`xcopy`. [^1]: > ERROR: The repo contents cache [/path/to/datadog-agent/.cache/repo_contents] is inside the workspace [/path/to/datadog-agent]. This can cause spurious failures. Disable the repo contents cache with `--repo_contents_cache=`, or specify `--repo_contents_cache=<path outside the workspace>`.
1 parent 5468df1 commit 43a1768

File tree

11 files changed

+246
-1
lines changed

11 files changed

+246
-1
lines changed

.bazelignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.cache/

.github/CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282

8383
/.gitlab/.ci-linters.yml @DataDog/agent-devx
8484
/.gitlab/.pre/* @DataDog/agent-devx
85+
/.gitlab/bazel/* @DataDog/agent-build
8586
/.gitlab/check_deploy/* @DataDog/agent-delivery
8687
/.gitlab/check_merge/* @DataDog/agent-devx
8788
/.gitlab/deploy*/* @DataDog/agent-delivery
@@ -750,6 +751,7 @@
750751
/test/regression/cases/docker_containers* @DataDog/single-machine-performance @DataDog/container-integrations
751752

752753
/tools/ @DataDog/agent-devx
754+
/tools/bazel* @DataDog/agent-build
753755
/tools/ci @DataDog/agent-devx
754756
/tools/ebpf/ @DataDog/ebpf-platform
755757
/tools/gdb/ @DataDog/agent-runtimes

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ venv*/
2727
*.log
2828
/main
2929

30+
# In-workpace cache
31+
/.cache/
3032
# Bazel convenience symlinks to output folders
3133
/bazel-*
3234
# User specific bazelrc file

.gitlab-ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
include:
33
- .gitlab/.pre/include.yml
4+
- .gitlab/bazel/*.yaml
45
- .gitlab/benchmarks/include.yml
56
- .gitlab/binary_build/include.yml
67
- .gitlab/check_deploy/check_deploy.yml

.gitlab/JOBOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ generate_minimized_btfs_* @DataDog/ebpf-platform
4848

4949
# Package build
5050
*agent_dmg* @DataDog/agent-build
51+
bazel:* @DataDog/agent-build
5152
datadog-agent-* @DataDog/agent-build
5253
datadog-ot-agent-* @DataDog/agent-build
5354
dogstatsd-* @DataDog/agent-build

.gitlab/bazel/build-deps.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
.bazel:build-deps:
2+
extends: .bazel:defs
3+
rules:
4+
- !reference [ .except_mergequeue ]
5+
- when: on_success
6+
stage: deps_build
7+
8+
bazel:build-deps:linux-amd64:
9+
extends: [ .bazel:build-deps, .linux_x64 ]
10+
tags: [ "arch:amd64", "specific:true" ]
11+
script:
12+
- bazel build //deps/...
13+
14+
bazel:build-deps:linux-arm64:
15+
extends: [ .bazel:build-deps, .linux_arm64 ]
16+
tags: [ "arch:arm64", "specific:true" ]
17+
script:
18+
- bazel build //deps/...
19+
20+
bazel:build-deps:macos-amd64:
21+
extends: .bazel:build-deps
22+
tags: [ "macos:ventura-amd64", "specific:true" ]
23+
script:
24+
- bazel build //deps/...
25+
26+
bazel:build-deps:macos-arm64:
27+
extends: .bazel:build-deps
28+
tags: [ "macos:ventura-arm64", "specific:true" ]
29+
script:
30+
- bazel build //deps/...
31+
32+
bazel:build-deps:windows-amd64:
33+
extends: [ .bazel:build-deps, .bazel:ext:windows ]
34+
variables:
35+
ARCH: x64
36+
SCRIPT: |-
37+
echo "🟡 TODO(regis): compilation errors remain - limiting to a working subset for the time being"
38+
bazel build @bzip2//...

.gitlab/bazel/defs.yaml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
.bazel:defs:
2+
cache:
3+
- key:
4+
prefix: bazel-$CI_RUNNER_DESCRIPTION
5+
files: [ .bazelversion ]
6+
paths:
7+
- .cache/bazelisk
8+
- .cache/bazel/install
9+
policy: pull-push
10+
when: on_success
11+
- key: bazel-$CI_RUNNER_DESCRIPTION
12+
paths:
13+
- .cache/bazel/cache
14+
- .cache/bazel/disk
15+
- .cache/bazel/repo-contents
16+
policy: pull-push
17+
when: on_success
18+
needs: [ ]
19+
variables:
20+
BAZELISK_HOME: "$XDG_CACHE_HOME/bazelisk"
21+
BAZEL_DISK_CACHE: "$BAZEL_OUTPUT_USER_ROOT/disk"
22+
BAZEL_OUTPUT_USER_ROOT: "$XDG_CACHE_HOME/bazel"
23+
BAZEL_REPO_CONTENTS_CACHE: "$BAZEL_OUTPUT_USER_ROOT/repo-contents"
24+
XDG_CACHE_HOME: "$CI_PROJECT_DIR/.cache"
25+
26+
.bazel:ext:windows:
27+
extends: .windows_docker_default
28+
variables:
29+
GIT_DEPTH: 2
30+
script:
31+
- |-
32+
$FailFast = @'
33+
$ErrorActionPreference = 'Stop'
34+
$PSNativeCommandUseErrorActionPreference = $true
35+
Set-StrictMode -Version 3.0
36+
'@
37+
- Invoke-Expression $FailFast
38+
- >-
39+
(($FailFast, $SCRIPT) -join [Environment]::NewLine) | docker run
40+
--env=BAZELISK_HOME
41+
--env=BAZEL_DISK_CACHE
42+
--env=BAZEL_OUTPUT_USER_ROOT
43+
--env=BAZEL_REPO_CONTENTS_CACHE
44+
--env=CI_PROJECT_DIR
45+
--env=RUNNER_TEMP_PROJECT_DIR
46+
--interactive
47+
--rm
48+
--volume="${CI_PROJECT_DIR}:$CI_PROJECT_DIR"
49+
--volume="${RUNNER_TEMP_PROJECT_DIR}:$RUNNER_TEMP_PROJECT_DIR"
50+
--workdir="$CI_PROJECT_DIR"
51+
"$WINBUILDIMAGE"
52+
powershell -Command -

tasks/libs/ciproviders/gitlab_api.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from __future__ import annotations
77

8+
import glob
89
import json
910
import os
1011
import platform
@@ -998,7 +999,7 @@ def read_includes(ctx, yaml_files, includes=None, return_config=False, add_file_
998999
if isinstance(yaml_files, str):
9991000
yaml_files = [yaml_files]
10001001

1001-
for yaml_file in yaml_files:
1002+
for yaml_file in [f for p in yaml_files for f in glob.glob(p, recursive=True)]:
10021003
current_file = read_content(ctx, yaml_file, git_ref=git_ref)
10031004

10041005
if add_file_path:

tools/bazel

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Check `bazelisk` properly bootstraps `bazel` or fail with instructions
5+
if [ -z "${BAZEL_REAL:-}" ] || [ "${BAZELISK_SKIP_WRAPPER:-}" != "true" ]; then
6+
cat >&2 "$(dirname "$0")/bazelisk.md"
7+
exit 1
8+
fi
9+
10+
# Not in CI: simply execute `bazel` - done
11+
if [ -z "${CI_PROJECT_DIR:-}" ]; then
12+
exec "$BAZEL_REAL" "$@"
13+
exit 2 # should not reach here
14+
fi
15+
16+
# In CI: externalize `--repo_contents_cache` to the job's sibling temporary directory created alongside $CI_PROJECT_DIR
17+
# - https://github.com/bazelbuild/bazel/issues/26384 for why
18+
# - https://docs.gitlab.com/runner/configuration/advanced-configuration/ for `RUNNER_TEMP_PROJECT_DIR`
19+
# - https://sissource.ethz.ch/sispub/gitlab-ci-euler-image/-/blob/main/entrypoint.sh#L43 for inspiration
20+
ext_repo_contents_cache=$RUNNER_TEMP_PROJECT_DIR/bazel-repo-contents-cache
21+
if [ -e "$BAZEL_REPO_CONTENTS_CACHE" ]; then
22+
rm >&2 -frv "$ext_repo_contents_cache"
23+
mv "$BAZEL_REPO_CONTENTS_CACHE" "$ext_repo_contents_cache"
24+
fi
25+
26+
# Pass CI-specific options through `.user.bazelrc` so any nested `bazel run` and next `bazel shutdown` also honor them
27+
cat >"$CI_PROJECT_DIR/user.bazelrc" <<EOF
28+
startup --output_user_root=$BAZEL_OUTPUT_USER_ROOT
29+
common --repo_contents_cache=$ext_repo_contents_cache
30+
build --disk_cache=$BAZEL_DISK_CACHE
31+
EOF
32+
33+
trap '
34+
# Stop `bazel` (if still running) to close files and proceed with cleanup
35+
"$BAZEL_REAL" shutdown --ui_event_filters=-info || true
36+
rm "$CI_PROJECT_DIR/user.bazelrc"
37+
38+
# Reintegrate `--repo_contents_cache` to original directory
39+
if [ -e "$ext_repo_contents_cache" ]; then
40+
rm >&2 -frv "$BAZEL_REPO_CONTENTS_CACHE"
41+
mv "$ext_repo_contents_cache" "$BAZEL_REPO_CONTENTS_CACHE"
42+
fi
43+
' EXIT
44+
45+
# Payload: execute `bazel` - done
46+
"$BAZEL_REAL" "$@"

tools/bazel.bat

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
@echo off
2+
setlocal EnableExtensions EnableDelayedExpansion
3+
4+
rem Check `bazelisk` properly bootstraps `bazel` or fail with instructions
5+
if not defined BAZEL_REAL (
6+
>&2 type "%~dp0bazelisk.md"
7+
exit /b 1
8+
) else if not "%BAZELISK_SKIP_WRAPPER%"=="true" (
9+
>&2 type "%~dp0bazelisk.md"
10+
exit /b 2
11+
)
12+
13+
rem Not in CI: simply execute `bazel` - done
14+
if not defined CI_PROJECT_DIR (
15+
"%BAZEL_REAL%" %*
16+
exit /b !errorlevel!
17+
)
18+
19+
rem In CI: first, verify directory environment variables are set and normalize their paths
20+
for %%v in (BAZEL_DISK_CACHE BAZEL_OUTPUT_USER_ROOT BAZEL_REPO_CONTENTS_CACHE RUNNER_TEMP_PROJECT_DIR VSTUDIO_ROOT) do (
21+
if not defined %%v (
22+
>&2 echo %~nx0: %%v: unbound variable
23+
exit /b 3
24+
)
25+
rem Path separators: `bazel` is fine with both `/` and `\\` but fails with `\`, so the simplest is to favor `/`
26+
set "%%v=!%%v:\=/!"
27+
)
28+
rem TODO(regis, if later needed): set "BAZEL_SH=C:/tools/msys64/usr/bin/bash.exe"
29+
set "BAZEL_VS=!VSTUDIO_ROOT!"
30+
set "ext_repo_contents_cache=!RUNNER_TEMP_PROJECT_DIR!/bazel-repo-contents-cache"
31+
32+
rem Externalize `--repo_contents_cache` to the job's sibling temporary directory created alongside $CI_PROJECT_DIR
33+
rem - https://github.com/bazelbuild/bazel/issues/26384 for why
34+
rem - https://docs.gitlab.com/runner/configuration/advanced-configuration/ for `RUNNER_TEMP_PROJECT_DIR`
35+
rem - https://sissource.ethz.ch/sispub/gitlab-ci-euler-image/-/blob/main/entrypoint.sh#L43 for inspiration
36+
if exist "!BAZEL_REPO_CONTENTS_CACHE!" (
37+
call :robomove "!BAZEL_REPO_CONTENTS_CACHE!" "!ext_repo_contents_cache!"
38+
set "rc=!errorlevel!"
39+
if !rc! neq 0 exit /b !rc!
40+
)
41+
42+
rem Pass CI-specific options through `.user.bazelrc` so any nested `bazel run` and next `bazel shutdown` also honor them
43+
(
44+
echo startup --output_user_root=!BAZEL_OUTPUT_USER_ROOT!
45+
echo common --repo_contents_cache=!ext_repo_contents_cache!
46+
echo build --disk_cache=!BAZEL_DISK_CACHE!
47+
) >"!CI_PROJECT_DIR!\user.bazelrc"
48+
49+
rem Payload: execute `bazel` and remember exit status
50+
"!BAZEL_REAL!" %*
51+
set "bazel_exit=!errorlevel!"
52+
53+
rem Stop `bazel` (if still running) to close files and proceed with cleanup
54+
>&2 "!BAZEL_REAL!" shutdown --ui_event_filters=-info
55+
>&2 del /f /q "!CI_PROJECT_DIR!\user.bazelrc"
56+
57+
rem Reintegrate `--repo_contents_cache` to original directory
58+
if exist "!ext_repo_contents_cache!" (
59+
call :robomove "!ext_repo_contents_cache!" "!BAZEL_REPO_CONTENTS_CACHE!"
60+
set "rc=!errorlevel!"
61+
if !bazel_exit!==0 set "bazel_exit=!rc!"
62+
)
63+
64+
rem Done
65+
exit /b !bazel_exit!
66+
67+
:robomove
68+
rem Contrarily to `copy`, `move` and `xcopy`, `robocopy` avoids messing up with recursive symlinks, thanks to `/xj`
69+
>&2 robocopy "%~1" "%~2" /b /copyall /dcopy:dat /mir /move /ndl /nfl /njh /njs /np /secfix /sl /timfix /w:0 /xj
70+
rem See: https://ss64.com/nt/robocopy-exit.html
71+
set /a rc=!errorlevel! ^& (8 ^| 16)
72+
if exist "%~1" (
73+
>&2 echo 🟡 Purging leftovers, most likely due to recursive symbolic links/junction points:
74+
>&2 dir /a /b /s "%~1"
75+
>&2 rmdir /q /s "%~1"
76+
)
77+
exit /b !rc!

0 commit comments

Comments
 (0)