Skip to content

[Draft] Add GitHub Actions workflow and CloudFormation templates #44

[Draft] Add GitHub Actions workflow and CloudFormation templates

[Draft] Add GitHub Actions workflow and CloudFormation templates #44

Workflow file for this run

# 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