diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml new file mode 100644 index 00000000000..5e9e767c383 --- /dev/null +++ b/.github/actions/build/action.yml @@ -0,0 +1,112 @@ +name: build +description: > + Sets up a cross-platform build environment for Basilisk and performs + either a Conan-based build or a pip-based build. +inputs: + python-version: + description: Python version + required: true + conan-args: + required: false + default: "" + is-canary: + description: If a canary build is being performed. + required: false + default: false + skip-build: + description: Used to do all build related setup, while skipping the actual build + required: false + default: false + +runs: + using: "composite" + steps: + - uses: actions/setup-python@v5 + with: + python-version: ${{ inputs.python-version }} + cache: "pip" + cache-dependency-path: | + requirements_dev.txt + requirements_doc.txt + requirements.txt + + - name: Install Linux System Deps. + if: runner.os == 'Linux' + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y build-essential python3-setuptools python3-tk libgtk2.0 + + - name: SWIG Install (Linux) + if: runner.os == 'Linux' + uses: mmomtchev/setup-swig@v4 + with: + version: v4.2.1 + + - name: SWIG Install (macOS) + if: runner.os == 'macOS' + shell: bash + env: + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_INSTALL_UPGRADE: 1 + HOMEBREW_NO_ANALYTICS: 1 + run: brew install swig || true + + - name: SWIG Install (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + $swigDir = "C:\Program Files\SWIG" + if (!(Test-Path $swigDir)) {New-Item -ItemType Directory -Path $swigDir | Out-Null} + $swigZip = "$swigDir\swigwin-4.2.1.zip" + $swigUrl = "https://sourceforge.net/projects/swig/files/swigwin/swigwin-4.2.1/swigwin-4.2.1.zip/download" + Start-Process -NoNewWindow -Wait -FilePath "curl.exe" -ArgumentList "-L -o `"$swigZip`" `"$swigUrl`"" + if (!(Test-Path $swigZip) -or ((Get-Item $swigZip).Length -lt 500KB)) { Write-Host "Download failed or file is corrupted." } + Expand-Archive -Path $swigZip -DestinationPath $swigDir -Force + + - name: "Add Basilisk and SWIG paths" + if: runner.os == 'Windows' + shell: pwsh + run: | + $oldpath = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).path + $newPath = “C:\Program Files\SWIG\swigwin-4.2.1;$oldpath;${{ env.GITHUB_WORKSPACE }}\dist3\Basilisk” + echo "PATH=$newPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + + - name: Install requirements + shell: bash + run: | + if [[ "${{ inputs.is-canary }}" == 'true' ]]; then + pip install -r .github/workflows/requirements.txt -r .github/workflows/requirements_dev.txt + else + pip install -r requirements.txt -r requirements_dev.txt + fi + + - name: Cache Conan + uses: actions/cache@v4 + with: + path: ${{ env.HOME }}/.conan2 + key: >- + conan-${{ runner.os }}-py${{ inputs.python-version }}- + ${{ hashFiles('conan.lock','conanfile.*','**/conanfile.*','CMakeLists.txt','**/*.cmake') }} + restore-keys: | + conan-${{ runner.os }}-py${{ inputs.python-version }}- + + - name: Configure Conan profile + shell: bash + run: | + python -m conans.conan profile detect --exist-ok + prof_path="$(python -m conans.conan profile path default)" + grep -q '^\[conf\]' "$prof_path" || printf "\n[conf]\n" >> "$prof_path" + grep -q '^tools.system.package_manager:mode=install$' "$prof_path" || \ + printf "tools.system.package_manager:mode=install\n" >> "$prof_path" + grep -q '^tools.system.package_manager:sudo=True$' "$prof_path" || \ + printf "tools.system.package_manager:sudo=True\n" >> "$prof_path" + + - name: Build Basilisk + shell: bash + if: ${{ inputs.skip-build == 'false' }} + env: + CONAN_ARGS: ${{ inputs.conan-args }} + run: | + pip install --no-build-isolation -e . -v + bskLargeData diff --git a/.github/actions/docs/action.yml b/.github/actions/docs/action.yml new file mode 100644 index 00000000000..be2f63bed9d --- /dev/null +++ b/.github/actions/docs/action.yml @@ -0,0 +1,33 @@ +name: docs +description: Build Sphinx docs + +inputs: + html-dir: { required: false, default: "docs/build/html" } + is-canary: + description: If a canary build is being performed. + required: false + default: false + +runs: + using: composite + steps: + - name: Install doc requirements + shell: bash + run: | + brew install doxygen + if [[ "${{ inputs.is-canary }}" == 'true' ]]; then + pip install -r .github/workflows/requirements_doc.txt + else + pip install -r requirements_doc.txt + fi + - name: Generate doc artifacts + shell: bash + env: + MPLBACKEND: agg + working-directory: src + run: pytest -n auto -m "not ciSkip" -rs --dist=loadscope -v + - name: Compile docs + shell: bash + run: | + make -C docs html SPHINXOPTS="-W" + echo "DOCS_HTML=${{ inputs.html-dir }}" >> "$GITHUB_ENV" diff --git a/.github/actions/pre-commit/action.yml b/.github/actions/pre-commit/action.yml new file mode 100644 index 00000000000..65f34b3a5aa --- /dev/null +++ b/.github/actions/pre-commit/action.yml @@ -0,0 +1,15 @@ +name: pre-commit +description: Run pre-commit on changed files with Python 3.11 + +runs: + using: composite + steps: + - uses: actions/setup-python@v5 + with: + python-version: 3.11 + + - id: file_changes + uses: tj-actions/changed-files@v44 + - uses: pre-commit/action@v3.0.1 + with: + extra_args: --files ${{ steps.file_changes.outputs.all_changed_files }} diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index 7c9b03b854e..fe4daae7371 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -1,8 +1,6 @@ name: "Canary Build" on: - schedule: - - cron: '0 0 * * 0' # Run weekly on Sunday at midnight workflow_dispatch: pull_request: branches: @@ -19,7 +17,7 @@ jobs: timeout-minutes: 75 strategy: matrix: - python-version: [ "3.13" ] + python-version: ["3.13"] steps: - name: Checkout code uses: actions/checkout@v4 @@ -27,62 +25,38 @@ jobs: uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - - name: Install Homebrew - run: | - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - brew install swig doxygen - - - name: "Create virtual Environment" - run: python3 -m venv .venv - - name: "Capture initial package versions" + - name: Capture initial package versions run: | - source .venv/bin/activate pip freeze > initial_versions.txt echo "Initial package versions:" >> $GITHUB_STEP_SUMMARY cat initial_versions.txt >> $GITHUB_STEP_SUMMARY echo "\n" >> $GITHUB_STEP_SUMMARY - - - name: "Install canary requirements" - run: | - source .venv/bin/activate - pip3 install -r .github/workflows/requirements.txt - pip3 install -r .github/workflows/requirements_dev.txt - pip3 install -r .github/workflows/requirements_doc.txt - pip3 install pytest-error-for-skips - - - name: "Capture final package versions" + - name: Build Basilisk + uses: ./.github/actions/build + with: + python-version: ${{ matrix.python-version }} + conan-args: --opNav True --allOptPkg --mujoco True --mujocoReplay True --pyPkgCanary True + is-canary: true + - name: Capture final package versions run: | - source .venv/bin/activate pip freeze > final_versions.txt echo "Final package versions:" >> $GITHUB_STEP_SUMMARY cat final_versions.txt >> $GITHUB_STEP_SUMMARY echo "\n" >> $GITHUB_STEP_SUMMARY echo "Package version changes:" >> $GITHUB_STEP_SUMMARY diff -u initial_versions.txt final_versions.txt | grep -E '^[+-]' | grep -v '^+++' | grep -v '^---' >> $GITHUB_STEP_SUMMARY - - - name: "Build basilisk with latest dependencies" - run: source .venv/bin/activate && python3 conanfile.py --opNav True --allOptPkg --mujoco True --mujocoReplay True --pyPkgCanary True - - - name: "Run Python Tests" - run: | - source .venv/bin/activate - cd src - pytest -n auto -m "not ciSkip" -rs --error-for-skips --dist=loadscope -v - if: ${{ always() }} - - name: "Run C/C++ Tests" + # NOTE: The documentation depends on images generated by executing the + # Python tests successfully. As such, the "Build docs" action below + # handles running the Python tests internally + - name: Run C/C++ Tests working-directory: ./dist3 run: ctest -C Release if: ${{ always() }} - - - name: "Build Documentation" - run: | - source .venv/bin/activate - cd docs - make html SPHINXOPTS="-W" - if: ${{ always() }} - - - name: "Upload package version logs" + - name: Build docs + uses: ./.github/actions/docs + with: + is-canary: true + - name: Upload package version logs if: always() uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml new file mode 100644 index 00000000000..6d9c4dc94b4 --- /dev/null +++ b/.github/workflows/merge.yml @@ -0,0 +1,87 @@ +name: Merge to develop + +on: + push: + branches: [develop] + workflow_dispatch: + +permissions: + contents: write + actions: read + +concurrency: + group: merge-develop + cancel-in-progress: false + +jobs: + bump_version: + name: Bump version (skip if already bumped) + runs-on: ubuntu-latest + if: ${{ github.actor != 'AVSlabBot' }} + steps: + - uses: actions/checkout@v4 + with: + ref: develop + fetch-depth: 0 + token: ${{ secrets.BOT_ACCESS_TOKEN }} + + - name: Bump version + run: ./.github/workflows/version-bumper.sh ./docs/source/bskVersion.txt + + - name: Commit and push + run: | + git config user.name "AVSlabBot" + git config user.email "cuavslab@gmail.com" + git commit -a -m "[AUTO] Bump version number" || echo "No changes" + git push || true + + build-ubuntu-latest-wheels: + name: Build ubuntu-latest wheels + needs: bump_version + # Allow for manual runs to generate new wheels + if: ${{ always() }} + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11"] + steps: + - name: Checkout code + uses: actions/checkout@v4 + + # The 'Build wheel' step will perform the actual build. However, we want + # all pre build setup to still be performed + - uses: ./.github/actions/build + with: + python-version: ${{ matrix.python-version }} + extra-apt: "cmake" + skip-build: true + + - name: Build wheel + run: | + python -m pip wheel . -v --wheel-dir /tmp/wheelhouse + + - uses: actions/upload-artifact@v4 + with: + name: basilisk-wheels_ubuntu-22.04_python${{ matrix['python-version'] }} + path: /tmp/wheelhouse/**/*asilisk*.whl + + build_documentation: + name: macOS Docs Deployment + needs: bump_version + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - name: Build Basilisk + uses: ./.github/actions/build + with: + python-version: 3.13 + conan-args: --opNav True --allOptPkg --mujoco True --mujocoReplay True --recorderPropertyRollback True + - name: Build docs + uses: ./.github/actions/docs + - name: Deploy + if: ${{ success() }} # deploy only if prior steps ok + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs/build/html + force_orphan: true diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 00000000000..c30d90bcd53 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,10 @@ +name: Pre-commit +on: + workflow_dispatch: + +jobs: + pre-commit: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/pre-commit diff --git a/.github/workflows/pull-request-closed.yml b/.github/workflows/pull-request-closed.yml deleted file mode 100644 index d88cc1973b4..00000000000 --- a/.github/workflows/pull-request-closed.yml +++ /dev/null @@ -1,124 +0,0 @@ -name: "Pull Request Closed" - -on: - pull_request: - types: - - closed - branches: - - develop - workflow_dispatch: - -jobs: - if_merged: - if: github.event.pull_request.merged == true - runs-on: ubuntu-latest - steps: - - name: Pull repo - uses: actions/checkout@v4 - with: - ref: develop - fetch-depth: 0 - token: ${{ secrets.BOT_ACCESS_TOKEN }} - - name: Bump version - run: ./.github/workflows/version-bumper.sh ./docs/source/bskVersion.txt - - name: Commit and push - run: | - git config user.name "AVSlabBot" - git config user.email "cuavslab@gmail.com" - git commit -a -m "[AUTO] Bump version number" - git push - - - wait_for_version_bump: - name: Wait for version bump - needs: if_merged - # run even if the version bump failed. If the merge is from an external fork the bump fails. - if: ${{ always() }} - runs-on: ubuntu-latest - steps: - - name: Wait for version number to be bumped - run: sleep 15 - - - build-ubuntu-latest-wheels: - name: Build ubuntu-latest wheels - needs: wait_for_version_bump - # Allow for manual runs to generate new wheels - if: ${{ always() }} - runs-on: ubuntu-22.04 - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11"] - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: "Install swig and cmake" - run: sudo apt-get update && sudo apt-get install build-essential swig cmake -y - - name: "Install python packages" - run: sudo apt-get install python3-setuptools python3-tk python3-venv - - name: "Create virtual Environment" - run: python3 -m venv .venv - - name: "Build basilisk" - run: | - source .venv/bin/activate - pip wheel . -v --wheel-dir /tmp/wheelhouse - - uses: actions/upload-artifact@v4 - with: - name: basilisk-wheels_ubuntu-22.04_python${{ matrix.python-version }} - path: /tmp/wheelhouse/**/*asilisk*.whl - - - build_documentation: - name: macOS Docs Deployment - needs: wait_for_version_bump - runs-on: macos-14 - strategy: - matrix: - python-version: [ "3.11" ] - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Install Homebrew - run: | - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - brew install swig doxygen - - - name: "Create virtual Environment" - run: python3 -m venv .venv - - name: "Install -r requirements_dev.txt" - run: | - source .venv/bin/activate - pip3 install cmake -r requirements_dev.txt - - - name: "Build basilisk with all options" - run: | - source .venv/bin/activate - python3 conanfile.py --opNav True --allOptPkg --mujoco True --mujocoReplay True - - - name: "Run Python Tests" - run: | - source .venv/bin/activate - cd src - pytest -n auto -m "not ciSkip" - - - name: "Build Documentation" - run: | - source .venv/bin/activate - cd docs - make html SPHINXOPTS="-W" - - - name: Deploy - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs/build/html - force_orphan: true diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 329440f6763..8788513c12f 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -13,281 +13,121 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - with: - python-version: 3.11 - - id: file_changes - uses: tj-actions/changed-files@v44 - - uses: pre-commit/action@v3.0.1 - with: - extra_args: --files ${{ steps.file_changes.outputs.all_changed_files}} - + - uses: ./.github/actions/pre-commit - build-linux-3-10: - name: Linux 22.04 + build-linux: runs-on: ubuntu-22.04 - timeout-minutes: 75 + timeout-minutes: 90 + needs: pre-commit strategy: + fail-fast: false matrix: - python-version: ["3.8", "3.9", "3.10"] + python: ["3.13"] + name: Linux (${{ matrix.python }}) steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + - uses: actions/checkout@v4 + - uses: ./.github/actions/build with: - python-version: ${{ matrix.python-version }} - - name: "Install swig" - run: sudo apt-get update && sudo apt-get install build-essential swig -y - - name: "Install python packages" - run: sudo apt-get install python3-setuptools python3-tk python3.10-venv - - name: "Create virtual Environment" - run: python3 -m venv .venv - - name: "Install requirements_dev.txt" - run: source .venv/bin/activate && pip3 install -r requirements_dev.txt pytest-timeout - - name: "Build basilisk" - run: source .venv/bin/activate && python3 conanfile.py - - name: "Run Python Tests" + python-version: ${{ matrix.python }} + conan-args: --opNav True --mujoco True --mujocoReplay True --recorderPropertyRollback True + - name: Pytest + working-directory: src run: | - source .venv/bin/activate - cd src && pytest -n auto -m "not ciSkip" -rs --dist=loadscope -v - - - name: "Run C/C++ Tests" - working-directory: ./dist3 - run: ctest + pip install pytest-error-for-skips + pytest -n auto -m "not ciSkip" -rs --error-for-skips --dist=loadscope -v + - name: CTest if: ${{ always() }} - - - build-linux-3-11: - name: Linux 22.04 All Tests - runs-on: ubuntu-22.04 - timeout-minutes: 75 - strategy: - matrix: - python-version: ["3.11"] - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: "Install libgtk2.0" - run: sudo apt-get update && sudo apt-get install build-essential libgtk2.0 -y - - name: Install SWIG 4.2.1 - uses: mmomtchev/setup-swig@v3 - with: - version: v4.2.1 - - name: "Install python packages" - run: sudo apt-get install python3-setuptools python3-tk python3.11-venv - - name: "Create virtual Environment" - run: python3 -m venv .venv - - name: "Install requirements_dev.txt" - run: source .venv/bin/activate && pip3 install -r requirements_dev.txt pytest-error-for-skips pytest-timeout - - name: "Update 'default' conan profile to allow installing system packages" - run: | - source .venv/bin/activate - python3 -m conans.conan profile detect --exist-ok - echo -e "\n[conf]\ntools.system.package_manager:mode=install\ntools.system.package_manager:sudo=True\n" >> $(python3 -m conans.conan profile path default) - - name: "Build basilisk" - run: source .venv/bin/activate && python3 conanfile.py --opNav True --mujoco True --mujocoReplay True --recorderPropertyRollback True - - - name: "Run Python Tests" - run: | - source .venv/bin/activate - cd src && pytest -n auto -m "not ciSkip" -rs --error-for-skips --dist=loadscope -v - - - name: "Run C/C++ Tests" - working-directory: ./dist3 + working-directory: dist3 run: ctest - if: ${{ always() }} - - build-linux-3-11-pip: - name: Linux 22.04 pip - runs-on: ubuntu-22.04 - timeout-minutes: 75 - strategy: - matrix: - python-version: ["3.11"] - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: "Install swig" - run: sudo apt-get update && sudo apt-get install build-essential swig -y - - name: "Install python packages" - run: sudo apt-get install python3-setuptools python3-tk python3.11-venv - - name: "Create virtual Environment" - run: python3 -m venv .venv - - name: "Build basilisk" - run: | - source .venv/bin/activate - pip install -r requirements_dev.txt - pip install . -v - bskLargeData - - name: "Run Python Tests" - run: | - source .venv/bin/activate - pip install pytest pytest-xdist - cd src && pytest -n auto -m "not ciSkip" -rs --dist=loadscope -v - build-windows: - name: Windows All Tests runs-on: windows-2025 - timeout-minutes: 100 + timeout-minutes: 90 + needs: pre-commit strategy: + fail-fast: false matrix: - python-version: ["3.11"] + python: ["3.13"] + name: Windows (${{ matrix.python }}) env: MPLBACKEND: agg steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + - uses: actions/checkout@v4 + - uses: ./.github/actions/build with: - python-version: ${{ matrix.python-version }} -# - name: Choco help -# uses: crazy-max/ghaction-chocolatey@v3 -# with: -# args: -h -# - name: "Install swig" -# shell: pwsh -# run: choco install swig -y - - name: "Install SWIG 4.2.1" - shell: pwsh - run: | - $swigDir = "C:\Program Files\SWIG" - if (!(Test-Path $swigDir)) {New-Item -ItemType Directory -Path $swigDir | Out-Null} - $swigZip = "$swigDir\swigwin-4.2.1.zip" - $swigUrl = "https://sourceforge.net/projects/swig/files/swigwin/swigwin-4.2.1/swigwin-4.2.1.zip/download" - Start-Process -NoNewWindow -Wait -FilePath "curl.exe" -ArgumentList "-L -o `"$swigZip`" `"$swigUrl`"" - if (!(Test-Path $swigZip) -or ((Get-Item $swigZip).Length -lt 500KB)) { Write-Host "Download failed or file is corrupted." } - Expand-Archive -Path $swigZip -DestinationPath $swigDir -Force - - name: "Create python virtual env" - shell: pwsh - run: python -m venv venv - - name: "Install requirements_dev.txt" - shell: pwsh - run: | - venv\Scripts\activate - pip install -r requirements_dev.txt pytest-error-for-skips pytest-timeout - - name: "Add basilisk and swig path to env path" - shell: pwsh - run: | - $oldpath = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).path - $newPath = “C:\Program Files\SWIG\swigwin-4.2.1;$oldpath;${{ env.GITHUB_WORKSPACE }}\dist3\Basilisk” - echo "PATH=$newPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - - name: "Build basilisk" + python-version: ${{ matrix.python }} + conan-args: --opNav True --mujoco True --mujocoReplay True --recorderPropertyRollback True + - name: Pytest shell: pwsh + working-directory: src run: | - venv\Scripts\activate - python conanfile.py --opNav True --mujoco True --mujocoReplay True --recorderPropertyRollback True - - name: "Run Python Tests" - shell: pwsh - run: | - Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name MPLBACKEND -Value ${MPLBACKEND} - venv\Scripts\activate - cd src - pytest -n auto -m "not ciSkip" -rs --error-for-skips --dist=loadscope -v + pip install pytest-error-for-skips + pytest -n auto -m "not ciSkip" -rs --error-for-skips --dist=loadscope -v if(($LastExitCode -ne 0) -and ($LastExitCode -ne 5)) {exit 1} - - name: "C/C++ Tests" + - name: CTest if: ${{ always() }} shell: pwsh + working-directory: dist3 run: | - cd dist3 ctest - if(($LastExitCode -ne 0) -and ($LastExitCode -ne 5)) {exit 1} + if(($LastExitCode -ne 0) -and ($LastExitCode -ne 5)) { exit 1 } - build-macOS: - name: macOS All Tests Docs + build-macos: runs-on: macos-latest - timeout-minutes: 75 + timeout-minutes: 90 + needs: pre-commit strategy: + fail-fast: false matrix: - python-version: [ "3.11", "3.12", "3.13" ] + job_suffix: [""] + python: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + pytest_flags: + ['-n auto -m "not ciSkip" -rs --error-for-skips --dist=loadscope -v'] + conan_args: + [ + "--opNav True --mujoco True --mujocoReplay True --recorderPropertyRollback True", + ] + include: + # An extra Basilisk build to test building without visualization enabled + - python: "3.13" + pytest_flags: -n auto -m "not ciSkip" -rs --dist=loadscope -v + conan_args: --opNav True --mujoco True --mujocoReplay True --recorderPropertyRollback True --vizInterface False + job_suffix: "--vizInterface False" + # Python 3.8 cannot run all tests. + # TODO: Once Python 3.8 support is dropped, delete this include and exclude and remove 3.8 from the python + # test matrix. + - python: "3.8" + pytest_flags: -n auto -m "not ciSkip" -rs --dist=loadscope -v -p no:pytest_forbid_skips + exclude: + - python: "3.8" + pytest_flags: '-n auto -m "not ciSkip" -rs --error-for-skips --dist=loadscope -v' + + name: macOS (${{ matrix.python }}) ${{ matrix.job_suffix }} steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + - uses: actions/checkout@v4 + - uses: ./.github/actions/build with: - python-version: ${{ matrix.python-version }} - - - name: Install Homebrew - run: | - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - brew install swig doxygen - - - name: "Create virtual Environment" - run: python3 -m venv .venv - - name: "Install requirements_dev.txt" - run: | - source .venv/bin/activate - pip3 install -r requirements_dev.txt pytest-error-for-skips pytest-timeout - - - name: "Build basilisk with all options" - run: | - source .venv/bin/activate - python3 conanfile.py --opNav True --allOptPkg --mujoco True --mujocoReplay True --recorderPropertyRollback True - - - name: "Run Python Tests" - run: | - source .venv/bin/activate - cd src - pytest -n auto -m "not ciSkip" -rs --error-for-skips --dist=loadscope -v + python-version: ${{ matrix.python }} + conan-args: --opNav True --mujoco True --mujocoReplay True --recorderPropertyRollback True + - name: Pytest + working-directory: src + run: | + pip install pytest-error-for-skips + pytest ${{ matrix.pytest_flags }} + - name: CTest if: ${{ always() }} - - name: "Run C/C++ Tests" - working-directory: ./dist3 + working-directory: dist3 run: ctest -C Release - if: ${{ always() }} - - name: "Build Documentation" - run: | - source .venv/bin/activate - cd docs - make html SPHINXOPTS="-W" - if: ${{ always() }} - - build-macOS-no-vizInterface: - name: macOS no vizInterface + docs: + needs: build-macos runs-on: macos-latest - timeout-minutes: 75 - strategy: - matrix: - python-version: [ "3.11" ] steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + - uses: actions/checkout@v4 + - name: Build Basilisk + uses: ./.github/actions/build with: - python-version: ${{ matrix.python-version }} - - - name: Install Homebrew - run: | - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - brew install swig - - - name: "Create virtual Environment" - run: python3 -m venv .venv - - name: "Install requirements_dev.txt" - run: | - source .venv/bin/activate - pip3 install -r requirements_dev.txt - - - name: "Build basilisk without vizInterface" - run: source .venv/bin/activate && python3 conanfile.py --vizInterface False - - name: "Run Python Tests" - run: | - source .venv/bin/activate - cd src - pytest -n auto -m "not ciSkip" -rs --dist=loadscope -v - - if: ${{ always() }} + python-version: 3.13 + conan-args: --opNav True --allOptPkg --mujoco True --mujocoReplay True --recorderPropertyRollback True + - name: Build docs + uses: ./.github/actions/docs diff --git a/.gitignore b/.gitignore index 1413ec07d8b..2b717ce721a 100755 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,5 @@ venv/ # Python packaging *.egg-info build/ +!.github/actions/build/ +!.github/actions/build/** diff --git a/docs/source/Support/bskReleaseNotes.rst b/docs/source/Support/bskReleaseNotes.rst index 8cbf9f402af..86761c8d5f1 100644 --- a/docs/source/Support/bskReleaseNotes.rst +++ b/docs/source/Support/bskReleaseNotes.rst @@ -26,7 +26,10 @@ Basilisk Release Notes Version |release| ----------------- -- text here +- Removed deprecated use of astro constants from ``src/utilities/astroFunction.py``. + Users should be astrodynamics constants from ``Basilisk.architecture.astroConstants``. +- Refactored the CI build system scripts + Version 2.78.0 (August 30, 2025) -------------------------------- diff --git a/setup.py b/setup.py index 5cff6e7a99a..dba17adcc96 100644 --- a/setup.py +++ b/setup.py @@ -91,9 +91,10 @@ def get_source_files(self) -> list[str]: def run(self) -> None: for ext in self.conan_extensions: if self.editable_mode: - # TODO: Add support for installing in editable mode. For now, we - # assume that it has already been built (e.g. by `conanfile.py`) - pass + # TODO: Add support for installing in editable mode. + built = any(Path(ext.build_dir).glob("Basilisk*")) + if not built: + run([sys.executable, ext.conanfile] + ext.args, check=True) else: # Call the underlying Conanfile with the desired arguments. run([sys.executable, ext.conanfile] + ext.args, check=True) diff --git a/src/architecture/utilities/tests/test_legacyAstroConstants.py b/src/architecture/utilities/tests/test_legacyAstroConstants.py deleted file mode 100644 index 893531faf39..00000000000 --- a/src/architecture/utilities/tests/test_legacyAstroConstants.py +++ /dev/null @@ -1,85 +0,0 @@ -# ISC License -# -# Copyright (c) 2024, Autonomous Vehicle Systems Lab, University of Colorado at Boulder -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - -from Basilisk.utilities import astroFunctions -import warnings -from Basilisk.utilities import deprecated -import numpy as np - -def test_legacy_astrofunctions_constants(show_plots): - __tracebackhide__ = True - - warnings.filterwarnings("ignore", category=deprecated.BSKDeprecationWarning) - - # check that deprecated astroFunction constants still work - # when it is time to remove this deprectated functionality, - # go to src/utilities/astroFunctions.py and remove - # - from Basilisk.utilities import deprecated - # - remove __getattr__() method near end of file - # - remove this test file - - # define astroConstant names - AU = 1.49597870691e8 # [km] - astroConstants = { - # Useful conversions - 'R2D': 180.0 / np.pi, # [deg] - 'D2R': np.pi / 180.0, # [rad] - 'AU': AU, - 'SEC2DAY': 1.0 / (3600*24), - 'DAY2SEC': 1.0 * 3600 * 24, - 'PI': np.pi, - - # Gravitational parameters [km^3 / s^2] - 'mu_S': 1.32712440018e11, - 'mu_E': 3.986004415e5, - 'mu_M': 4.28283100e4, - 'mu_V': 3.24858599e5, - 'mu_J': 1.26686534e8, - 'mu_Saturn': 3.79395000e7, - 'mu_U': 5.79396566e6, - 'mu_N': 6.83509920e6, - 'mu_Moon': 4902.799, - - # Planets' Radius [km] - 'S_radius': 695508, - 'J_radius': 71492, - 'V_radius': 6051.8, - 'E_radius': 6378.1363, - 'M_radius': 3396.19, - 'Saturn_radius': 60268, - 'U_radius': 25559, - 'N_radius': 24764, - 'Moon_radius': 1738.1, - - # Planetary Heliocentric orbits [km] - 'a_E': 1.0 * AU, - 'a_M': 1.52367934 * AU, - 'a_Mercury': 0.387 * AU, - 'a_V': 0.723 * AU, - 'a_J': 5.203 * AU, - 'a_Saturn': 9.537 * AU, - 'a_U': 19.191 * AU, - 'a_N': 30.069 * AU, - 'a_P': 39.482 * AU, - } - - for key in astroConstants: - np.testing.assert_almost_equal(getattr(astroFunctions, key), astroConstants[key]) - -'' -if __name__ == '__main__': - test_legacy_astrofunctions_constants(False) diff --git a/src/utilities/astroFunctions.py b/src/utilities/astroFunctions.py index 1303ede9df2..51f26644b82 100755 --- a/src/utilities/astroFunctions.py +++ b/src/utilities/astroFunctions.py @@ -20,7 +20,6 @@ import matplotlib.pyplot as plt import numpy as np from numpy import linalg as la -from Basilisk.utilities import deprecated from Basilisk.architecture import astroConstants # Reference solar flux at Earth [W/m^2] @@ -683,61 +682,6 @@ def Tisserand_ESU(): plt.show() -# ------------------------------------------------------------------------------------------------------------------- # -# DEPRECATED CONSTANTS -# - -def __getattr__(name): - """ Special `__getattr__` to handle deprecation warning """ - AU = 1.49597870691e8 # [km] - astroConstants = { - # Useful conversions - 'R2D': 180.0 / np.pi, # [deg] - 'D2R': np.pi / 180.0, # [rad] - 'AU': AU, - 'SEC2DAY': 1.0 / (3600*24), - 'DAY2SEC': 1.0 * 3600 * 24, - 'PI': np.pi, - - # Gravitational parameters [km^3 / s^2] - 'mu_S': 1.32712440018e11, - 'mu_E': 3.986004415e5, - 'mu_M': 4.28283100e4, - 'mu_V': 3.24858599e5, - 'mu_J': 1.26686534e8, - 'mu_Saturn': 3.79395000e7, - 'mu_U': 5.79396566e6, - 'mu_N': 6.83509920e6, - 'mu_Moon': 4902.799, - - # Planets' Radius [km] - 'S_radius': 695508, - 'J_radius': 71492, - 'V_radius': 6051.8, - 'E_radius': 6378.1363, - 'M_radius': 3396.19, - 'Saturn_radius': 60268, - 'U_radius': 25559, - 'N_radius': 24764, - 'Moon_radius': 1738.1, - - # Planetary Heliocentric orbits [km] - 'a_E': 1.0 * AU, - 'a_M': 1.52367934 * AU, - 'a_Mercury': 0.387 * AU, - 'a_V': 0.723 * AU, - 'a_J': 5.203 * AU, - 'a_Saturn': 9.537 * AU, - 'a_U': 19.191 * AU, - 'a_N': 30.069 * AU, - 'a_P': 39.482 * AU, - } - if name in astroConstants: - deprecated.deprecationWarn( - name, '2025/08/31', 'Astro constants should be used from Basilisk.architecture.astroConstants') - return astroConstants[name] - - def main(): Mars_RV(JulianDate([2018, 10, 16]))