Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
46f925a79This file is pinned to the selected release. Download the original to open it in your design tool.
# This configuration is used to build and test on GitHub Actions only.
# It is not the same configuration that is used by Google DeepMind to create release binaries.
# The "official" binaries are built with Clang 13 on all platforms, and are linked against libc++
# on Linux.
#
# We set CMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF here to reduce build time.
# It is highly recommended that this is set to ON for production builds.
#
# Build speed notes:
# * The compiler matrix lives in build_matrix.json. Pull requests build the
# representative "core" subset; pushes to main run the full compiler sweep.
# (See generate_matrix() in build_steps.sh.)
# * Studio/Filament and WASM are NOT built in the main matrix - they are covered
# by the dedicated `studio` and `wasm` jobs below. WASM in particular is built
# with emcc, which ignores the host compiler, so building it per-compiler added
# no coverage.
# * ccache is used to wrap the compiler. PR branches fall back to main's cache, so
# the expensive (and pinned) Filament build is restored rather than recompiled.
# TODO(matijak): Consider switching Windows to Ninja builds only, this configures slightly faster
# and brings Windows in line with other OSes. Also we wouldn't need to specify the --config option
# in the build step because Ninja doesn't support multiple configurations (unlike MSBuild).
name: build
on:
push:
branches:
- main
paths-ignore:
- "doc/**"
- "**/README.md"
pull_request:
paths-ignore:
- "doc/**"
- "**/README.md"
# Limit the default GITHUB_TOKEN to read-only. No job here writes via the token:
# checkout reads the repo; ccache/cache and upload-artifact use their own backend
# tokens; the chat notification uses a secret webhook.
permissions:
contents: read
jobs:
# Compute the build matrix based on the event: PRs get the "core" representative
# compiler set, pushes to main get the full sweep.
setup:
name: "setup (compute matrix)"
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.generate.outputs.matrix }}
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
persist-credentials: false
- name: Generate build matrix
id: generate
env:
GITHUB_EVENT_NAME: ${{ github.event_name }}
run: bash ./.github/workflows/build_steps.sh generate_matrix
mujoco:
needs: setup
strategy:
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
name: "${{ matrix.label }}"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
persist-credentials: false
- name: Prepare Linux
if: ${{ runner.os == 'Linux' }}
run: bash ./.github/workflows/build_steps.sh prepare_linux
- name: Prepare macOS
if: ${{ runner.os == 'macOS' }}
run: brew install ninja
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.11"
# uv makes the dependency install much faster, with a cross-run cache. POSIX
# only: Windows stays on pip (it is not a Python-setup bottleneck, and this
# keeps the venv activate fixup path untouched there).
- name: Install uv
if: ${{ runner.os != 'Windows' }}
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
enable-cache: true
cache-dependency-glob: "python/build_requirements*.txt"
- name: Prepare Python
shell: bash
env:
TMPDIR: ${{ matrix.tmpdir }}
run: bash ./.github/workflows/build_steps.sh prepare_python
# ccache dramatically speeds up warm rebuilds. The key is the matrix label so
# each compiler gets its own cache; the action's restore-keys let PR branches
# fall back to main's cache. ccache on Windows/MSVC is finicky and Windows
# isn't the bottleneck, so we skip it there.
- name: Setup ccache
if: ${{ runner.os != 'Windows' }}
uses: hendrikmuhs/ccache-action@d62db5f07c26379fc4b4e0916f098a92573c3b03 # v1.2.23
with:
key: ${{ matrix.label }}
max-size: "1.5G"
- name: Configure MuJoCo
env:
TMPDIR: ${{ matrix.tmpdir }}
CMAKE_ARGS: ${{ matrix.cmake_args }}
run: bash ./.github/workflows/build_steps.sh configure_mujoco
- name: Upload CMake Configure Log
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: cmake-configure-log-${{ matrix.label }}
path: build/CMakeFiles/CMakeConfigureLog.yaml
retention-days: 5
- name: Build MuJoCo
working-directory: build
env:
CMAKE_BUILD_ARGS: ${{ matrix.cmake_build_args }}
run: bash ../.github/workflows/build_steps.sh build_mujoco
- name: Test MuJoCo
working-directory: build
run: bash ../.github/workflows/build_steps.sh test_mujoco
- name: Install MuJoCo
working-directory: build
run: bash ../.github/workflows/build_steps.sh install_mujoco
- name: Copy plugins (POSIX)
if: ${{ runner.os != 'Windows' }}
working-directory: build
env:
TMPDIR: ${{ matrix.tmpdir }}
run: bash ../.github/workflows/build_steps.sh copy_plugins_posix
- name: Copy plugins (Windows)
if: ${{ runner.os == 'Windows' }}
working-directory: build
env:
TMPDIR: ${{ matrix.tmpdir }}
run: bash ../.github/workflows/build_steps.sh copy_plugins_window
- name: Configure samples
working-directory: sample
env:
TMPDIR: ${{ matrix.tmpdir }}
CMAKE_ARGS: ${{ matrix.cmake_args }}
run: bash ../.github/workflows/build_steps.sh configure_samples
- name: Build samples
working-directory: sample/build
env:
CMAKE_BUILD_ARGS: ${{ matrix.cmake_build_args }}
run: bash ../../.github/workflows/build_steps.sh build_samples
- name: Configure simulate
working-directory: simulate
env:
TMPDIR: ${{ matrix.tmpdir }}
CMAKE_ARGS: ${{ matrix.cmake_args }}
run: bash ../.github/workflows/build_steps.sh configure_simulate
- name: Build simulate
working-directory: simulate/build
env:
CMAKE_BUILD_ARGS: ${{ matrix.cmake_build_args }}
run: bash ../../.github/workflows/build_steps.sh build_simulate
- name: Make Python sdist
shell: bash
working-directory: python
env:
TMPDIR: ${{ matrix.tmpdir }}
run: bash ../.github/workflows/build_steps.sh make_python_sdist
- name: Build Python bindings
if: ${{ runner.os != 'Windows' }}
shell: bash
working-directory: python/dist
env:
TMPDIR: ${{ matrix.tmpdir }}
CMAKE_ARGS: ${{ matrix.cmake_args }}
run: bash ../../.github/workflows/build_steps.sh build_python_bindings
- name: Install Python bindings
if: ${{ runner.os != 'Windows' }}
shell: bash
working-directory: python/dist
env:
TMPDIR: ${{ matrix.tmpdir }}
run: bash ../../.github/workflows/build_steps.sh install_python_bindings
- name: Test Python bindings
if: ${{ runner.os != 'Windows' }}
shell: bash
env:
MUJOCO_GL: disable
TMPDIR: ${{ matrix.tmpdir }}
run: bash ./.github/workflows/build_steps.sh test_python_bindings
# MJX (mujoco.mjx) is covered by the dedicated `mjx` job below; it is
# compiler-independent so it does not need to run in every matrix job.
- name: Notify team chat
if: failure() && github.ref_name == 'main' && github.event_name == 'push'
uses: ./.github/actions/notify-chat
with:
service-account-key: ${{ secrets.CHAT_SERVICE_ACCOUNT_KEY }}
user-id-map: ${{ secrets.CHAT_USER_ID_MAP }}
space-id: "spaces/AAAAzcCLt1A"
# This job quickly determines if MuJoCo Studio is broken. It is the only place
# Filament is compiled in CI, so ccache here is what keeps the long pole short.
studio:
strategy:
matrix:
include:
- os: ubuntu-24.04
label: "ubuntu-24.04-clang-18-studio"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-18
-DCMAKE_CXX_COMPILER:STRING=clang++-18
-DMUJOCO_HARDEN:BOOL=ON
# gcc canary: Filament is compiler-dependent and historically finicky on
# gcc, so keep one gcc Studio build even though the matrix no longer does.
- os: ubuntu-24.04
label: "ubuntu-24.04-gcc-14-studio"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=gcc-14
-DCMAKE_CXX_COMPILER:STRING=g++-14
-DCMAKE_EXE_LINKER_FLAGS:STRING=-Wl,--no-as-needed
- os: windows-2025
label: "windows-2025-ninja-studio"
cmake_args: >-
-G Ninja
-DCMAKE_SYSTEM_VERSION=10.0.26100.0
- os: macos-15
label: "macos-15-arm64-studio"
cmake_args: >-
-G Ninja
-DCMAKE_CXX_FLAGS="-Wno-error=deprecated-declarations"
-DMUJOCO_HARDEN:BOOL=ON
name: "${{ matrix.label }}"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
persist-credentials: false
- name: Prepare Windows (setup MSVC)
if: ${{ runner.os == 'Windows' }}
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1
- name: Prepare Linux
if: ${{ runner.os == 'Linux' }}
run: bash ./.github/workflows/build_steps.sh prepare_linux
# Key the cache on the Filament pin: hashing cmake/third_party_deps/filament.cmake
# captures BOTH the pinned commit hash and the FILAMENT_* build flags, so bumping
# either starts a fresh cache namespace instead of restoring stale artifacts.
# (Correctness does not depend on this: ccache is content-addressed on the full
# compiler invocation, so changing any build flag forces a recompile regardless.)
- name: Setup ccache
if: ${{ runner.os != 'Windows' }}
uses: hendrikmuhs/ccache-action@d62db5f07c26379fc4b4e0916f098a92573c3b03 # v1.2.23
with:
key: ${{ matrix.label }}-filament-${{ hashFiles('cmake/third_party_deps/filament.cmake') }}
restore-keys: ${{ matrix.label }}-filament-
max-size: "2.0G"
- name: Configure Studio
env:
CMAKE_ARGS: ${{ matrix.cmake_args }}
run: bash ./.github/workflows/build_steps.sh configure_studio
- name: Build Studio
run: bash ./.github/workflows/build_steps.sh build_studio
- name: Notify team chat
if: failure() && github.ref_name == 'main' && github.event_name == 'push'
uses: ./.github/actions/notify-chat
with:
service-account-key: ${{ secrets.CHAT_SERVICE_ACCOUNT_KEY }}
user-id-map: ${{ secrets.CHAT_USER_ID_MAP }}
space-id: "spaces/AAAAzcCLt1A"
# This job quickly determines if WASM bindings are broken.
wasm:
name: "ubuntu-24.04-clang-18-wasm"
runs-on: ubuntu-24.04
env:
label: "ubuntu-24.04-clang-18-wasm"
cmake_args: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-18
-DCMAKE_CXX_COMPILER:STRING=clang++-18
-DMUJOCO_HARDEN:BOOL=ON
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
persist-credentials: false
- name: Setup Node.js for WASM bindings
uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
with:
node-version: '24.x'
- name: Prepare Linux
if: ${{ runner.os == 'Linux' }}
run: bash ./.github/workflows/build_steps.sh prepare_linux
- name: Setup ccache
uses: hendrikmuhs/ccache-action@d62db5f07c26379fc4b4e0916f098a92573c3b03 # v1.2.23
with:
key: ${{ env.label }}
max-size: "1.5G"
# For convenience run multiple build_steps functions in a single step.
- name: Prepare, Build and Test WASM bindings
env:
CMAKE_ARGS: ${{ env.cmake_args }}
run: |
bash ./.github/workflows/build_steps.sh npm_ci
bash ./.github/workflows/build_steps.sh setup_emsdk
bash ./.github/workflows/build_steps.sh build_test_wasm
- name: Notify team chat
if: failure() && github.ref_name == 'main' && github.event_name == 'push'
uses: ./.github/actions/notify-chat
with:
service-account-key: ${{ secrets.CHAT_SERVICE_ACCOUNT_KEY }}
user-id-map: ${{ secrets.CHAT_USER_ID_MAP }}
space-id: "spaces/AAAAzcCLt1A"
# MJX (mujoco.mjx) is pure JAX/XLA and compiler-independent: it imports the
# mujoco Python package only as a reference, so its tests run once here instead
# of in every matrix job. MuJoCo is built WITHOUT the C++ test suite (MJX does
# not need it) to keep the build lean.
mjx:
name: "ubuntu-24.04-clang-18-mjx"
runs-on: ubuntu-24.04
env:
TMPDIR: "/tmp"
CMAKE_ARGS: >-
-G Ninja
-DCMAKE_C_COMPILER:STRING=clang-18
-DCMAKE_CXX_COMPILER:STRING=clang++-18
-DMUJOCO_HARDEN:BOOL=ON
-DMUJOCO_BUILD_TESTS:BOOL=OFF
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
persist-credentials: false
- name: Prepare Linux
run: bash ./.github/workflows/build_steps.sh prepare_linux
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.11"
- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
enable-cache: true
cache-dependency-glob: "python/build_requirements*.txt"
- name: Prepare Python
run: bash ./.github/workflows/build_steps.sh prepare_python
- name: Setup ccache
uses: hendrikmuhs/ccache-action@d62db5f07c26379fc4b4e0916f098a92573c3b03 # v1.2.23
with:
key: ubuntu-24.04-clang-18-mjx
max-size: "1.0G"
- name: Configure MuJoCo
run: bash ./.github/workflows/build_steps.sh configure_mujoco
- name: Build MuJoCo
working-directory: build
run: bash ../.github/workflows/build_steps.sh build_mujoco
- name: Install MuJoCo
working-directory: build
run: bash ../.github/workflows/build_steps.sh install_mujoco
- name: Copy plugins
working-directory: build
run: bash ../.github/workflows/build_steps.sh copy_plugins_posix
- name: Make Python sdist
working-directory: python
run: bash ../.github/workflows/build_steps.sh make_python_sdist
- name: Build Python bindings
working-directory: python/dist
run: bash ../../.github/workflows/build_steps.sh build_python_bindings
- name: Install Python bindings
working-directory: python/dist
run: bash ../../.github/workflows/build_steps.sh install_python_bindings
- name: Package MJX
working-directory: mjx
run: bash ../.github/workflows/build_steps.sh package_mjx
- name: Install MJX
working-directory: mjx
run: bash ../.github/workflows/build_steps.sh install_mjx
- name: Test MJX
working-directory: mjx
run: bash ../.github/workflows/build_steps.sh test_mjx
- name: Notify team chat
if: failure() && github.ref_name == 'main' && github.event_name == 'push'
uses: ./.github/actions/notify-chat
with:
service-account-key: ${{ secrets.CHAT_SERVICE_ACCOUNT_KEY }}
user-id-map: ${{ secrets.CHAT_USER_ID_MAP }}
space-id: "spaces/AAAAzcCLt1A"