name: tests on: push: branches: - master pull_request: workflow_dispatch: workflow_call: inputs: run_number: default: '1' required: true type: string concurrency: group: tests-ci-run-${{ inputs.run_number }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && github.run_id || github.head_ref || github.ref }}-${{ github.workflow }}-${{ github.event_name }} cancel-in-progress: true env: CI: 1 jobs: build_release: name: build release runs-on: ${{ (github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot')) && fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]') || fromJSON('["ubuntu-24.04"]') }} env: STRIPPED_DIR: /tmp/releasepilot PYTHONPATH: /tmp/releasepilot steps: - uses: actions/checkout@v6 with: submodules: true - name: Getting LFS files uses: nick-fields/retry@7152eba30c6575329ac0576536151aca5a72780e with: timeout_minutes: 2 max_attempts: 3 command: git lfs pull - name: Build devel timeout-minutes: 1 run: TARGET_DIR=$STRIPPED_DIR release/build_stripped.sh - uses: ./.github/workflows/setup-with-retry - name: Build openpilot and run checks timeout-minutes: 30 working-directory: ${{ env.STRIPPED_DIR }} run: python3 system/manager/build.py - name: Run tests timeout-minutes: 1 working-directory: ${{ env.STRIPPED_DIR }} run: release/check-dirty.sh - name: Check submodules if: github.repository == 'commaai/openpilot' timeout-minutes: 3 run: release/check-submodules.sh build_mac: name: build macOS runs-on: ${{ ((github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot'))) && 'namespace-profile-macos-8x14' || 'macos-latest' }} steps: - uses: actions/checkout@v6 with: submodules: true - uses: ./.github/workflows/setup-with-retry - name: Building openpilot run: scons static_analysis: name: static analysis runs-on: ${{ (github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot')) && fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]') || fromJSON('["ubuntu-24.04"]') }} steps: - uses: actions/checkout@v6 with: submodules: true - uses: ./.github/workflows/setup-with-retry - name: Static analysis timeout-minutes: 1 run: scripts/lint/lint.sh unit_tests: name: unit tests runs-on: ${{ (github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot')) && fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]') || fromJSON('["ubuntu-24.04"]') }} steps: - uses: actions/checkout@v6 with: submodules: true - uses: ./.github/workflows/setup-with-retry id: setup-step - name: Build openpilot run: scons -j$(nproc) - name: Run unit tests timeout-minutes: ${{ contains(runner.name, 'nsc') && ((steps.setup-step.outputs.duration < 18) && 1 || 2) || 20 }} run: | source selfdrive/test/setup_xvfb.sh # Pre-compile Python bytecode so each pytest worker doesn't need to pytest --collect-only -m 'not slow' -qq MAX_EXAMPLES=1 pytest -m 'not slow' process_replay: name: process replay runs-on: ${{ (github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot')) && fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]') || fromJSON('["ubuntu-24.04"]') }} steps: - uses: actions/checkout@v6 with: submodules: true - uses: ./.github/workflows/setup-with-retry id: setup-step - name: Cache test routes id: dependency-cache uses: actions/cache@v5 with: path: /tmp/comma_download_cache key: proc-replay-${{ hashFiles('selfdrive/test/process_replay/test_processes.py') }} - name: Build openpilot run: scons -j$(nproc) - name: Run replay timeout-minutes: ${{ contains(runner.name, 'nsc') && (steps.dependency-cache.outputs.cache-hit == 'true') && ((steps.setup-step.outputs.duration < 18) && 1 || 2) || 20 }} continue-on-error: ${{ github.ref == 'refs/heads/master' }} run: selfdrive/test/process_replay/test_processes.py -j$(nproc) - name: Print diff id: print-diff if: always() run: cat selfdrive/test/process_replay/diff.txt - uses: actions/upload-artifact@v6 if: always() continue-on-error: true with: name: process_replay_diff.txt path: selfdrive/test/process_replay/diff.txt - name: Checkout ci-artifacts if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master' uses: actions/checkout@v4 with: repository: commaai/ci-artifacts ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }} path: ${{ github.workspace }}/ci-artifacts - name: Push refs if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master' working-directory: ${{ github.workspace }}/ci-artifacts run: | git checkout --orphan process-replay git rm -rf . git config user.name "GitHub Actions Bot" git config user.email "<>" cp ${{ github.workspace }}/selfdrive/test/process_replay/fakedata/*.zst . echo "${{ github.sha }}" > ref_commit git add . git commit -m "process-replay refs for ${{ github.repository }}@${{ github.sha }}" git push origin process-replay --force - name: Run regen if: false timeout-minutes: 4 env: ONNXCPU: 1 run: pytest selfdrive/test/process_replay/test_regen.py simulator_driving: name: simulator driving runs-on: ${{ (github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot')) && fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]') || fromJSON('["ubuntu-24.04"]') }} if: false # FIXME: Started to timeout recently steps: - uses: actions/checkout@v6 with: submodules: true - uses: ./.github/workflows/setup-with-retry id: setup-step - name: Build openpilot run: scons -j$(nproc) - name: Driving test timeout-minutes: ${{ (steps.setup-step.outputs.duration < 18) && 1 || 2 }} run: | source selfdrive/test/setup_xvfb.sh pytest -s tools/sim/tests/test_metadrive_bridge.py create_ui_report: name: Create UI Report runs-on: ${{ (github.repository == 'commaai/openpilot') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.full_name == 'commaai/openpilot')) && fromJSON('["namespace-profile-amd64-8x16", "namespace-experiments:docker.builds.local-cache=separate"]') || fromJSON('["ubuntu-24.04"]') }} steps: - uses: actions/checkout@v6 with: submodules: true - uses: ./.github/workflows/setup-with-retry - name: Build openpilot run: scons -j$(nproc) - name: Create UI Report run: | source selfdrive/test/setup_xvfb.sh python3 selfdrive/ui/tests/diff/replay.py python3 selfdrive/ui/tests/diff/replay.py --big - name: Upload UI Report uses: actions/upload-artifact@v6 with: name: ui-report-${{ inputs.run_number || '1' }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/master' && 'master' || github.event.number }} path: selfdrive/ui/tests/diff/report