SEO_iamge_renamer_starting_.../.forgejo/workflows/ci.yml
DustyWalker 9366cfa94f feat: add .forgejo/workflows/ci.yml - comprehensive CI pipeline configuration
CI/CD pipeline with comprehensive automation:
- Multi-stage workflow with dependency caching
- Linting, formatting, and TypeScript type checking
- Unit tests with coverage reporting across all packages
- Integration tests with PostgreSQL, Redis, and MinIO services
- Docker build and container testing
- Security scanning with npm audit and Snyk
- Dependency update monitoring
- Deployment readiness validation
- Matrix testing strategy for monorepo packages
- Artifact management and retention policies

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-05 16:52:14 +02:00

397 lines
No EOL
10 KiB
YAML

name: CI Pipeline
on:
push:
branches: [ main, develop, 'feature/*', 'hotfix/*' ]
pull_request:
branches: [ main, develop ]
workflow_dispatch:
env:
NODE_VERSION: '18'
PNPM_VERSION: '8.15.0'
jobs:
# Install dependencies and cache
setup:
name: Setup Dependencies
runs-on: ubuntu-latest
outputs:
cache-key: ${{ steps.cache-keys.outputs.node-modules }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://registry.npmjs.org'
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
run_install: false
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Generate cache keys
id: cache-keys
run: |
echo "node-modules=${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}" >> $GITHUB_OUTPUT
- name: Setup pnpm cache
uses: actions/cache@v3
with:
path: ${{ env.STORE_PATH }}
key: ${{ steps.cache-keys.outputs.node-modules }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Cache node_modules
uses: actions/cache@v3
id: cache-node-modules
with:
path: |
node_modules
packages/*/node_modules
key: ${{ steps.cache-keys.outputs.node-modules }}-modules
restore-keys: |
${{ runner.os }}-pnpm-modules-
# Linting and formatting
lint:
name: Lint & Format Check
runs-on: ubuntu-latest
needs: setup
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: Restore dependencies
uses: actions/cache@v3
with:
path: |
node_modules
packages/*/node_modules
key: ${{ needs.setup.outputs.cache-key }}-modules
- name: Run ESLint
run: pnpm lint
- name: Check Prettier formatting
run: pnpm format:check
- name: TypeScript type check
run: pnpm typecheck
# Unit tests
test:
name: Unit Tests
runs-on: ubuntu-latest
needs: setup
strategy:
matrix:
package: [api, worker, frontend, shared]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: Restore dependencies
uses: actions/cache@v3
with:
path: |
node_modules
packages/*/node_modules
key: ${{ needs.setup.outputs.cache-key }}-modules
- name: Run tests for ${{ matrix.package }}
run: pnpm --filter @ai-renamer/${{ matrix.package }} test
- name: Generate coverage report
run: pnpm --filter @ai-renamer/${{ matrix.package }} test:coverage
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./packages/${{ matrix.package }}/coverage/lcov.info
flags: ${{ matrix.package }}
name: ${{ matrix.package }}-coverage
fail_ci_if_error: false
# Integration tests
integration-test:
name: Integration Tests
runs-on: ubuntu-latest
needs: setup
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_PASSWORD: test_password
POSTGRES_DB: ai_image_renamer_test
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
minio:
image: minio/minio:latest
env:
MINIO_ROOT_USER: test_user
MINIO_ROOT_PASSWORD: test_password
options: >-
--health-cmd "curl -f http://localhost:9000/minio/health/live"
--health-interval 30s
--health-timeout 20s
--health-retries 3
ports:
- 9000:9000
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: Restore dependencies
uses: actions/cache@v3
with:
path: |
node_modules
packages/*/node_modules
key: ${{ needs.setup.outputs.cache-key }}-modules
- name: Setup test environment
run: |
cp .env.example .env.test
echo "DATABASE_URL=postgresql://postgres:test_password@localhost:5432/ai_image_renamer_test" >> .env.test
echo "REDIS_URL=redis://localhost:6379" >> .env.test
echo "MINIO_ENDPOINT=localhost:9000" >> .env.test
echo "MINIO_ACCESS_KEY=test_user" >> .env.test
echo "MINIO_SECRET_KEY=test_password" >> .env.test
- name: Run database migrations
run: pnpm --filter @ai-renamer/api db:migrate
- name: Run integration tests
run: pnpm test:integration
env:
NODE_ENV: test
# Build application
build:
name: Build Application
runs-on: ubuntu-latest
needs: [setup, lint, test]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: Restore dependencies
uses: actions/cache@v3
with:
path: |
node_modules
packages/*/node_modules
key: ${{ needs.setup.outputs.cache-key }}-modules
- name: Build all packages
run: pnpm build
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: build-artifacts
path: |
packages/*/dist
packages/*/build
retention-days: 7
# Docker build and test
docker:
name: Docker Build & Test
runs-on: ubuntu-latest
needs: [setup, lint, test]
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop')
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker image
uses: docker/build-push-action@v5
with:
context: .
target: production
tags: ai-bulk-image-renamer:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
outputs: type=docker,dest=/tmp/image.tar
- name: Upload Docker image artifact
uses: actions/upload-artifact@v3
with:
name: docker-image
path: /tmp/image.tar
retention-days: 1
- name: Test Docker image
run: |
docker load < /tmp/image.tar
docker run --rm --name test-container -d \
-e NODE_ENV=test \
ai-bulk-image-renamer:${{ github.sha }}
sleep 10
docker logs test-container
docker stop test-container
# Security scanning
security:
name: Security Scan
runs-on: ubuntu-latest
needs: setup
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: Restore dependencies
uses: actions/cache@v3
with:
path: |
node_modules
packages/*/node_modules
key: ${{ needs.setup.outputs.cache-key }}-modules
- name: Run npm audit
run: pnpm audit --audit-level moderate
continue-on-error: true
- name: Run Snyk security scan
uses: snyk/actions/node@master
continue-on-error: true
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=medium
# Dependency updates check
dependency-updates:
name: Check Dependency Updates
runs-on: ubuntu-latest
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: Check for outdated dependencies
run: pnpm outdated
- name: Create dependency update issue
if: failure()
uses: actions/github-script@v6
with:
script: |
github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: 'Dependency Updates Available',
body: 'Automated check found outdated dependencies. Please review and update.',
labels: ['dependencies', 'maintenance']
})
# Deployment readiness check
deploy-check:
name: Deployment Readiness
runs-on: ubuntu-latest
needs: [build, docker, security, integration-test]
if: github.ref == 'refs/heads/main'
steps:
- name: Deployment ready
run: |
echo "✅ All checks passed - ready for deployment"
echo "Build artifacts and Docker image are available"
echo "Security scans completed"
echo "Integration tests passed"