name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
release:
types: [published]
schedule:
- cron: "0 2 * * *" # Daily at 2 AM UTC
workflow_dispatch:
env:
NODE_VERSION: "20"
NODE_OPTIONS: "--max-old-space-size=8192"
jobs:
# Parallel test execution with right-sized memory allocation
test:
name: Test (${{ matrix.suite }}, Node ${{ matrix.node-version }})
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
node-version: [20, 22]
suite:
- name: "security-cache-server"
path: "tests/security/ tests/cache/ tests/server/"
memory: "4096"
- name: "client-config-utils"
path: "tests/client/ tests/config/ tests/utils/"
memory: "6144"
- name: "tools-performance"
path: "tests/tools/ tests/performance/"
memory: "4096"
- name: "root-docs"
path: "tests/*.test.js tests/docs/"
memory: "2048"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
- name: Run tests - ${{ matrix.suite.name }}
run:
NODE_OPTIONS="--max-old-space-size=${{ matrix.suite.memory }}" npx vitest run ${{ matrix.suite.path }}
--no-coverage --reporter=default
env:
CI: true
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.suite.name }}-node-${{ matrix.node-version }}
path: |
coverage/
tests/results/
# Quality checks (linting, security, etc.) - no test execution here
quality:
name: Quality Checks
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
- name: TypeScript check
run: npm run typecheck
- name: Lint code
run: npm run lint
- name: Security audit
run: npm audit --production --audit-level moderate
continue-on-error: true
# Security scanning
security:
name: Security Scan
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: "fs"
scan-ref: "."
format: "sarif"
output: "trivy-results.sarif"
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: "trivy-results.sarif"
# Build and package
build:
name: Build Package
runs-on: ubuntu-latest
needs: [test, quality]
if: success()
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
- name: Test package
run: npm pack --dry-run
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: |
dist/
package.json
README.md
LICENSE
# Docker build and push
docker:
name: Docker Build & Push
runs-on: ubuntu-latest
needs: [test, quality]
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: docdyhr/mcp-wordpress
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# NPM publish (on releases)
publish-npm:
name: Publish to NPM
runs-on: ubuntu-latest
needs: [test, quality, build]
if: github.event_name == 'release' && github.event.action == 'published'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
registry-url: "https://registry.npmjs.org"
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
- name: Publish to NPM
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# Update badges and documentation
update-badges:
name: Update Badges
runs-on: ubuntu-latest
needs: [test, quality]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
- name: Generate coverage badge data
run: npm run test:coverage
continue-on-error: true
- name: Update documentation
run: |
if [ -f "scripts/update-badges.js" ]; then
node scripts/update-badges.js
fi
continue-on-error: true
- name: Commit badge updates
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore: update badges and documentation [skip ci]"
file_pattern: "README.md docs/**"
continue-on-error: true