Making it more resiliant to network problems, fixing playright
Some checks failed
Tests / Build and Push CICD Complete Image (push) Failing after 4m6s
Tests / TSDoc Lint Check (push) Has been skipped
Tests / Backend Tests (push) Has been skipped
Tests / Frontend Tests (push) Has been skipped
Tests / Integration Tests (push) Has been skipped
Tests / End-to-End Tests (push) Has been skipped
Tests / Trailing Whitespace Check (push) Has been skipped
Tests / End of File Check (push) Has been skipped
Tests / YAML Syntax Check (push) Has been skipped
Tests / Backend Doctests (push) Has been skipped
Tests / TOML Syntax Check (push) Has been skipped
Tests / Mixed Line Ending Check (push) Has been skipped
Tests / TOML Formatting Check (push) Has been skipped
Tests / Ruff Linting (push) Has been skipped
Tests / Pyright Type Check (push) Has been skipped
Tests / Darglint Docstring Check (push) Has been skipped
Tests / No Docstring Types Check (push) Has been skipped
Tests / ESLint Check (push) Has been skipped
Tests / Prettier Format Check (push) Has been skipped
Tests / Ruff Format Check (push) Has been skipped
Tests / TypeScript Type Check (push) Has been skipped
Tests / Build and Push CICD Base Image (push) Successful in 3m27s
Some checks failed
Tests / Build and Push CICD Complete Image (push) Failing after 4m6s
Tests / TSDoc Lint Check (push) Has been skipped
Tests / Backend Tests (push) Has been skipped
Tests / Frontend Tests (push) Has been skipped
Tests / Integration Tests (push) Has been skipped
Tests / End-to-End Tests (push) Has been skipped
Tests / Trailing Whitespace Check (push) Has been skipped
Tests / End of File Check (push) Has been skipped
Tests / YAML Syntax Check (push) Has been skipped
Tests / Backend Doctests (push) Has been skipped
Tests / TOML Syntax Check (push) Has been skipped
Tests / Mixed Line Ending Check (push) Has been skipped
Tests / TOML Formatting Check (push) Has been skipped
Tests / Ruff Linting (push) Has been skipped
Tests / Pyright Type Check (push) Has been skipped
Tests / Darglint Docstring Check (push) Has been skipped
Tests / No Docstring Types Check (push) Has been skipped
Tests / ESLint Check (push) Has been skipped
Tests / Prettier Format Check (push) Has been skipped
Tests / Ruff Format Check (push) Has been skipped
Tests / TypeScript Type Check (push) Has been skipped
Tests / Build and Push CICD Base Image (push) Successful in 3m27s
Signed-off-by: Cliff Hill <xlorep@darkhelm.org>
This commit is contained in:
171
Dockerfile.cicd
171
Dockerfile.cicd
@@ -1,4 +1,11 @@
|
||||
# CICD Complete Setup - Inherits base and adds project dependencies
|
||||
# CICD Complete Setup - Optimized Build Order for Maximum Caching
|
||||
# OPTIMIZATION STRATEGY:
|
||||
# Phase 1: Extract dependency files (package.json, pyproject.toml)
|
||||
# Phase 2: Install dependencies (cached layer, only invalidates when deps change)
|
||||
# Phase 3: Clone full source code (doesn't bust dependency cache)
|
||||
# Phase 4-6: Install packages and verify (requires full source)
|
||||
#
|
||||
# BENEFITS: Dependency installation ~20-30 minutes is cached across source code changes
|
||||
ARG CICD_BASE_IMAGE=dogar.darkhelm.org/darkhelm.org/plex-playlist/cicd-base:latest
|
||||
FROM ${CICD_BASE_IMAGE}
|
||||
|
||||
@@ -12,7 +19,8 @@ ARG GITHUB_SHA
|
||||
# Set working directory
|
||||
WORKDIR /workspace
|
||||
|
||||
# Set up SSH and clone repository using BuildKit secrets
|
||||
# OPTIMIZATION: Extract dependency files first for better layer caching
|
||||
# Step 1: Clone repository minimally to get dependency files only
|
||||
RUN --mount=type=secret,id=ssh_private_key \
|
||||
mkdir -p ~/.ssh && \
|
||||
cp /run/secrets/ssh_private_key ~/.ssh/id_rsa && \
|
||||
@@ -23,20 +31,28 @@ RUN --mount=type=secret,id=ssh_private_key \
|
||||
echo " UserKnownHostsFile /dev/null" >> ~/.ssh/config && \
|
||||
chmod 600 ~/.ssh/config && \
|
||||
ssh-keyscan -p 2222 dogar.darkhelm.org >> ~/.ssh/known_hosts 2>/dev/null && \
|
||||
echo "=== Extracting dependency files for optimized caching ===" && \
|
||||
GIT_SSH_COMMAND="ssh -F ~/.ssh/config" \
|
||||
git clone --depth 1 --branch main \
|
||||
ssh://git@dogar.darkhelm.org:2222/DarkHelm.org/plex-playlist.git . && \
|
||||
ssh://git@dogar.darkhelm.org:2222/DarkHelm.org/plex-playlist.git /tmp/repo && \
|
||||
if [ -n "$GITHUB_SHA" ]; then \
|
||||
git checkout "$GITHUB_SHA" 2>/dev/null || echo "Using main branch HEAD"; \
|
||||
cd /tmp/repo && git checkout "$GITHUB_SHA" 2>/dev/null || echo "Using main branch HEAD"; \
|
||||
fi && \
|
||||
rm -rf ~/.ssh
|
||||
# Extract only dependency files for caching optimization
|
||||
mkdir -p /workspace/backend /workspace/frontend && \
|
||||
cp /tmp/repo/backend/pyproject.toml /workspace/backend/ 2>/dev/null || echo "No backend pyproject.toml" && \
|
||||
cp /tmp/repo/frontend/package.json /workspace/frontend/ 2>/dev/null || echo "No frontend package.json" && \
|
||||
cp /tmp/repo/frontend/yarn.lock /workspace/frontend/ 2>/dev/null || echo "No frontend yarn.lock" && \
|
||||
cp /tmp/repo/.pre-commit-config.yaml /workspace/ 2>/dev/null || echo "No pre-commit config" && \
|
||||
echo "✓ Dependency files extracted for optimized layer caching" && \
|
||||
rm -rf /tmp/repo ~/.ssh
|
||||
|
||||
# Set up Python environment for backend with optimized dependency installation
|
||||
# OPTIMIZATION PHASE 1: Install backend dependencies from extracted pyproject.toml
|
||||
WORKDIR /workspace/backend
|
||||
ENV VIRTUAL_ENV=/workspace/backend/.venv
|
||||
|
||||
# Create venv and leverage pre-installed common tools
|
||||
RUN echo "=== Setting up optimized Python environment ===" && \
|
||||
# Install backend dependencies first (before source code) for better caching
|
||||
RUN echo "=== Installing Backend Dependencies (Phase 1: Optimized Caching) ===" && \
|
||||
# Create project virtual environment
|
||||
uv venv $VIRTUAL_ENV && \
|
||||
# Check if base image optimization is available
|
||||
@@ -50,75 +66,110 @@ RUN echo "=== Setting up optimized Python environment ===" && \
|
||||
echo "⚠ Pre-installed Python dev tools not found - fresh installation" && \
|
||||
echo "Base image may need rebuild for optimal caching"; \
|
||||
fi && \
|
||||
# Install project dependencies (uv will handle tool requirements automatically)
|
||||
echo "Installing project-specific dependencies..." && \
|
||||
uv sync --dev && \
|
||||
echo "✓ Backend environment ready with dependencies"
|
||||
# Install dependencies from extracted pyproject.toml (this layer will cache!)
|
||||
if [ -f "pyproject.toml" ]; then \
|
||||
echo "Installing project dependencies from pyproject.toml..." && \
|
||||
uv sync --dev && \
|
||||
echo "✓ Backend dependencies installed and cached"; \
|
||||
else \
|
||||
echo "No pyproject.toml found, skipping dependency installation"; \
|
||||
fi
|
||||
|
||||
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||
|
||||
# Install backend package in development mode
|
||||
RUN uv pip install -e .
|
||||
|
||||
# Install pre-commit environments for CI validation using optimized approach
|
||||
WORKDIR /workspace
|
||||
RUN cd /workspace && \
|
||||
echo "=== Installing Pre-commit Hook Environments (Optimized) ===" && \
|
||||
# Use the pre-installed pre-commit from global tools when possible
|
||||
if [ -f ".pre-commit-config.yaml" ]; then \
|
||||
# Use project's Python environment but leverage global pre-commit tools
|
||||
uv run pre-commit install-hooks && \
|
||||
echo "✓ Pre-commit hook environments installed successfully"; \
|
||||
else \
|
||||
echo "No .pre-commit-config.yaml found, skipping hook installation"; \
|
||||
fi
|
||||
|
||||
# Set up frontend dependencies
|
||||
# OPTIMIZATION PHASE 2: Install frontend dependencies from extracted package.json
|
||||
WORKDIR /workspace/frontend
|
||||
|
||||
# Install frontend dependencies with optimized approach
|
||||
# Many development tools are already installed globally in base image via npm
|
||||
RUN echo "=== Setting up optimized frontend environment ===" && \
|
||||
# Setup frontend environment and install dependencies (before source code) for better caching
|
||||
RUN echo "=== Installing Frontend Dependencies (Phase 2: Optimized Caching) ===" && \
|
||||
echo "Available global tools (installed via npm):" && \
|
||||
npm list -g --depth=0 2>/dev/null | head -10 || echo "Global npm tools available" && \
|
||||
which tsc && which eslint && which prettier && which playwright || echo "Global tools verified" && \
|
||||
which tsc && which eslint && which prettier || echo "Global tools verified" && \
|
||||
# Create temporary swap file for memory-intensive yarn install
|
||||
dd if=/dev/zero of=/tmp/swapfile bs=1M count=1024 2>/dev/null && \
|
||||
mkswap /tmp/swapfile && \
|
||||
swapon /tmp/swapfile || echo "Swap setup failed, continuing without swap"
|
||||
|
||||
# Install project-specific frontend dependencies (many tools already global)
|
||||
# Cache bust: ${GITHUB_SHA}
|
||||
RUN export NODE_OPTIONS="--max-old-space-size=1024 --max-semi-space-size=64" && \
|
||||
export UV_WORKERS=1 && \
|
||||
echo "Memory info before install:" && \
|
||||
free -h || true && \
|
||||
INSTALL_SUCCESS=false && \
|
||||
for i in 1 2 3; do \
|
||||
echo "Attempt $i: Installing project-specific frontend dependencies..." && \
|
||||
echo "(Common dev tools pre-installed globally for performance)" && \
|
||||
timeout 2400 yarn install --immutable --mode=skip-build \
|
||||
&& { INSTALL_SUCCESS=true; break; } || \
|
||||
(echo "Attempt $i failed, cleaning up and retrying..." && \
|
||||
rm -rf node_modules .yarn/cache .yarn/install-state.gz && \
|
||||
yarn cache clean --all 2>/dev/null || true && \
|
||||
sleep 60); \
|
||||
done && \
|
||||
rm -rf .yarn/cache && \
|
||||
swapoff /tmp/swapfile 2>/dev/null || true && \
|
||||
rm -f /tmp/swapfile && \
|
||||
if [ "$INSTALL_SUCCESS" = "false" ]; then \
|
||||
echo "WARNING: Frontend dependencies installation failed after 3 attempts"; \
|
||||
echo "Continuing without frontend dependencies for CI/CD environment"; \
|
||||
touch .frontend-deps-failed; \
|
||||
# Install frontend dependencies from extracted package.json (this layer will cache!)
|
||||
RUN if [ -f "package.json" ]; then \
|
||||
echo "Installing frontend dependencies from extracted package.json..." && \
|
||||
export NODE_OPTIONS="--max-old-space-size=1024 --max-semi-space-size=64" && \
|
||||
export UV_WORKERS=1 && \
|
||||
echo "Memory info before install:" && \
|
||||
free -h || true && \
|
||||
INSTALL_SUCCESS=false && \
|
||||
for i in 1 2 3; do \
|
||||
echo "Attempt $i: Installing project-specific frontend dependencies..." && \
|
||||
echo "(Common dev tools pre-installed globally for performance)" && \
|
||||
timeout 2400 yarn install --immutable --mode=skip-build \
|
||||
&& { INSTALL_SUCCESS=true; break; } || \
|
||||
(echo "Attempt $i failed, cleaning up and retrying..." && \
|
||||
rm -rf node_modules .yarn/cache .yarn/install-state.gz && \
|
||||
yarn cache clean --all 2>/dev/null || true && \
|
||||
sleep 60); \
|
||||
done && \
|
||||
rm -rf .yarn/cache && \
|
||||
swapoff /tmp/swapfile 2>/dev/null || true && \
|
||||
rm -f /tmp/swapfile && \
|
||||
if [ "$INSTALL_SUCCESS" = "false" ]; then \
|
||||
echo "WARNING: Frontend dependencies installation failed after 3 attempts"; \
|
||||
echo "Continuing without frontend dependencies for CI/CD environment"; \
|
||||
touch .frontend-deps-failed; \
|
||||
else \
|
||||
echo "✓ Frontend dependencies installed and cached"; \
|
||||
fi; \
|
||||
else \
|
||||
echo "✓ Frontend dependencies installed (leveraging global tools)"; \
|
||||
echo "No package.json found, skipping frontend dependencies"; \
|
||||
fi
|
||||
|
||||
# Playwright browsers optimization check (may be pre-installed in base image)
|
||||
# OPTIMIZATION PHASE 3: Now clone full source code (dependencies already cached above)
|
||||
WORKDIR /workspace
|
||||
RUN --mount=type=secret,id=ssh_private_key \
|
||||
echo "=== Cloning Full Source Code (Phase 3: After Dependencies) ===" && \
|
||||
mkdir -p ~/.ssh && \
|
||||
cp /run/secrets/ssh_private_key ~/.ssh/id_rsa && \
|
||||
chmod 600 ~/.ssh/id_rsa && \
|
||||
echo "Host dogar.darkhelm.org" > ~/.ssh/config && \
|
||||
echo " Port 2222" >> ~/.ssh/config && \
|
||||
echo " StrictHostKeyChecking no" >> ~/.ssh/config && \
|
||||
echo " UserKnownHostsFile /dev/null" >> ~/.ssh/config && \
|
||||
chmod 600 ~/.ssh/config && \
|
||||
ssh-keyscan -p 2222 dogar.darkhelm.org >> ~/.ssh/known_hosts 2>/dev/null && \
|
||||
# Clone full repository (dependencies already installed, this won't bust cache layers)
|
||||
GIT_SSH_COMMAND="ssh -F ~/.ssh/config" \
|
||||
git clone --depth 1 --branch main \
|
||||
ssh://git@dogar.darkhelm.org:2222/DarkHelm.org/plex-playlist.git /tmp/fullrepo && \
|
||||
if [ -n "$GITHUB_SHA" ]; then \
|
||||
cd /tmp/fullrepo && git checkout "$GITHUB_SHA" 2>/dev/null || echo "Using main branch HEAD"; \
|
||||
fi && \
|
||||
# Copy source code over existing dependency files (preserving node_modules, .venv)
|
||||
echo "Copying source code while preserving installed dependencies..." && \
|
||||
rsync -av --exclude='node_modules' --exclude='.venv' --exclude='.yarn/cache' /tmp/fullrepo/ /workspace/ && \
|
||||
echo "✓ Full source code copied, dependencies preserved" && \
|
||||
rm -rf /tmp/fullrepo ~/.ssh
|
||||
|
||||
# PHASE 4: Install backend package in development mode (requires full source)
|
||||
WORKDIR /workspace/backend
|
||||
RUN echo "=== Installing Backend Package in Development Mode ===" && \
|
||||
uv pip install -e . && \
|
||||
echo "✓ Backend package installed in development mode"
|
||||
|
||||
# PHASE 5: Install pre-commit environments (requires full source with .pre-commit-config.yaml)
|
||||
WORKDIR /workspace
|
||||
RUN echo "=== Installing Pre-commit Hook Environments ===" && \
|
||||
if [ -f ".pre-commit-config.yaml" ]; then \
|
||||
# Use project's Python environment for pre-commit
|
||||
cd backend && uv run pre-commit install-hooks && \
|
||||
echo "✓ Pre-commit hook environments installed successfully"; \
|
||||
else \
|
||||
echo "No .pre-commit-config.yaml found, skipping hook installation"; \
|
||||
fi
|
||||
|
||||
# PHASE 6: Playwright browsers optimization check (may be pre-installed in base image)
|
||||
WORKDIR /workspace/frontend
|
||||
RUN if [ -f ".frontend-deps-failed" ]; then \
|
||||
echo "Frontend dependencies failed - Playwright E2E tests will be skipped"; \
|
||||
elif grep -q '@playwright/test' package.json && [ -d "node_modules" ]; then \
|
||||
elif [ -f "package.json" ] && grep -q '@playwright/test' package.json && [ -d "node_modules" ]; then \
|
||||
echo "Checking Playwright browser optimization status..." && \
|
||||
# Check if Playwright CLI is available via yarn (from project dependencies)
|
||||
if yarn playwright --version >/dev/null 2>&1; then \
|
||||
|
||||
Reference in New Issue
Block a user