From e4fc779da1f303ce81f920183c77ee334aa16ede Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 11 Nov 2025 15:11:30 +0000 Subject: [PATCH 1/6] Initial plan From ef6873ecfb915b6468983e1e2b7bfb958344d674 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 11 Nov 2025 15:24:37 +0000 Subject: [PATCH 2/6] feat(compose): dev stack scaffold Co-authored-by: macroflux <8061740+macroflux@users.noreply.github.com> --- .gitignore | 1 + Makefile | 40 +++++- README.md | 17 +++ compose.yaml | 42 ++++++ dev/compose/README.md | 189 +++++++++++++++++++++++++++ dev/compose/docker-compose.yml | 42 ++++++ services/actuator_bus/Dockerfile | 20 +++ services/orchestrator_ren/Dockerfile | 20 +++ 8 files changed, 366 insertions(+), 5 deletions(-) create mode 100644 compose.yaml create mode 100644 dev/compose/README.md create mode 100644 dev/compose/docker-compose.yml create mode 100644 services/actuator_bus/Dockerfile create mode 100644 services/orchestrator_ren/Dockerfile diff --git a/.gitignore b/.gitignore index b739a3c..a2b45ef 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ build/ .ipynb_checkpoints/ datasets/raw/ artifacts/ +logs/ diff --git a/Makefile b/Makefile index 759379e..7348675 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,18 @@ -.PHONY: help venv validate test clean +.PHONY: help venv validate test clean up down logs compose-test compose-validate help: @echo "Available targets:" - @echo " make venv - Create Python virtual environment and install dependencies" - @echo " make validate - Run contract validator with golden checks" - @echo " make test - Run all pytest tests" - @echo " make clean - Remove virtual environment and cache files" + @echo " make venv - Create Python virtual environment and install dependencies" + @echo " make validate - Run contract validator with golden checks" + @echo " make test - Run all pytest tests" + @echo " make clean - Remove virtual environment and cache files" + @echo "" + @echo "Docker Compose targets:" + @echo " make up - Start dev stack (orchestrator + actuator)" + @echo " make down - Stop and remove dev stack containers" + @echo " make logs - Follow logs from all containers" + @echo " make compose-test - Run smoke test against running containers" + @echo " make compose-validate - Validate docker-compose configuration" venv: python -m venv .venv @@ -22,3 +29,26 @@ clean: if exist .venv rmdir /s /q .venv for /d /r %%i in (__pycache__) do @if exist "%%i" rmdir /s /q "%%i" for /d /r %%i in (.pytest_cache) do @if exist "%%i" rmdir /s /q "%%i" + +# ============================================================================ +# Docker Compose Targets +# ============================================================================ + +up: + cd dev\compose && docker compose up -d --build + +down: + cd dev\compose && docker compose down + +logs: + cd dev\compose && docker compose logs -f + +compose-test: + @echo "Testing orchestrator-ren on port 8000..." + @curl -s http://localhost:8000/ || echo "Failed to connect to orchestrator-ren" + @echo "" + @echo "Testing actuator-bus on port 8010..." + @curl -s http://localhost:8010/ || echo "Failed to connect to actuator-bus" + +compose-validate: + cd dev\compose && docker compose config diff --git a/README.md b/README.md index a95d104..11b0261 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,23 @@ git checkout -b feat/contracts-v1 git checkout -b feat/orchestrator-skeleton ``` +## Docker Compose Development Stack + +Run orchestrator-ren and actuator-bus locally: + +```bash +# Start services +docker compose up + +# In another terminal - run smoke tests +make compose-test + +# Stop services +docker compose down +``` + +See `dev/compose/README.md` for detailed documentation. + ## Branching - `main`: protected, release-quality - `dev`: integration diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..f68d423 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,42 @@ +services: + orchestrator-ren: + build: + context: ./services/orchestrator_ren + dockerfile: Dockerfile + container_name: monad-orchestrator-ren + ports: + - "8000:8000" + volumes: + - ./logs:/app/logs + healthcheck: + test: ["CMD", "python", "-c", "from urllib.request import urlopen; urlopen('http://localhost:8000/', timeout=2).read()"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 5s + networks: + - monad-network + restart: unless-stopped + + actuator-bus: + build: + context: ./services/actuator_bus + dockerfile: Dockerfile + container_name: monad-actuator-bus + ports: + - "8010:8001" + volumes: + - ./logs:/app/logs + healthcheck: + test: ["CMD", "python", "-c", "from urllib.request import urlopen; urlopen('http://localhost:8001/', timeout=2).read()"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 5s + networks: + - monad-network + restart: unless-stopped + +networks: + monad-network: + driver: bridge diff --git a/dev/compose/README.md b/dev/compose/README.md new file mode 100644 index 0000000..1eff4f0 --- /dev/null +++ b/dev/compose/README.md @@ -0,0 +1,189 @@ +# MONAD Development Stack + +Docker Compose setup for local development and testing of MONAD services. + +## Services + +- **orchestrator-ren**: Robot Execution Orchestrator (port 8000) +- **actuator-bus**: Robot Actuator Command Interface (port 8010) + +## Quick Start + +### Start the Stack + +```bash +# From repository root +make up + +# Or from this directory +docker compose up -d --build +``` + +### Check Service Health + +```bash +# Orchestrator-REN +curl http://localhost:8000/ + +# Actuator-Bus +curl http://localhost:8010/ +``` + +### View Logs + +```bash +# From repository root +make logs + +# Or from this directory +docker compose logs -f + +# View specific service +docker compose logs -f orchestrator-ren +docker compose logs -f actuator-bus +``` + +### Stop the Stack + +```bash +# From repository root +make down + +# Or from this directory +docker compose down +``` + +## Makefile Targets + +From the repository root: + +- `make up` - Start all services (builds images if needed) +- `make down` - Stop and remove all containers +- `make logs` - Follow logs from all services +- `make compose-test` - Run smoke tests against running services +- `make compose-validate` - Validate docker-compose configuration + +## Shared Resources + +### Logs Volume + +Both services mount `./logs:/app/logs` for shared logging output. + +### Network + +Services communicate via the `monad-network` bridge network. + +## Health Checks + +Both services include health checks via their root endpoints (`/`): + +- **Interval**: 30 seconds +- **Timeout**: 3 seconds +- **Retries**: 3 +- **Start Period**: 5 seconds + +Check container health: +```bash +docker compose ps +``` + +## Ports + +- **8000**: orchestrator-ren (internal and external) +- **8010**: actuator-bus (maps to internal 8001) + +## Testing Workflow + +1. Start the stack: + ```bash + make up + ``` + +2. Wait for services to be healthy (check with `docker compose ps`) + +3. Test orchestrator-ren: + ```bash + # Create a ticket + curl -X POST http://localhost:8000/ticket \ + -H "Content-Type: application/json" \ + -d '{ + "command": "drive", + "params": {"speed": 1.5, "direction": 90, "duration_seconds": 5}, + "priority": "normal" + }' + + # Execute the ticket (use the returned ticket_id) + curl -X POST http://localhost:8000/execute \ + -H "Content-Type: application/json" \ + -d '{"ticket_id": "tick-20251111-abcd1234"}' + ``` + +4. Test actuator-bus: + ```bash + curl -X POST http://localhost:8010/actuate \ + -H "Content-Type: application/json" \ + -d '{ + "timestamp": "2025-11-11T10:30:00Z", + "command": "drive", + "params": {"speed": 1.5, "direction": 90} + }' + ``` + +5. View interactive API documentation: + - Orchestrator-REN: http://localhost:8000/docs + - Actuator-Bus: http://localhost:8010/docs + +## Troubleshooting + +### Container won't start + +Check logs: +```bash +docker compose logs +``` + +### Port already in use + +Stop conflicting services or change ports in `docker-compose.yml`. + +### Build issues + +Clean and rebuild: +```bash +docker compose down +docker compose build --no-cache +docker compose up -d +``` + +### Health check failing + +Check service is responding: +```bash +docker compose exec orchestrator-ren curl http://localhost:8000/ +docker compose exec actuator-bus curl http://localhost:8001/ +``` + +## Development Tips + +- Use `docker compose up` (without `-d`) to see real-time logs +- Edit code in `services/` directories - rebuild required after changes +- Use `docker compose restart ` to restart a specific service +- Check container resource usage: `docker stats` + +## CI/CD Integration + +The stack can be used in CI pipelines: + +```bash +# Start services +docker compose up -d + +# Wait for health +docker compose ps + +# Run tests +make compose-test + +# Cleanup +docker compose down +``` diff --git a/dev/compose/docker-compose.yml b/dev/compose/docker-compose.yml new file mode 100644 index 0000000..3a7ef27 --- /dev/null +++ b/dev/compose/docker-compose.yml @@ -0,0 +1,42 @@ +services: + orchestrator-ren: + build: + context: ../../services/orchestrator_ren + dockerfile: Dockerfile + container_name: monad-orchestrator-ren + ports: + - "8000:8000" + volumes: + - ../../logs:/app/logs + healthcheck: + test: ["CMD", "python", "-c", "from urllib.request import urlopen; urlopen('http://localhost:8000/', timeout=2).read()"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 5s + networks: + - monad-network + restart: unless-stopped + + actuator-bus: + build: + context: ../../services/actuator_bus + dockerfile: Dockerfile + container_name: monad-actuator-bus + ports: + - "8010:8001" + volumes: + - ../../logs:/app/logs + healthcheck: + test: ["CMD", "python", "-c", "from urllib.request import urlopen; urlopen('http://localhost:8001/', timeout=2).read()"] + interval: 30s + timeout: 3s + retries: 3 + start_period: 5s + networks: + - monad-network + restart: unless-stopped + +networks: + monad-network: + driver: bridge diff --git a/services/actuator_bus/Dockerfile b/services/actuator_bus/Dockerfile new file mode 100644 index 0000000..f39d73c --- /dev/null +++ b/services/actuator_bus/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.11-slim + +WORKDIR /app + +# Copy requirements and install dependencies +COPY requirements.txt . +RUN pip install --no-cache-dir --trusted-host pypi.org --trusted-host files.pythonhosted.org -r requirements.txt + +# Copy application code +COPY . . + +# Expose port +EXPOSE 8001 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD python -c "from urllib.request import urlopen; urlopen('http://localhost:8001/', timeout=2).read()" || exit 1 + +# Run the application +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8001"] diff --git a/services/orchestrator_ren/Dockerfile b/services/orchestrator_ren/Dockerfile new file mode 100644 index 0000000..40cef9b --- /dev/null +++ b/services/orchestrator_ren/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.11-slim + +WORKDIR /app + +# Copy requirements and install dependencies +COPY requirements.txt . +RUN pip install --no-cache-dir --trusted-host pypi.org --trusted-host files.pythonhosted.org -r requirements.txt + +# Copy application code +COPY . . + +# Expose port +EXPOSE 8000 + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD python -c "from urllib.request import urlopen; urlopen('http://localhost:8000/', timeout=2).read()" || exit 1 + +# Run the application +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] From 46c75d6ad55df135736e09948b62ab6bd79b160b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 11 Nov 2025 16:29:57 +0000 Subject: [PATCH 3/6] fix(compose): address PR feedback - /healthz, .dockerignore, POSIX paths, CI Co-authored-by: macroflux <8061740+macroflux@users.noreply.github.com> --- .dockerignore | 42 +++++++++++++++++++++++++ .github/workflows/compose-smoke.yml | 47 ++++++++++++++++++++++++++++ Makefile | 12 +++---- compose.yaml | 14 +++++++-- dev/compose/README.md | 15 ++++++--- dev/compose/docker-compose.yml | 7 +++-- services/actuator_bus/Dockerfile | 6 +++- services/actuator_bus/main.py | 6 ++++ services/orchestrator_ren/Dockerfile | 6 +++- services/orchestrator_ren/main.py | 6 ++++ 10 files changed, 144 insertions(+), 17 deletions(-) create mode 100644 .dockerignore create mode 100644 .github/workflows/compose-smoke.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..9f533bb --- /dev/null +++ b/.dockerignore @@ -0,0 +1,42 @@ +# Python +.venv +__pycache__/ +*.pyc +*.pyo +*.pyd +.pytest_cache/ +.coverage +*.egg-info/ + +# Logs +logs/ +*.log + +# Git +.git +.gitignore +.gitattributes + +# IDE +.vscode/ +.idea/ +*.swp +*.swo + +# Documentation +*.md +!README.md + +# CI/CD +.github/ + +# Docker +Dockerfile +.dockerignore +docker-compose*.yml +compose.yaml + +# Misc +.env +.env.* +.DS_Store diff --git a/.github/workflows/compose-smoke.yml b/.github/workflows/compose-smoke.yml new file mode 100644 index 0000000..33d1dcf --- /dev/null +++ b/.github/workflows/compose-smoke.yml @@ -0,0 +1,47 @@ +name: Compose Smoke + +on: + pull_request: + paths: + - 'services/**' + - 'dev/compose/**' + - 'compose.yaml' + - '.github/workflows/compose-smoke.yml' + +jobs: + compose: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Validate compose configuration + run: docker compose -f dev/compose/docker-compose.yml config + + - name: Build services + run: docker compose -f dev/compose/docker-compose.yml build + + - name: Start services + run: docker compose -f dev/compose/docker-compose.yml up -d + + - name: Wait for services to be healthy + run: | + echo "Waiting for services to be healthy..." + timeout 60 bash -c 'until docker compose -f dev/compose/docker-compose.yml ps | grep -q "healthy"; do sleep 2; done' + + - name: Check orchestrator-ren health + run: curl -f http://localhost:8000/healthz + + - name: Check actuator-bus health + run: curl -f http://localhost:8010/healthz + + - name: Show logs on failure + if: failure() + run: docker compose -f dev/compose/docker-compose.yml logs + + - name: Cleanup + if: always() + run: docker compose -f dev/compose/docker-compose.yml down diff --git a/Makefile b/Makefile index 7348675..2da0719 100644 --- a/Makefile +++ b/Makefile @@ -35,20 +35,20 @@ clean: # ============================================================================ up: - cd dev\compose && docker compose up -d --build + cd dev/compose && docker compose up -d --build down: - cd dev\compose && docker compose down + cd dev/compose && docker compose down logs: - cd dev\compose && docker compose logs -f + cd dev/compose && docker compose logs -f compose-test: @echo "Testing orchestrator-ren on port 8000..." - @curl -s http://localhost:8000/ || echo "Failed to connect to orchestrator-ren" + @curl -s http://localhost:8000/healthz || echo "Failed to connect to orchestrator-ren" @echo "" @echo "Testing actuator-bus on port 8010..." - @curl -s http://localhost:8010/ || echo "Failed to connect to actuator-bus" + @curl -s http://localhost:8010/healthz || echo "Failed to connect to actuator-bus" compose-validate: - cd dev\compose && docker compose config + cd dev/compose && docker compose config diff --git a/compose.yaml b/compose.yaml index f68d423..4ae0947 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,3 +1,10 @@ +# This file provides a convenient entrypoint at the repo root. +# The source of truth is dev/compose/docker-compose.yml +# +# Usage: docker compose up +# +# See dev/compose/README.md for full documentation. + services: orchestrator-ren: build: @@ -9,7 +16,7 @@ services: volumes: - ./logs:/app/logs healthcheck: - test: ["CMD", "python", "-c", "from urllib.request import urlopen; urlopen('http://localhost:8000/', timeout=2).read()"] + test: ["CMD", "python", "-c", "from urllib.request import urlopen; urlopen('http://localhost:8000/healthz', timeout=2).read()"] interval: 30s timeout: 3s retries: 3 @@ -28,11 +35,14 @@ services: volumes: - ./logs:/app/logs healthcheck: - test: ["CMD", "python", "-c", "from urllib.request import urlopen; urlopen('http://localhost:8001/', timeout=2).read()"] + test: ["CMD", "python", "-c", "from urllib.request import urlopen; urlopen('http://localhost:8001/healthz', timeout=2).read()"] interval: 30s timeout: 3s retries: 3 start_period: 5s + depends_on: + orchestrator-ren: + condition: service_healthy networks: - monad-network restart: unless-stopped diff --git a/dev/compose/README.md b/dev/compose/README.md index 1eff4f0..1fa5359 100644 --- a/dev/compose/README.md +++ b/dev/compose/README.md @@ -22,11 +22,13 @@ docker compose up -d --build ### Check Service Health ```bash -# Orchestrator-REN -curl http://localhost:8000/ +# Health check endpoints +curl http://localhost:8000/healthz # orchestrator-ren +curl http://localhost:8010/healthz # actuator-bus -# Actuator-Bus -curl http://localhost:8010/ +# Full service info +curl http://localhost:8000/ # orchestrator-ren +curl http://localhost:8010/ # actuator-bus ``` ### View Logs @@ -75,8 +77,9 @@ Services communicate via the `monad-network` bridge network. ## Health Checks -Both services include health checks via their root endpoints (`/`): +Both services include health checks via the `/healthz` endpoint: +- **Endpoint**: `/healthz` (returns `{"status": "healthy"}`) - **Interval**: 30 seconds - **Timeout**: 3 seconds - **Retries**: 3 @@ -87,6 +90,8 @@ Check container health: docker compose ps ``` +The actuator-bus service depends on orchestrator-ren being healthy before starting. + ## Ports - **8000**: orchestrator-ren (internal and external) diff --git a/dev/compose/docker-compose.yml b/dev/compose/docker-compose.yml index 3a7ef27..99c7f4a 100644 --- a/dev/compose/docker-compose.yml +++ b/dev/compose/docker-compose.yml @@ -9,7 +9,7 @@ services: volumes: - ../../logs:/app/logs healthcheck: - test: ["CMD", "python", "-c", "from urllib.request import urlopen; urlopen('http://localhost:8000/', timeout=2).read()"] + test: ["CMD", "python", "-c", "from urllib.request import urlopen; urlopen('http://localhost:8000/healthz', timeout=2).read()"] interval: 30s timeout: 3s retries: 3 @@ -28,11 +28,14 @@ services: volumes: - ../../logs:/app/logs healthcheck: - test: ["CMD", "python", "-c", "from urllib.request import urlopen; urlopen('http://localhost:8001/', timeout=2).read()"] + test: ["CMD", "python", "-c", "from urllib.request import urlopen; urlopen('http://localhost:8001/healthz', timeout=2).read()"] interval: 30s timeout: 3s retries: 3 start_period: 5s + depends_on: + orchestrator-ren: + condition: service_healthy networks: - monad-network restart: unless-stopped diff --git a/services/actuator_bus/Dockerfile b/services/actuator_bus/Dockerfile index f39d73c..d533adc 100644 --- a/services/actuator_bus/Dockerfile +++ b/services/actuator_bus/Dockerfile @@ -1,5 +1,9 @@ FROM python:3.11-slim +# Prevent Python from writing .pyc files and buffer stdout/stderr +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 + WORKDIR /app # Copy requirements and install dependencies @@ -14,7 +18,7 @@ EXPOSE 8001 # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD python -c "from urllib.request import urlopen; urlopen('http://localhost:8001/', timeout=2).read()" || exit 1 + CMD python -c "from urllib.request import urlopen; urlopen('http://localhost:8001/healthz', timeout=2).read()" || exit 1 # Run the application CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8001"] diff --git a/services/actuator_bus/main.py b/services/actuator_bus/main.py index bb4fcfd..da977b6 100644 --- a/services/actuator_bus/main.py +++ b/services/actuator_bus/main.py @@ -95,6 +95,12 @@ async def root(): return {"service": "actuator-bus", "version": "0.1.0", "status": "operational"} +@app.get("/healthz") +async def healthz(): + """Health check endpoint for container orchestration.""" + return {"status": "healthy"} + + @app.post("/actuate", response_model=ActuateResponse, status_code=status.HTTP_200_OK) async def actuate(request: ActuateRequest): """ diff --git a/services/orchestrator_ren/Dockerfile b/services/orchestrator_ren/Dockerfile index 40cef9b..14ecfa2 100644 --- a/services/orchestrator_ren/Dockerfile +++ b/services/orchestrator_ren/Dockerfile @@ -1,5 +1,9 @@ FROM python:3.11-slim +# Prevent Python from writing .pyc files and buffer stdout/stderr +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 + WORKDIR /app # Copy requirements and install dependencies @@ -14,7 +18,7 @@ EXPOSE 8000 # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD python -c "from urllib.request import urlopen; urlopen('http://localhost:8000/', timeout=2).read()" || exit 1 + CMD python -c "from urllib.request import urlopen; urlopen('http://localhost:8000/healthz', timeout=2).read()" || exit 1 # Run the application CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/services/orchestrator_ren/main.py b/services/orchestrator_ren/main.py index f26fb76..4e2587d 100644 --- a/services/orchestrator_ren/main.py +++ b/services/orchestrator_ren/main.py @@ -244,6 +244,12 @@ async def root(): } +@app.get("/healthz") +async def healthz(): + """Health check endpoint for container orchestration.""" + return {"status": "healthy"} + + @app.post("/ticket", response_model=Ticket, status_code=status.HTTP_201_CREATED) async def create_ticket(request: TicketCreateRequest): """ From c14aef6d7353f819f78f7bfe091b6429c8f24209 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 11 Nov 2025 16:32:53 +0000 Subject: [PATCH 4/6] security(ci): add permissions block to compose-smoke workflow Co-authored-by: macroflux <8061740+macroflux@users.noreply.github.com> --- .github/workflows/compose-smoke.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/compose-smoke.yml b/.github/workflows/compose-smoke.yml index 33d1dcf..99acc6e 100644 --- a/.github/workflows/compose-smoke.yml +++ b/.github/workflows/compose-smoke.yml @@ -11,6 +11,8 @@ on: jobs: compose: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Checkout code uses: actions/checkout@v4 From 86dba4b072d0763df4a8ba98ce1be3195fb4d3ce Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 11 Nov 2025 18:44:22 +0000 Subject: [PATCH 5/6] fix(ci): improve compose smoke workflow reliability Co-authored-by: macroflux <8061740+macroflux@users.noreply.github.com> --- .github/workflows/compose-smoke.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/compose-smoke.yml b/.github/workflows/compose-smoke.yml index 99acc6e..a3ee9f2 100644 --- a/.github/workflows/compose-smoke.yml +++ b/.github/workflows/compose-smoke.yml @@ -32,13 +32,19 @@ jobs: - name: Wait for services to be healthy run: | echo "Waiting for services to be healthy..." - timeout 60 bash -c 'until docker compose -f dev/compose/docker-compose.yml ps | grep -q "healthy"; do sleep 2; done' + timeout 120 bash -c 'until [ $(docker compose -f dev/compose/docker-compose.yml ps | grep -c "healthy") -eq 2 ]; do echo "Waiting..."; sleep 3; done' + echo "Both services are healthy" + docker compose -f dev/compose/docker-compose.yml ps - name: Check orchestrator-ren health - run: curl -f http://localhost:8000/healthz + run: | + echo "Testing orchestrator-ren /healthz endpoint..." + curl -f http://localhost:8000/healthz - name: Check actuator-bus health - run: curl -f http://localhost:8010/healthz + run: | + echo "Testing actuator-bus /healthz endpoint..." + curl -f http://localhost:8010/healthz - name: Show logs on failure if: failure() From 7cbbf41f0729e36da30741166aee7114392d4287 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 14:28:54 +0000 Subject: [PATCH 6/6] chore(deps): pin runtime dependencies for stability Co-authored-by: macroflux <8061740+macroflux@users.noreply.github.com> --- services/actuator_bus/requirements.txt | 10 +++++----- services/orchestrator_ren/requirements.txt | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/services/actuator_bus/requirements.txt b/services/actuator_bus/requirements.txt index 0c158e1..c08d873 100644 --- a/services/actuator_bus/requirements.txt +++ b/services/actuator_bus/requirements.txt @@ -1,5 +1,5 @@ -fastapi>=0.104.0 -uvicorn[standard]>=0.24.0 -pydantic>=2.0.0 -pytest>=7.4.0 -httpx>=0.25.0 +fastapi~=0.121.0 +uvicorn[standard]~=0.38.0 +pydantic~=2.12.0 +pytest~=9.0.0 +httpx~=0.28.0 diff --git a/services/orchestrator_ren/requirements.txt b/services/orchestrator_ren/requirements.txt index 2d70152..5f7c9ba 100644 --- a/services/orchestrator_ren/requirements.txt +++ b/services/orchestrator_ren/requirements.txt @@ -1,4 +1,4 @@ -fastapi>=0.104.0 -uvicorn[standard]>=0.24.0 -pydantic>=2.0.0 -requests>=2.0.0 +fastapi~=0.121.0 +uvicorn[standard]~=0.38.0 +pydantic~=2.12.0 +requests~=2.32.0