[Draft] Add GitHub Actions workflow and CloudFormation templates #44
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Copyright 2025 NVIDIA Corporation | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| name: CI | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main, develop] | |
| env: | |
| PYTHONPATH: ${{ github.workspace }} | |
| jobs: | |
| pre-commit: | |
| name: Pre-commit Checks | |
| runs-on: self-hosted | |
| container: | |
| image: python:3.12-slim | |
| steps: | |
| - name: Setup Git and LFS | |
| run: | | |
| apt-get update -y | |
| DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git git-lfs | |
| git config --global --add safe.directory /__w/SWAGGER/SWAGGER | |
| git lfs install --force | |
| mkdir -p .git/hooks | |
| rm -f .git/hooks/pre-push | |
| rm -f .git/hooks/post-checkout | |
| git config --global core.hooksPath /dev/null | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| lfs: true | |
| fetch-depth: 0 | |
| - name: Cache Python packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: precommit-${{ hashFiles('.pre-commit-config.yaml') }} | |
| restore-keys: | | |
| precommit- | |
| - name: Install dependencies | |
| run: | | |
| set -e | |
| python3 -m pip install --upgrade pip | |
| python3 -m pip install pre-commit | |
| pre-commit --version | |
| - name: Run pre-commit | |
| run: | | |
| echo "Current directory: $(pwd)" | |
| echo "Listing files in workspace:" | |
| ls -la | |
| git status | |
| git log -1 | |
| echo "Running pre-commit..." | |
| pre-commit run --all-files | |
| timeout-minutes: 60 | |
| package-check: | |
| name: Package Check | |
| runs-on: self-hosted | |
| needs: pre-commit | |
| container: | |
| image: python:3.12-slim | |
| steps: | |
| - name: Setup Git and LFS | |
| run: | | |
| apt-get update -y | |
| DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git git-lfs | |
| git config --global --add safe.directory /__w/SWAGGER/SWAGGER | |
| git lfs install | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| lfs: true | |
| - name: Cache pip packages for Poetry | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/pip | |
| key: poetry-pip-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| poetry-pip- | |
| - name: Install dependencies | |
| run: | | |
| set -e | |
| python3 -m pip install --upgrade pip | |
| python3 -m pip install poetry | |
| poetry env use python3.12 | |
| poetry install | |
| - name: Run Poetry check | |
| run: poetry check | |
| timeout-minutes: 15 | |
| unit-tests: | |
| name: Unit Tests | |
| needs: package-check | |
| runs-on: self-hosted | |
| env: | |
| CUDA_VISIBLE_DEVICES: all | |
| container: | |
| image: nvidia/cuda:12.6.0-runtime-ubuntu22.04 | |
| options: --privileged --gpus all --group-add 998 | |
| steps: | |
| - name: Setup Git and LFS | |
| run: | | |
| apt-get update -y | |
| DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git git-lfs | |
| git config --global --add safe.directory /__w/SWAGGER/SWAGGER | |
| git lfs install | |
| - uses: actions/checkout@v4 | |
| with: | |
| lfs: true | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Cache Python packages | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/pip | |
| venv/ | |
| key: unit-tests-${{ hashFiles('**/requirements.txt') }} | |
| - name: Install dependencies | |
| run: | | |
| set -e | |
| apt-get update | |
| DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends python3-pip python3-venv libgl1-mesa-glx libglib2.0-0 | |
| python3 -m pip install --upgrade pip | |
| python3 -m pip install poetry | |
| poetry env use python3.12 | |
| poetry install | |
| - name: Run unit tests | |
| run: | | |
| mkdir -p test-results | |
| poetry run python -m unittest discover -p "test_*.py" -v > test-results/unit-tests.txt | |
| # Convert unittest output to JUnit XML format | |
| poetry run python -c 'import xml.etree.ElementTree as ET, re; root = ET.Element("testsuites"); suite = ET.SubElement(root, "testsuite", name="unit-tests"); [suite.append(ET.SubElement(suite, "testcase", classname=m.group(2), name=m.group(1))) if m.group(3) == "ok" else suite.append(ET.SubElement(suite, "testcase", classname=m.group(2), name=m.group(1)).append(ET.SubElement(suite, "failure", message=f"Test {m.group(1)} in {m.group(2)} {m.group(3).lower()}ed"))) for m in re.finditer(r"test_(\w+) \((.*?)\) \.\.\. (ok|FAIL|ERROR)", open("test-results/unit-tests.txt").read())]; ET.ElementTree(root).write("test-results/unit-tests.xml", encoding="utf-8", xml_declaration=True)' | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: unit-test-results | |
| path: test-results/ | |
| retention-days: 7 | |
| e2e-tests: | |
| name: End-to-End Tests | |
| needs: unit-tests | |
| runs-on: self-hosted | |
| env: | |
| CUDA_VISIBLE_DEVICES: all | |
| NVIDIA_VISIBLE_DEVICES: all | |
| container: | |
| image: nvidia/cuda:12.6.0-runtime-ubuntu22.04 | |
| options: --privileged --gpus all --group-add 998 | |
| steps: | |
| - name: Setup Git and LFS | |
| run: | | |
| apt-get update -y | |
| DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git git-lfs | |
| git config --global --add safe.directory /__w/SWAGGER/SWAGGER | |
| git lfs install | |
| - uses: actions/checkout@v4 | |
| with: | |
| lfs: true | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Install dependencies | |
| run: | | |
| set -e | |
| apt-get update | |
| DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ | |
| python3-pip python3-venv \ | |
| libgl1-mesa-glx libglib2.0-0 \ | |
| libcudnn8 libcudnn8-dev \ | |
| nvidia-cuda-toolkit | |
| python3 -m pip install --upgrade pip | |
| python3 -m pip install poetry | |
| poetry env use python3.12 | |
| poetry install | |
| - name: Verify CUDA setup | |
| run: | | |
| echo "Checking CUDA setup..." | |
| nvidia-smi | |
| python3 -c 'import os, sys, cv2, numpy as np; print("CUDA_VISIBLE_DEVICES:", os.environ.get("CUDA_VISIBLE_DEVICES")); print("NVIDIA_VISIBLE_DEVICES:", os.environ.get("NVIDIA_VISIBLE_DEVICES")); try: img = cv2.imread("maps/carter_warehouse_navigation.png"); print("Image exists:", os.path.exists("maps/carter_warehouse_navigation.png")); print("Image size:", os.path.getsize("maps/carter_warehouse_navigation.png")); if img is None: print("Failed to read image with OpenCV"); sys.exit(1); print("Image shape:", img.shape); print("Image type:", img.dtype); except Exception as e: print("Error reading image:", str(e)); sys.exit(1)' | |
| - name: Run E2E tests | |
| run: | | |
| set -e | |
| poetry run python scripts/generate_graph.py \ | |
| --map-path maps/carter_warehouse_navigation.png \ | |
| --graph-eval.active \ | |
| --perf-eval.active | |
| poetry run python scripts/evaluate_graph.py \ | |
| --graph-path graphs/graph.gml \ | |
| --map-path maps/carter_warehouse_navigation.png \ | |
| --output-dir results \ | |
| --resolution 0.05 \ | |
| --safety-distance 0.3 \ | |
| --occupancy-threshold 127 | |
| - name: Cleanup | |
| if: always() | |
| run: rm -rf results graphs | |
| docker-build: | |
| name: Docker Build and Test | |
| needs: e2e-tests | |
| runs-on: self-hosted | |
| env: | |
| CUDA_VISIBLE_DEVICES: all | |
| DOCKER_HOST: tcp://docker:2375 | |
| DOCKER_TLS_CERTDIR: "" | |
| container: | |
| image: nvidia/cuda:12.6.0-runtime-ubuntu22.04 | |
| options: --privileged --gpus all --group-add 998 | |
| steps: | |
| - name: Setup Git and LFS | |
| run: | | |
| apt-get update -y | |
| DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git git-lfs | |
| git config --global --add safe.directory /__w/SWAGGER/SWAGGER | |
| git lfs install | |
| - uses: actions/checkout@v4 | |
| with: | |
| lfs: true | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Build and test | |
| run: | | |
| set -e | |
| cd docker || { echo "Missing docker directory"; exit 1; } | |
| docker compose build --no-cache | |
| docker compose up rest-api & | |
| sleep 10 | |
| cd ../ | |
| poetry env use python3.12 | |
| poetry install | |
| poetry run python scripts/test_api_client.py \ | |
| --map_path maps/carter_warehouse_navigation.png \ | |
| --host docker | |
| - name: Cleanup | |
| if: always() | |
| run: | | |
| cd docker && docker compose down -v |