mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
c264c6eef9
Highlights: - Trimmed down to just the repository cache for faster upload / download - Made the cache key only include files that affect external dependencies (since that's what the repository cache caches) - MODULE.bazel, codex-rs/Cargo.lock, codex-rs/Cargo.toml - Split the caching action in to explicit restore / save steps (similar to your rust CI) which allows us to skip uploads on cache hit, and not fail the build if upload fails This should get rid of 842 network fetches that are happening on every Bazel CI run, while also reducing the Github flakiness @bolinfest reported. Uploading should be faster (since we're not caching many small files), and will only happen when MODULE.bazel or Cargo.lock / Cargo.toml files change. In my testing, it [took 3s to save the repository cache](https://github.com/siggisim/codex/actions/runs/23014186143/job/66832859781).
230 lines
9.1 KiB
YAML
230 lines
9.1 KiB
YAML
name: Bazel (experimental)
|
|
|
|
# Note this workflow was originally derived from:
|
|
# https://github.com/cerisier/toolchains_llvm_bootstrapped/blob/main/.github/workflows/ci.yaml
|
|
|
|
on:
|
|
pull_request: {}
|
|
push:
|
|
branches:
|
|
- main
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
# Cancel previous actions from the same PR or branch except 'main' branch.
|
|
# See https://docs.github.com/en/actions/using-jobs/using-concurrency and https://docs.github.com/en/actions/learn-github-actions/contexts for more info.
|
|
group: concurrency-group::${{ github.workflow }}::${{ github.event.pull_request.number > 0 && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}${{ github.ref_name == 'main' && format('::{0}', github.run_id) || ''}}
|
|
cancel-in-progress: ${{ github.ref_name != 'main' }}
|
|
jobs:
|
|
test:
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
# macOS
|
|
- os: macos-15-xlarge
|
|
target: aarch64-apple-darwin
|
|
- os: macos-15-xlarge
|
|
target: x86_64-apple-darwin
|
|
|
|
# Linux
|
|
- os: ubuntu-24.04
|
|
target: x86_64-unknown-linux-gnu
|
|
- os: ubuntu-24.04
|
|
target: x86_64-unknown-linux-musl
|
|
# 2026-02-27 Bazel tests have been flaky on arm in CI.
|
|
# Disable until we can investigate and stabilize them.
|
|
# - os: ubuntu-24.04-arm
|
|
# target: aarch64-unknown-linux-musl
|
|
# - os: ubuntu-24.04-arm
|
|
# target: aarch64-unknown-linux-gnu
|
|
|
|
# TODO: Enable Windows once we fix the toolchain issues there.
|
|
#- os: windows-latest
|
|
# target: x86_64-pc-windows-gnullvm
|
|
runs-on: ${{ matrix.os }}
|
|
|
|
# Configure a human readable name for each job
|
|
name: Local Bazel build on ${{ matrix.os }} for ${{ matrix.target }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- name: Set up Node.js for js_repl tests
|
|
uses: actions/setup-node@v6
|
|
with:
|
|
node-version-file: codex-rs/node-version.txt
|
|
|
|
# Some integration tests rely on DotSlash being installed.
|
|
# See https://github.com/openai/codex/pull/7617.
|
|
- name: Install DotSlash
|
|
uses: facebook/install-dotslash@v2
|
|
|
|
- name: Make DotSlash available in PATH (Unix)
|
|
if: runner.os != 'Windows'
|
|
run: cp "$(which dotslash)" /usr/local/bin
|
|
|
|
- name: Make DotSlash available in PATH (Windows)
|
|
if: runner.os == 'Windows'
|
|
shell: pwsh
|
|
run: Copy-Item (Get-Command dotslash).Source -Destination "$env:LOCALAPPDATA\Microsoft\WindowsApps\dotslash.exe"
|
|
|
|
# Install Bazel via Bazelisk
|
|
- name: Set up Bazel
|
|
uses: bazelbuild/setup-bazelisk@v3
|
|
|
|
- name: Check MODULE.bazel.lock is up to date
|
|
if: matrix.os == 'ubuntu-24.04' && matrix.target == 'x86_64-unknown-linux-gnu'
|
|
shell: bash
|
|
run: ./scripts/check-module-bazel-lock.sh
|
|
|
|
# Restore bazel repository cache so we don't have to redownload all the external dependencies
|
|
# on every CI run.
|
|
- name: Restore bazel repository cache
|
|
id: cache_bazel_repository_restore
|
|
uses: actions/cache/restore@v5
|
|
with:
|
|
path: |
|
|
~/.cache/bazel-repo-cache
|
|
key: bazel-cache-${{ matrix.os }}-${{ hashFiles('MODULE.bazel', 'codex-rs/Cargo.lock', 'codex-rs/Cargo.toml') }}
|
|
restore-keys: |
|
|
bazel-cache-${{ matrix.os }}
|
|
|
|
- name: Configure Bazel startup args (Windows)
|
|
if: runner.os == 'Windows'
|
|
shell: pwsh
|
|
run: |
|
|
# Use a very short path to reduce argv/path length issues.
|
|
"BAZEL_STARTUP_ARGS=--output_user_root=C:\" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
|
|
|
- name: bazel test //...
|
|
env:
|
|
BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }}
|
|
shell: bash
|
|
run: |
|
|
set -o pipefail
|
|
|
|
bazel_console_log="$(mktemp)"
|
|
|
|
print_failed_bazel_test_logs() {
|
|
local console_log="$1"
|
|
local testlogs_dir
|
|
|
|
testlogs_dir="$(bazel $BAZEL_STARTUP_ARGS info bazel-testlogs 2>/dev/null || echo bazel-testlogs)"
|
|
|
|
local failed_targets=()
|
|
while IFS= read -r target; do
|
|
failed_targets+=("$target")
|
|
done < <(
|
|
grep -E '^FAIL: //' "$console_log" \
|
|
| sed -E 's#^FAIL: (//[^ ]+).*#\1#' \
|
|
| sort -u
|
|
)
|
|
|
|
if [[ ${#failed_targets[@]} -eq 0 ]]; then
|
|
echo "No failed Bazel test targets were found in console output."
|
|
return
|
|
fi
|
|
|
|
for target in "${failed_targets[@]}"; do
|
|
local rel_path="${target#//}"
|
|
rel_path="${rel_path/:/\/}"
|
|
local test_log="${testlogs_dir}/${rel_path}/test.log"
|
|
|
|
echo "::group::Bazel test log tail for ${target}"
|
|
if [[ -f "$test_log" ]]; then
|
|
tail -n 200 "$test_log"
|
|
else
|
|
echo "Missing test log: $test_log"
|
|
fi
|
|
echo "::endgroup::"
|
|
done
|
|
}
|
|
|
|
bazel_args=(
|
|
test
|
|
--test_verbose_timeout_warnings
|
|
--build_metadata=REPO_URL=https://github.com/openai/codex.git
|
|
--build_metadata=COMMIT_SHA=$(git rev-parse HEAD)
|
|
--build_metadata=ROLE=CI
|
|
--build_metadata=VISIBILITY=PUBLIC
|
|
)
|
|
|
|
bazel_targets=(
|
|
//...
|
|
# Keep V8 out of the ordinary Bazel CI path. Only the dedicated
|
|
# canary and release workflows should build `third_party/v8`.
|
|
-//third_party/v8:all
|
|
)
|
|
|
|
if [[ "${RUNNER_OS:-}" != "Windows" ]]; then
|
|
# Bazel test sandboxes on macOS may resolve an older Homebrew `node`
|
|
# before the `actions/setup-node` runtime on PATH.
|
|
node_bin="$(which node)"
|
|
bazel_args+=("--test_env=CODEX_JS_REPL_NODE_PATH=${node_bin}")
|
|
fi
|
|
|
|
if [[ -n "${BUILDBUDDY_API_KEY:-}" ]]; then
|
|
echo "BuildBuddy API key is available; using remote Bazel configuration."
|
|
# Work around Bazel 9 remote repo contents cache / overlay materialization failures
|
|
# seen in CI (for example "is not a symlink" or permission errors while
|
|
# materializing external repos such as rules_perl). We still use BuildBuddy for
|
|
# remote execution/cache; this only disables the startup-level repo contents cache.
|
|
set +e
|
|
bazel $BAZEL_STARTUP_ARGS \
|
|
--noexperimental_remote_repo_contents_cache \
|
|
--bazelrc=.github/workflows/ci.bazelrc \
|
|
"${bazel_args[@]}" \
|
|
"--remote_header=x-buildbuddy-api-key=$BUILDBUDDY_API_KEY" \
|
|
-- \
|
|
"${bazel_targets[@]}" \
|
|
2>&1 | tee "$bazel_console_log"
|
|
bazel_status=${PIPESTATUS[0]}
|
|
set -e
|
|
else
|
|
echo "BuildBuddy API key is not available; using local Bazel configuration."
|
|
# Keep fork/community PRs on Bazel but disable remote services that are
|
|
# configured in .bazelrc and require auth.
|
|
#
|
|
# Flag docs:
|
|
# - Command-line reference: https://bazel.build/reference/command-line-reference
|
|
# - Remote caching overview: https://bazel.build/remote/caching
|
|
# - Remote execution overview: https://bazel.build/remote/rbe
|
|
# - Build Event Protocol overview: https://bazel.build/remote/bep
|
|
#
|
|
# --noexperimental_remote_repo_contents_cache:
|
|
# disable remote repo contents cache enabled in .bazelrc startup options.
|
|
# https://bazel.build/reference/command-line-reference#startup_options-flag--experimental_remote_repo_contents_cache
|
|
# --remote_cache= and --remote_executor=:
|
|
# clear remote cache/execution endpoints configured in .bazelrc.
|
|
# https://bazel.build/reference/command-line-reference#common_options-flag--remote_cache
|
|
# https://bazel.build/reference/command-line-reference#common_options-flag--remote_executor
|
|
set +e
|
|
bazel $BAZEL_STARTUP_ARGS \
|
|
--noexperimental_remote_repo_contents_cache \
|
|
"${bazel_args[@]}" \
|
|
--remote_cache= \
|
|
--remote_executor= \
|
|
-- \
|
|
"${bazel_targets[@]}" \
|
|
2>&1 | tee "$bazel_console_log"
|
|
bazel_status=${PIPESTATUS[0]}
|
|
set -e
|
|
fi
|
|
|
|
if [[ ${bazel_status:-0} -ne 0 ]]; then
|
|
print_failed_bazel_test_logs "$bazel_console_log"
|
|
exit "$bazel_status"
|
|
fi
|
|
|
|
# Save bazel repository cache explicitly; make non-fatal so cache uploading
|
|
# never fails the overall job. Only save when key wasn't hit.
|
|
- name: Save bazel repository cache
|
|
if: always() && !cancelled() && steps.cache_bazel_repository_restore.outputs.cache-hit != 'true'
|
|
continue-on-error: true
|
|
uses: actions/cache/save@v5
|
|
with:
|
|
path: |
|
|
~/.cache/bazel-repo-cache
|
|
key: bazel-cache-${{ matrix.os }}-${{ hashFiles('MODULE.bazel', 'codex-rs/Cargo.lock', 'codex-rs/Cargo.toml') }}
|