diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 33922b3b..982b2960 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,100 +1,135 @@ +name: Continuous integration + on: push: - branches: [ master ] + branches: [master] pull_request: -name: Continuous integration +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true jobs: - ci: + rust_tests: + name: Rust tests (${{ matrix.name }}) runs-on: ${{ matrix.os }} + timeout-minutes: 45 strategy: + fail-fast: false matrix: - os: [ubuntu-latest] + include: + - name: Linux + os: ubuntu-latest + - name: macOS + os: macos-latest + steps: + - uses: actions/checkout@v5 + + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + rustflags: "" + + - name: Cargo tests + run: cargo test + + - name: Cargo tests (RP and JEM) + run: | + cargo test --features rp + cargo test --features jem + + python_tests: + name: Python tests (${{ matrix.name }}) + needs: rust_tests + runs-on: ${{ matrix.os }} + timeout-minutes: 45 + strategy: + fail-fast: false + matrix: + include: + - name: Linux + os: ubuntu-latest + skip_rpi_test: 0 + - name: macOS + os: macos-latest + skip_rpi_test: 1 env: DO_DOCKER: 0 + SKIP_RPI_TEST: ${{ matrix.skip_rpi_test }} steps: - - uses: actions/checkout@v2 - - uses: egor-tensin/setup-clang@v1 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v5 + + - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - profile: minimal toolchain: stable - override: true - - uses: actions-rs/cargo@v1 - with: - command: test - - uses: actions/setup-python@v5 + components: clippy + rustflags: "" + + - uses: actions/setup-python@v6 with: - python-version: '3.12' - architecture: 'x64' + python-version: "3.12" + cache: "pip" + cache-dependency-path: open-codegen/setup.py + + - uses: egor-tensin/setup-clang@v1 + if: runner.os == 'Linux' + + - name: Install Linux ARM target + if: runner.os == 'Linux' + run: rustup target add arm-unknown-linux-gnueabihf + - name: Install ARM cross-compiler and C libraries + if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install -y gcc-arm-linux-gnueabihf libc6-dev-armhf-cross - # If icasadi_rosenbrock or other deps need C++: - # sudo apt-get install -y g++-arm-linux-gnueabihf - - name: Cargo tests (RP and JEM) - run: | - cargo test --features rp - cargo test --features jem - - name: Run tests (script.sh) - # Set environment variables for the cc crate + + - name: Install LLVM + if: runner.os == 'macOS' + run: brew install llvm + + - name: Run Python tests and generated Clippy checks + if: runner.os == 'Linux' env: CC_arm_unknown_linux_gnueabihf: arm-linux-gnueabihf-gcc AR_arm_unknown_linux_gnueabihf: arm-linux-gnueabihf-ar - # If C++ is involved and you installed g++-arm-linux-gnueabihf: - # CXX_arm_unknown_linux_gnueabihf: arm-linux-gnueabihf-g++ - run: | - bash ./ci/script.sh + run: bash ./ci/script.sh python-tests - ci_macos: + - name: Run Python tests and generated Clippy checks + if: runner.os == 'macOS' + run: bash ./ci/script.sh python-tests + + ocp_tests: + name: OCP tests (${{ matrix.name }}) + needs: python_tests runs-on: ${{ matrix.os }} + timeout-minutes: 45 strategy: + fail-fast: false matrix: - os: [macos-latest] + include: + - name: Linux + os: ubuntu-latest + - name: macOS + os: macos-latest env: DO_DOCKER: 0 steps: - - uses: actions/checkout@v2 - - run: brew install llvm - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v5 + + - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - profile: minimal toolchain: stable - override: true - - uses: actions-rs/cargo@v1 - with: - command: test - - uses: actions/setup-python@v5 + rustflags: "" + + - uses: actions/setup-python@v6 with: - python-version: '3.12' - - run: cargo test --features rp - - run: cargo test --features jem - - name: Install ARM cross-compiler toolchain (via Homebrew) - run: | - # Tap the repository that provides the cross-compiler - brew tap messense/macos-cross-toolchains - # Update brew to ensure the tap is recognized (can sometimes be needed) - brew update - # Install the full toolchain (includes gcc, binutils, sysroot) - # This specific formula provides the entire toolchain. - brew install arm-unknown-linux-gnueabihf - - # The above `brew install` might have linking conflicts if other partial - # toolchains were somehow pre-installed or installed by other steps. - # If it fails with link errors, you might need: - # brew link --overwrite arm-unknown-linux-gnueabihf - - # Verify the compiler is found - which arm-linux-gnueabihf-gcc || (echo "arm-linux-gnueabihf-gcc not found in PATH" && exit 1) - - name: Run tests (script.sh) - # Set environment variables for the cc crate and PyO3 (if needed) - env: - CC_arm_unknown_linux_gnueabihf: arm-linux-gnueabihf-gcc - AR_arm_unknown_linux_gnueabihf: arm-linux-gnueabihf-ar - # If you are building PyO3 bindings and need to specify Python libs from the sysroot: - # PYO3_CROSS_LIB_DIR: "/opt/homebrew/opt/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/sysroot/usr/lib" # Adjust path and Python version - # PYO3_CROSS_INCLUDE_DIR: "/opt/homebrew/opt/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/sysroot/usr/include/python3.x" # Adjust path and Python version - run: | - bash ./ci/script.sh + python-version: "3.12" + cache: "pip" + cache-dependency-path: open-codegen/setup.py + + - name: Run OCP Python tests + run: bash ./ci/script.sh ocp-tests diff --git a/ci/script.sh b/ci/script.sh index 35599d7e..18f1f2b7 100755 --- a/ci/script.sh +++ b/ci/script.sh @@ -1,6 +1,9 @@ #!/bin/bash set -euxo pipefail +SKIP_RPI_TEST="${SKIP_RPI_TEST:-0}" +TASK="${1:-all-python-tests}" + function run_clippy_test() { pushd $1 cargo clippy --all-targets --all-features @@ -21,53 +24,51 @@ function run_clippy_test() { popd } -regular_test() { - # Run Python tests - # ------------------------------------ - - # --- create virtual environment +setup_python_test_env() { cd open-codegen export PYTHONPATH=. - # --- install virtualenv - pip install virtualenv - - # --- create virtualenv - virtualenv -p python3.12 venv - - # --- activate venv + python -m venv venv source venv/bin/activate + python -m pip install --upgrade pip + python -m pip install . +} - # --- upgrade pip within venv - pip install --upgrade pip - - # --- install opengen - pip install . - - # --- rust dependencies - rustup update - rustup target add arm-unknown-linux-gnueabihf +generated_clippy_tests() { + pushd .python_test_build + run_clippy_test "only_f1" + run_clippy_test "only_f2" + run_clippy_test "halfspace_optimizer" + run_clippy_test "parametric_f2" + run_clippy_test "plain" + run_clippy_test "python_bindings" + run_clippy_test "rosenbrock_ros" + popd +} - # --- run the tests +run_python_core_tests() { export PYTHONPATH=. + python -W ignore test/test_constraints.py -v python -W ignore test/test.py -v - python -W ignore test/test_ocp.py -v - python -W ignore test/test_raspberry_pi.py -v - + if [ "$SKIP_RPI_TEST" -eq 0 ]; then + python -W ignore test/test_raspberry_pi.py -v + fi # Run Clippy for generated optimizers # ------------------------------------ + generated_clippy_tests +} - cd .python_test_build - run_clippy_test "only_f1" - run_clippy_test "only_f2" - run_clippy_test "halfspace_optimizer" - run_clippy_test "parametric_f2" - run_clippy_test "plain" - run_clippy_test "python_bindings" - run_clippy_test "rosenbrock_ros" - +run_python_ocp_tests() { + export PYTHONPATH=. + python -W ignore test/test_ocp.py -v +} + +all_python_tests() { + setup_python_test_env + run_python_core_tests + run_python_ocp_tests } test_docker() { @@ -77,8 +78,26 @@ test_docker() { main() { if [ $DO_DOCKER -eq 0 ]; then - echo "Running regular tests" - regular_test + case "$TASK" in + python-tests) + echo "Running Python tests and generated Clippy tests" + setup_python_test_env + run_python_core_tests + ;; + ocp-tests) + echo "Running OCP Python tests" + setup_python_test_env + run_python_ocp_tests + ;; + all-python-tests) + echo "Running Python tests, generated Clippy tests, and OCP tests" + all_python_tests + ;; + *) + echo "Unknown task: $TASK" + exit 1 + ;; + esac else echo "Building Docker image" test_docker