diff --git a/.gitea/workflows/ci-image-builder.yml b/.gitea/workflows/ci-image-builder.yml deleted file mode 100644 index 80f27c4..0000000 --- a/.gitea/workflows/ci-image-builder.yml +++ /dev/null @@ -1,80 +0,0 @@ -# CI Image Builder Workflow -# Automatically builds and pushes CI images when dependencies change -# Uses GitHub Container Registry (GHCR) or any container registry - -name: CI Image Builder - -on: - push: - branches: - - main - paths: - - 'package.json' - - 'package-lock.json' - - 'Dockerfile.ci' - - '.gitea/workflows/ci-image-builder.yml' - workflow_dispatch: - inputs: - force_rebuild: - description: 'Force rebuild even if no changes detected' - required: false - default: 'false' - type: boolean - -env: - # Use your existing Docker registry - REGISTRY: docker.notsosm.art - IMAGE_NAME: euchre-camp-ci-runner - -jobs: - build-ci-image: - runs-on: ubuntu-latest - # Skip if this is an auto-generated version bump commit - if: "!contains(github.event.head_commit.message, 'chore: bump version')" - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Build CI image - run: | - docker build \ - -f Dockerfile.ci \ - -t ${{ env.IMAGE_NAME }}:latest \ - -t ${{ env.IMAGE_NAME }}:$(git rev-parse --short HEAD) \ - . - - - name: Test CI image - run: | - docker run --rm \ - ${{ env.IMAGE_NAME }}:latest \ - sh -c "node --version && npm --version && npx prisma --version" - - - name: Push to registry - run: | - echo "Pushing to ${{ env.REGISTRY }}..." - # Check if we can authenticate to the registry using DOCKER_LOGIN and DOCKER_PASSWORD secrets - if [ -n "${{ secrets.DOCKER_LOGIN }}" ] && [ -n "${{ secrets.DOCKER_PASSWORD }}" ]; then - if docker login ${{ env.REGISTRY }} -u ${{ secrets.DOCKER_LOGIN }} -p ${{ secrets.DOCKER_PASSWORD }} 2>/dev/null; then - docker tag ${{ env.IMAGE_NAME }}:latest ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - echo "Successfully pushed CI image to ${{ env.REGISTRY }}" - else - echo "Warning: Docker login failed with provided credentials" - echo "CI image built locally but not pushed to registry" - fi - else - echo "Warning: DOCKER_LOGIN or DOCKER_PASSWORD secrets not configured" - echo "CI image built locally but not pushed to registry" - fi - - - name: Show usage instructions - run: | - echo "CI Image built successfully!" - echo "" - echo "To use in workflows:" - echo " container:" - echo " image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" diff --git a/.gitea/workflows/pr.yml b/.gitea/workflows/pr.yml index f056317..4894686 100644 --- a/.gitea/workflows/pr.yml +++ b/.gitea/workflows/pr.yml @@ -9,19 +9,15 @@ jobs: unit-tests: runs-on: ubuntu-latest container: - image: docker.notsosm.art/euchre-camp-ci-runner:latest + image: node:20-alpine options: --user root - env: - NODE_PATH: /workspace/david/euchre_camp/node_modules steps: - name: Checkout code uses: actions/checkout@v4 - - name: Link node_modules from container - run: | - # Create symlink from container's node_modules to workspace - ln -sf /app/node_modules /workspace/david/euchre_camp/node_modules + - name: Install dependencies + run: npm ci - name: Run unit tests run: npm run test:run @@ -30,22 +26,29 @@ jobs: runs-on: ubuntu-latest needs: unit-tests container: - image: docker.notsosm.art/euchre-camp-ci-runner:latest + image: mcr.microsoft.com/playwright:v1.58.0-jammy options: --user root env: DATABASE_PROVIDER: sqlite DATABASE_URL: file:./prisma/ci.db BETTER_AUTH_SECRET: test-secret-key-for-ci-only - NODE_PATH: /workspace/david/euchre_camp/node_modules steps: - name: Checkout code uses: actions/checkout@v4 - - name: Link node_modules from container - run: | - # Create symlink from container's node_modules to workspace - ln -sf /app/node_modules /workspace/david/euchre_camp/node_modules + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install dependencies + run: npm ci + + - name: Generate Prisma client + run: npx prisma generate + env: + DATABASE_URL: postgresql://user:pass@localhost:5432/dummy - name: Setup SQLite database run: | diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index 1537d15..2a3e21e 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -9,21 +9,17 @@ jobs: unit-tests: runs-on: ubuntu-latest container: - image: docker.notsosm.art/euchre-camp-ci-runner:latest + image: node:20-alpine options: --user root # Skip if this is an auto-generated version bump commit (handled by release workflow) if: "!contains(github.event.head_commit.message, 'chore: bump version')" - env: - NODE_PATH: /workspace/david/euchre_camp/node_modules steps: - name: Checkout code uses: actions/checkout@v4 - - name: Link node_modules from container - run: | - # Create symlink from container's node_modules to workspace - ln -sf /app/node_modules /workspace/david/euchre_camp/node_modules + - name: Install dependencies + run: npm ci - name: Run unit tests run: npm run test:run diff --git a/AGENTS.md b/AGENTS.md index cc1bd0c..9fad454 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -129,23 +129,26 @@ DATABASE_PROVIDER=sqlite DATABASE_URL=file:./prisma/ci.db npm run test:acceptanc ### CI Runner Image -To speed up CI runs, the project uses a pre-built CI runner image with all dependencies pre-installed. +**Note:** The CI runner image approach has been deprecated for Gitea Actions workflows. -**Building the CI image locally:** -```bash -./scripts/build-ci-image.sh [tag] -``` +The original attempt to use a pre-built CI runner image with pre-installed dependencies encountered fundamental issues with how Gitea Actions handles workspace mounting. When Gitea Actions runs a container job, it mounts the workspace at a specific path (e.g., `/workspace/david/euchre_camp`), which hides the container's `/app` directory where dependencies were installed. -**Using the CI image:** -- Workflows automatically use `ghcr.io//ci-runner:latest` when available -- Falls back to `node:20-alpine` if image is not found -- Image is automatically rebuilt when `package.json` changes +**Current Approach:** +- Workflows use standard `node:20-alpine` or `mcr.microsoft.com/playwright` containers +- Dependencies are installed via `npm ci` in each workflow run +- This is the recommended approach for Gitea Actions -**CI Image contains:** -- Node.js 20 Alpine -- All npm dependencies pre-installed -- Prisma client pre-generated -- System tools (bash, git, python, make, g++) +**Why the CI image approach doesn't work:** +1. Dockerfile.ci installs dependencies in `/app` +2. Gitea Actions mounts workspace at `/workspace/david/euchre_camp` +3. Workspace mount hides the `/app` directory +4. Symlinks from `/app/node_modules` don't work because `/app` is hidden + +**Alternative for performance:** +If CI performance becomes an issue, consider: +- Using GitHub Actions cache for node_modules +- Using a self-hosted runner with persistent workspace +- Using the main Dockerfile's `test-runner` target for release workflows (which works because it builds a complete image) ### CI/CD Pipeline The project uses Gitea Actions for continuous integration: diff --git a/Dockerfile.ci b/Dockerfile.ci deleted file mode 100644 index 36429f2..0000000 --- a/Dockerfile.ci +++ /dev/null @@ -1,46 +0,0 @@ -# CI Runner Image for EuchreCamp -# Pre-installed with all dependencies to speed up CI runs -# This image is rebuilt automatically when package.json changes - -FROM node:20-alpine - -# Install system dependencies needed for various tasks -RUN apk add --no-cache \ - bash \ - git \ - curl \ - python3 \ - make \ - g++ \ - && rm -rf /var/cache/apk/* - -# Set working directory -WORKDIR /app - -# Copy package files first (for better caching) -COPY package*.json ./ - -# Install ALL dependencies including dev dependencies -# This is done at image build time, not at CI runtime -RUN npm ci - -# Copy Prisma schema (needed for Prisma client generation) -COPY prisma/schema.prisma ./prisma/ - -# Generate Prisma client -RUN npx prisma generate - -# Copy the rest of the application -COPY . . - -# Set environment variables for CI environment -ENV NODE_ENV=production -ENV DATABASE_PROVIDER=sqlite -ENV DATABASE_URL=file:./prisma/ci.db -ENV BETTER_AUTH_SECRET=test-secret-key-for-ci-only - -# Verify installations -RUN node --version && npm --version && git --version && npx prisma --version - -# Default command -CMD ["/bin/sh"] diff --git a/README.md b/README.md index 43809f9..df765b7 100644 --- a/README.md +++ b/README.md @@ -368,35 +368,27 @@ The application uses Gitea Actions for continuous integration and deployment: - Unit tests for quick feedback - Skips auto-generated version bumps -3. **Release Workflow** (`.gitea/workflows/release.yml`): Runs on main branch pushes - - Version bumping and tagging - - Docker image building and testing - - Registry push and deployment - -4. **CI Image Builder** (`.gitea/workflows/ci-image-builder.yml`): Runs when dependencies change - - Automatically builds CI runner image with all dependencies pre-installed - - Triggered by changes to `package.json`, `package-lock.json`, or `Dockerfile.ci` + 3. **Release Workflow** (`.gitea/workflows/release.yml`): Runs on main branch pushes + - Version bumping and tagging + - Docker image building and testing + - Registry push and deployment ### CI Runner Image -To avoid installing dependencies on every workflow run, we use a pre-built CI runner image: +**Note:** The CI runner image approach has been deprecated for Gitea Actions workflows. -**Dockerfile.ci** - Contains: -- Node.js 20 Alpine -- All npm dependencies pre-installed -- Prisma client pre-generated -- System tools (bash, git, python, make, g++) +The original attempt to use a pre-built CI runner image with pre-installed dependencies encountered fundamental issues with how Gitea Actions handles workspace mounting. When Gitea Actions runs a container job, it mounts the workspace at a specific path (e.g., `/workspace/david/euchre_camp`), which hides the container's `/app` directory where dependencies were installed. -**Automatic Rebuilding:** -- The CI image is automatically rebuilt when `package.json` or `package-lock.json` changes -- Images are tagged with commit SHA for traceability -- Falls back to `node:20-alpine` if custom image is not available +**Current Approach:** +- Workflows use standard `node:20-alpine` or `mcr.microsoft.com/playwright` containers +- Dependencies are installed via `npm ci` in each workflow run +- This is the recommended approach for Gitea Actions -**Manual Build:** -```bash -docker build -f Dockerfile.ci -t euchre-camp-ci:latest . -docker run --rm euchre-camp-ci:latest node --version -``` +**Why the CI image approach doesn't work:** +1. Dockerfile.ci installs dependencies in `/app` +2. Gitea Actions mounts workspace at `/workspace/david/euchre_camp` +3. Workspace mount hides the `/app` directory +4. Symlinks from `/app/node_modules` don't work because `/app` is hidden ### Database Strategy for CI - **CI Tests**: SQLite database (fast, no server required) @@ -410,9 +402,6 @@ npm run test:run # Run acceptance tests with SQLite DATABASE_PROVIDER=sqlite DATABASE_URL=file:./prisma/ci.db npm run test:acceptance - -# Run tests in CI container (if built) -docker run --rm -v $(pwd):/app -w /app euchre-camp-ci:latest npm run test:run ``` ## Docker Deployment diff --git a/justfile b/justfile index b25676e..ce44c9a 100644 --- a/justfile +++ b/justfile @@ -173,16 +173,6 @@ pr-validate: lint typecheck test-unit test-acceptance-sqlite ci-postgres: lint typecheck test-unit test-acceptance-postgres docker-build @echo "CI Pipeline with PostgreSQL completed successfully!" -# --- CI Image --- - -# Build CI runner image locally -ci-build: - @./scripts/build-ci-image.sh - -# Build CI runner image with custom tag -ci-build-tag TAG: - @./scripts/build-ci-image.sh {{TAG}} - # --- Utilities --- # Show help information @@ -256,6 +246,8 @@ workflow-status: @echo "PR Workflow: Runs unit + acceptance tests on pull requests" @echo "Test Workflow: Runs unit tests on all branch pushes" @echo "Release Workflow: Runs on main branch pushes (version bump + Docker build)" + @echo "" + @echo "Note: CI image approach deprecated due to Gitea Actions workspace mounting" # Check current database provider db-status: diff --git a/scripts/build-ci-image.sh b/scripts/build-ci-image.sh deleted file mode 100755 index 403e356..0000000 --- a/scripts/build-ci-image.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -# Build and test the CI runner image locally - -set -e - -IMAGE_NAME="euchre-camp-ci-runner" -TAG="${1:-latest}" - -echo "Building CI runner image..." -echo "Image: ${IMAGE_NAME}:${TAG}" -echo "" - -# Build the image -docker build \ - -f Dockerfile.ci \ - -t ${IMAGE_NAME}:${TAG} \ - . - -echo "" -echo "✅ Image built successfully!" -echo "" - -# Test the image -echo "Testing CI image..." -docker run --rm ${IMAGE_NAME}:${TAG} sh -c " - echo 'Node.js version:' && node --version - echo 'npm version:' && npm --version - echo 'Git version:' && git --version - echo 'Prisma version:' && npx prisma --version - echo '' - echo 'Installed packages (top 10):' - npm list --depth=0 | head -10 -" - -echo "" -echo "✅ CI image is ready to use!" -echo "" -echo "To use in GitHub Actions/Gitea Actions:" -echo " container:" -echo " image: docker.notsosm.art/${IMAGE_NAME}:${TAG}" -echo "" -echo "To push to registry:" -echo " docker tag ${IMAGE_NAME}:${TAG} docker.notsosm.art/${IMAGE_NAME}:${TAG}" -echo " docker push docker.notsosm.art/${IMAGE_NAME}:${TAG}"