Backend runtime upgraded to Python 3.14 with exact dependency pinning (#57)
Some checks failed
CICD Start / Sanity and Base Decision (push) Successful in 18s
Runner Canary / Canary Heavy (ubuntu-act-8gb) (push) Has been skipped
Runner Canary / Canary Heavy (ubuntu-act-4gb) (push) Has been skipped
Runner Canary / Canary Burst (ubuntu-act (push) Failing after 11m10s
Runner Canary / Canary (ubuntu-latest) (push) Failing after 12m39s
Runner Canary / Canary (ubuntu-act) (push) Failing after 12m42s
Some checks failed
CICD Start / Sanity and Base Decision (push) Successful in 18s
Runner Canary / Canary Heavy (ubuntu-act-8gb) (push) Has been skipped
Runner Canary / Canary Heavy (ubuntu-act-4gb) (push) Has been skipped
Runner Canary / Canary Burst (ubuntu-act (push) Failing after 11m10s
Runner Canary / Canary (ubuntu-latest) (push) Failing after 12m39s
Runner Canary / Canary (ubuntu-act) (push) Failing after 12m42s
Signed-off-by: Cliff Hill <xlorep@darkhelm.org> ## Summary Upgrades backend runtime baseline and dependency management for issue #10. ### Changes 1. **Python Baseline**: Updated from 3.13 to 3.14 - Updated `backend/pyproject.toml` requires-python constraint - Updated `backend/pyrightconfig.json` pythonVersion - Updated all Dockerfile and CI references 2. **Dependency Pinning**: Switched to exact version pins in `backend/pyproject.toml` - All dev and runtime dependencies now use `==` instead of `>=` - `fastapi==0.120.2`, `uvicorn==0.38.0` - ruff, pyright, pytest suite pinned to current resolved versions - Regenerated `backend/uv.lock` under Python 3.14 3. **Startup Compatibility Guard** (TDD via RED→GREEN) - New `compatibility_status()` function evaluates runtime and pinned deps - Startup raises `RuntimeError` if policy fails - Implemented via FastAPI lifespan (non-deprecated) handler 4. **Compatibility Status Endpoint** - New `GET /compatibility` returns policy status, runtime version, and package checks - Shares single source of truth with startup validation 5. **Integration Tests** - Added failing-then-passing tests for startup guard and endpoint behavior - 100% coverage maintained 6. **Direnv Configuration** - Added `UV_PYTHON="3.14"` pin to repo `.envrc` - Ensures direnv creates/recreates venv with correct Python version ### Validation - ✅ ruff format/check - ✅ pyright strict (0 errors) - ✅ pytest: 8 passed, 100% coverage (>=95 gate) - ✅ pydoclint: pass - ✅ xdoctest: pass ### Notes - SQLAlchemy/SQLModel introduction deferred to next pass per scope - Compatibility logic currently validates fastapi/uvicorn pins (runtime deps) - Ready for container build validation and Renovate bot testing Co-authored-by: copilotcoder <copilotcoder@darkhelm.org> Reviewed-on: #57 Co-authored-by: Cliff Hill <xlorep@darkhelm.org> Co-committed-by: Cliff Hill <xlorep@darkhelm.org>
This commit was merged in pull request #57.
This commit is contained in:
@@ -1,10 +1,17 @@
|
||||
# CICD Base Setup - System dependencies and language runtimes only
|
||||
ARG PLAYWRIGHT_BROWSERS_IMAGE=mcr.microsoft.com/playwright:v1.56.1-jammy
|
||||
FROM ${PLAYWRIGHT_BROWSERS_IMAGE} AS playwright-browsers
|
||||
|
||||
FROM ubuntu:22.04
|
||||
|
||||
# Build args for cache busting (base dependencies change rarely)
|
||||
ARG BASE_IMAGE_VERSION=v1.0.0
|
||||
ARG BASE_IMAGE_HASH=unknown
|
||||
ENV BASE_IMAGE_VERSION=${BASE_IMAGE_VERSION}
|
||||
|
||||
LABEL darkhelm.cicd-base.hash=${BASE_IMAGE_HASH}
|
||||
LABEL org.opencontainers.image.version=${BASE_IMAGE_VERSION}
|
||||
|
||||
# Set timezone and make installs non-interactive
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=America/New_York
|
||||
@@ -55,10 +62,22 @@ RUN apt-fast update && apt-fast install -y \
|
||||
software-properties-common \
|
||||
build-essential \
|
||||
openssh-client \
|
||||
# Playwright Chromium runtime dependencies (Linux)
|
||||
libnspr4 \
|
||||
libnss3 \
|
||||
libatk1.0-0 \
|
||||
libatspi2.0-0 \
|
||||
libxcomposite1 \
|
||||
libxdamage1 \
|
||||
libxfixes3 \
|
||||
libxrandr2 \
|
||||
libgbm1 \
|
||||
libxkbcommon0 \
|
||||
libasound2 \
|
||||
tzdata \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Python 3.13 with retry and fallback mechanisms
|
||||
# Install Python 3.14 with retry and fallback mechanisms
|
||||
RUN for i in 1 2 3; do \
|
||||
echo "Attempt $i: Adding deadsnakes PPA..." && \
|
||||
add-apt-repository -y ppa:deadsnakes/ppa && \
|
||||
@@ -68,11 +87,11 @@ RUN for i in 1 2 3; do \
|
||||
done
|
||||
|
||||
RUN for i in 1 2 3; do \
|
||||
echo "Attempt $i: Installing Python 3.13..." && \
|
||||
echo "Attempt $i: Installing Python 3.14..." && \
|
||||
timeout 300 apt-fast install -y \
|
||||
python3.13 \
|
||||
python3.13-venv \
|
||||
python3.13-dev && \
|
||||
python3.14 \
|
||||
python3.14-venv \
|
||||
python3.14-dev && \
|
||||
break || \
|
||||
(echo "Attempt $i failed, retrying in 15s..." && sleep 15); \
|
||||
done && \
|
||||
@@ -101,17 +120,23 @@ RUN yarn config set httpTimeout 60000 && \
|
||||
yarn config set compressionLevel 0 && \
|
||||
yarn config set nmMode hardlinks-local
|
||||
|
||||
# Install uv package manager globally
|
||||
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
|
||||
# Install uv package manager globally without requiring GHCR pulls
|
||||
RUN set -eu && \
|
||||
curl -LsSf https://astral.sh/uv/install.sh -o /tmp/uv-install.sh && \
|
||||
sh /tmp/uv-install.sh && \
|
||||
rm -f /tmp/uv-install.sh && \
|
||||
cp /root/.local/bin/uv /usr/local/bin/uv && \
|
||||
chmod +x /usr/local/bin/uv && \
|
||||
uv --version
|
||||
|
||||
# Install common development tools globally using npm (more reliable for global installs)
|
||||
RUN echo "=== Installing Global Development Tools ===" && \
|
||||
# Use npm for global installations (works better than yarn global in Berry)
|
||||
npm install -g \
|
||||
@playwright/test@1.40.0 \
|
||||
@playwright/test@1.56.1 \
|
||||
typescript@5.3.3 \
|
||||
eslint@9.33.0 \
|
||||
prettier@3.3.3 \
|
||||
prettier@3.6.2 \
|
||||
vite@7.1.10 \
|
||||
@types/node@20.16.0 && \
|
||||
# Verify global tools are available
|
||||
@@ -121,17 +146,21 @@ RUN echo "=== Installing Global Development Tools ===" && \
|
||||
which prettier && \
|
||||
echo "✓ Global Node.js development tools installed via npm"
|
||||
|
||||
# Install Playwright browsers for E2E testing
|
||||
# This downloads ~400MB+ of browser binaries that will be cached
|
||||
RUN echo "=== Installing Playwright Browsers ===" && \
|
||||
# Verify Playwright CLI is available
|
||||
playwright --version && \
|
||||
# Install browsers with system dependencies (non-interactive)
|
||||
export PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=0 && \
|
||||
playwright install --with-deps chromium firefox webkit && \
|
||||
# Install system dependencies for browsers
|
||||
playwright install-deps && \
|
||||
echo "✓ Playwright browsers installed and cached in base image"
|
||||
# Keep browser binaries in a deterministic location so E2E runs do not re-download them.
|
||||
ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright
|
||||
|
||||
# Copy preinstalled browsers from the official Playwright image to avoid flaky CDN downloads.
|
||||
COPY --from=playwright-browsers /ms-playwright /ms-playwright
|
||||
|
||||
RUN echo "=== Verifying preinstalled Playwright Chromium Browser ===" && \
|
||||
chromium_count=$(find "${PLAYWRIGHT_BROWSERS_PATH}" -maxdepth 1 -type d -name 'chromium-*' | wc -l) && \
|
||||
echo "playwright_chromium_dir_count=${chromium_count} path=${PLAYWRIGHT_BROWSERS_PATH}" && \
|
||||
if [ "${chromium_count}" -eq 0 ]; then \
|
||||
echo "❌ No Chromium browser directories found in preinstalled Playwright cache"; \
|
||||
exit 1; \
|
||||
fi && \
|
||||
ls -la "${PLAYWRIGHT_BROWSERS_PATH}" && \
|
||||
echo "✓ Playwright Chromium preinstalled at ${PLAYWRIGHT_BROWSERS_PATH}"
|
||||
|
||||
# Pre-install common Python development dependencies globally
|
||||
# These are stable tools that rarely change and take time to compile
|
||||
@@ -162,7 +191,7 @@ RUN echo '#!/bin/bash' > /usr/local/bin/setup-ssh && \
|
||||
echo ' cp /run/secrets/ssh_private_key ~/.ssh/id_rsa' >> /usr/local/bin/setup-ssh && \
|
||||
echo ' chmod 600 ~/.ssh/id_rsa' >> /usr/local/bin/setup-ssh && \
|
||||
echo ' ssh-keyscan -H github.com >> ~/.ssh/known_hosts 2>/dev/null' >> /usr/local/bin/setup-ssh && \
|
||||
echo ' ssh-keyscan -p 2222 -H dogar.darkhelm.org >> ~/.ssh/known_hosts 2>/dev/null' >> /usr/local/bin/setup-ssh && \
|
||||
echo ' ssh-keyscan -p 2222 -H kankali.darkhelm.lan >> ~/.ssh/known_hosts 2>/dev/null' >> /usr/local/bin/setup-ssh && \
|
||||
echo 'else' >> /usr/local/bin/setup-ssh && \
|
||||
echo ' echo "No SSH key provided via secrets mount"' >> /usr/local/bin/setup-ssh && \
|
||||
echo 'fi' >> /usr/local/bin/setup-ssh && \
|
||||
@@ -170,7 +199,7 @@ RUN echo '#!/bin/bash' > /usr/local/bin/setup-ssh && \
|
||||
|
||||
# Verify that all base tools are working
|
||||
RUN echo "=== Base System Verification ===" && \
|
||||
python3.13 --version && \
|
||||
python3.14 --version && \
|
||||
node --version && \
|
||||
yarn --version && \
|
||||
uv --version && \
|
||||
|
||||
Reference in New Issue
Block a user