Skip to content

Add manual workflow for building clr tests with buildxl #2

Add manual workflow for building clr tests with buildxl

Add manual workflow for building clr tests with buildxl #2

name: BuildXL CoreCLR tests
permissions:
contents: read
on:
pull_request:
branches: [ main, bxl ]
paths:
- '.github/workflows/buildxl-coreclr-tests.yml'
- 'bxl.sh'
- 'config.dsc'
- 'defs/**'
- 'src/tests/Common/**'
- 'src/tests/coreclr_test/**'
- 'src/tests/baseservices/TieredCompilation/**'
push:
branches: [ main, bxl ]
paths:
- '.github/workflows/buildxl-coreclr-tests.yml'
- 'bxl.sh'
- 'config.dsc'
- 'defs/**'
- 'src/tests/Common/**'
- 'src/tests/coreclr_test/**'
- 'src/tests/baseservices/TieredCompilation/**'
workflow_dispatch:
jobs:
buildxl-coreclr-tests:
if: github.repository == 'agocke/rbz'
runs-on: ubuntu-latest
env:
BXL_TOOL_VERSION: '0.2.0-ci.8.5f00873'
RUNTIME_PACKAGE_VERSION: '11.0.0-preview.5.26264.105'
steps:
- name: Checkout runtime
uses: actions/checkout@v6
- name: Install .NET SDK
uses: actions/setup-dotnet@v5
with:
dotnet-version: '11.0.100-preview.5.26227.104'
- name: Restore BuildXL cache
uses: actions/cache@v4
with:
path: ~/.cache/bxl
key: bxl-cache-${{ github.sha }}
restore-keys: bxl-cache-
save-always: true
- name: Install BuildXL bootstrap tool
shell: bash
run: |
set -euo pipefail
dotnet tool install --tool-path "$RUNNER_TEMP/bxl-tools" agtest.bxl.tool \
--version "$BXL_TOOL_VERSION" \
--add-source https://api.nuget.org/v3/index.json
echo "$RUNNER_TEMP/bxl-tools" >> "$GITHUB_PATH"
- name: Install native build dependencies
shell: bash
run: |
set -euo pipefail
sudo ./eng/common/native/install-dependencies.sh
- name: Build corerun test host and IL tools
shell: bash
run: |
set -euo pipefail
./build.sh clr.hosts+clr.iltools -c Release
- name: Assemble Core_Root from NuGet runtime package
shell: bash
run: |
set -euo pipefail
CORE_ROOT="artifacts/tests/coreclr/linux.x64.Release/Tests/Core_Root"
mkdir -p "$CORE_ROOT"
# Download the runtime NuGet package
pkg_url="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet11/nuget/v3/flat2"
pkg_url+="/microsoft.netcore.app.runtime.linux-x64"
pkg_url+="/${RUNTIME_PACKAGE_VERSION}/microsoft.netcore.app.runtime.linux-x64.${RUNTIME_PACKAGE_VERSION}.nupkg"
pkg_dir="$(mktemp -d)"
curl -sSL "$pkg_url" -o "$pkg_dir/runtime.nupkg"
# Extract managed and native files into Core_Root
python3 -c "
import zipfile, shutil, os, sys
core_root = sys.argv[1]
with zipfile.ZipFile(sys.argv[2]) as z:
for info in z.infolist():
if info.filename.startswith('runtimes/linux-x64/lib/net11.0/') and info.filename.endswith('.dll'):
with z.open(info) as src, open(os.path.join(core_root, os.path.basename(info.filename)), 'wb') as dst:
shutil.copyfileobj(src, dst)
elif info.filename.startswith('runtimes/linux-x64/native/'):
name = os.path.basename(info.filename)
if name:
target = os.path.join(core_root, name)
with z.open(info) as src, open(target, 'wb') as dst:
shutil.copyfileobj(src, dst)
os.chmod(target, 0o755)
" "$CORE_ROOT" "$pkg_dir/runtime.nupkg"
# Copy corerun and ilasm from the build output
cp artifacts/bin/coreclr/linux.x64.Release/corerun "$CORE_ROOT/"
cp artifacts/bin/coreclr/linux.x64.Release/ilasm "$CORE_ROOT/"
echo "Core_Root assembled: $(ls "$CORE_ROOT"/*.dll | wc -l) managed + $(ls "$CORE_ROOT"/*.so | wc -l) native files"
- name: Build
shell: bash
run: |
set -euo pipefail
chmod +x ./bxl.sh
./bxl.sh build
- name: Test
shell: bash
run: |
set -uo pipefail
chmod +x ./bxl.sh
./bxl.sh test
bxl_exit=$?
# Source of truth: every enabled test target produces a
# *.test.stamp output on success. Cached pips re-emit the stamp,
# so this count is correct on warm-cache runs too.
mapfile -t passed_stamps < <(find Out/Objects -name '*.test.stamp' | sort)
mapfile -t passed_tests < <(
printf '%s\n' "${passed_stamps[@]}" \
| awk -F/ '{ n=$NF; sub(/\.test\.stamp$/,"",n); print n }' \
| sort -u
)
log="Out/Logs/BuildXL.Dev.log"
mapfile -t failed_tests < <(
[[ -f "$log" ]] && grep -E 'error DX0064:.*run coreclr test: [A-Za-z_0-9]+.*failed with exit code' "$log" \
| grep -oE 'run coreclr test: [A-Za-z_0-9]+' \
| awk '{print $NF}' | sort -u
)
passed=${#passed_tests[@]}
failed=${#failed_tests[@]}
total=$((passed + failed))
# Whole-build cache stats from BuildXL.stats. Per-pip cached-vs-executed
# for test pips specifically would require parsing the XLG; the build-wide
# numbers convey the cache effectiveness clearly enough.
stats="Out/Logs/BuildXL.stats"
total_pips=$(awk -F= '$1=="TotalProcessPips"{print $2}' "$stats" 2>/dev/null)
cache_hits=$(awk -F= '$1=="ProcessPipCacheHits"{print $2}' "$stats" 2>/dev/null)
cache_misses=$(awk -F= '$1=="ProcessPipCacheMisses"{print $2}' "$stats" 2>/dev/null)
: "${total_pips:=?}"; : "${cache_hits:=?}"; : "${cache_misses:=?}"
if [[ "$cache_hits" =~ ^[0-9]+$ && "$total_pips" =~ ^[0-9]+$ && "$total_pips" -gt 0 ]]; then
hit_pct=$(awk -v h="$cache_hits" -v t="$total_pips" 'BEGIN{printf "%.1f", (h*100)/t}')
cache_line="${cache_hits} cache hits / ${cache_misses} executed of ${total_pips} process pips (${hit_pct}% hit)"
else
cache_line="cache stats unavailable"
fi
echo
echo "============================================================"
echo " BuildXL test results: ${passed} passed, ${failed} failed (of ${total} total)"
echo " Build cache: ${cache_line}"
echo "============================================================"
if (( failed > 0 )); then
echo "Failed tests:"
for t in "${failed_tests[@]}"; do echo " - $t"; done
fi
echo
if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then
{
echo "## BuildXL test results"
echo
echo "**${passed} passed, ${failed} failed (of ${total} total)**"
echo
echo "Build cache: ${cache_line}"
if (( failed > 0 )); then
echo
echo "### Failed tests"
for t in "${failed_tests[@]}"; do echo "- \`$t\`"; done
fi
echo
echo "<details><summary>All ${passed} passed tests</summary>"
echo
for t in "${passed_tests[@]}"; do echo "- \`$t\`"; done
echo
echo "</details>"
} >> "$GITHUB_STEP_SUMMARY"
fi
exit "$bxl_exit"
- name: Upload workflow logs
if: failure()
uses: actions/upload-artifact@v7
with:
name: buildxl-coreclr-logs
path: |
${{ github.workspace }}/Out/Logs/**
${{ github.workspace }}/Out/Objects/**/*_run/*.log
${{ github.workspace }}/artifacts/log/**
${{ github.workspace }}/artifacts/tests/coreclr/**/*.log
${{ github.workspace }}/artifacts/tests/coreclr/**/*.xml
if-no-files-found: ignore