---
name: ๐ Continuous Integration
"on":
push:
branches: [main, develop, "feat/**"]
pull_request:
branches: [main, develop]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# ============================================================================
# PRE-FLIGHT CHECKS
# ============================================================================
pre-flight:
name: ๐ Pre-flight Checks
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
should-run-tests: ${{ steps.changes.outputs.should-run-tests }}
should-run-security: ${{ steps.changes.outputs.should-run-security }}
steps:
- name: ๐ฅ Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: ๐ Detect Changes
id: changes
run: |
# Check if we should run tests based on file changes
# Handle cases where github.event.before might be null
# (new branch, force push, etc.)
BEFORE="${{ github.event.before }}"
if [[ "$BEFORE" == \
"0000000000000000000000000000000000000000" ]] || \
[[ -z "$BEFORE" ]]; then
echo "๐ New branch or force push detected - running all tests"
echo "should-run-tests=true" >> $GITHUB_OUTPUT
else
# Check for relevant file changes
PATTERN='\.(ts|js|json)$|package\.json|\.github/workflows|scripts/'
if git diff --name-only "$BEFORE" "${{ github.sha }}" | \
grep -E "$PATTERN"; then
echo "๐ Code changes detected - running tests"
echo "should-run-tests=true" >> $GITHUB_OUTPUT
else
echo "๐ Only documentation changes detected - skipping tests"
echo "should-run-tests=false" >> $GITHUB_OUTPUT
fi
fi
# Always run security checks on main/develop, or if package.json
# changed
REF="${{ github.ref }}"
if [[ "$REF" == "refs/heads/main" || \
"$REF" == "refs/heads/develop" ]]; then
echo "should-run-security=true" >> $GITHUB_OUTPUT
elif [[ "$BEFORE" != \
"0000000000000000000000000000000000000000" ]] && \
[[ -n "$BEFORE" ]]; then
PKG_PATTERN='package\.json|package-lock\.json'
if git diff --name-only "$BEFORE" "${{ github.sha }}" | \
grep -E "$PKG_PATTERN"; then
echo "๐ฆ Pkg deps changed, run security"
echo "should-run-security=true" >> $GITHUB_OUTPUT
else
echo "should-run-security=false" >> $GITHUB_OUTPUT
fi
else
echo "should-run-security=false" >> $GITHUB_OUTPUT
fi
- name: ๐ฏ Pre-flight Check
run: |
echo "โ
Repository checked out successfully"
echo "๐${{ steps.changes.outputs.should-run-tests }}"
echo "๐ ${{ steps.changes.outputs.should-run-security }}"
dependency-sync:
name: ๐ Dependency Sync Check
runs-on: ubuntu-latest
needs: pre-flight
if: needs.pre-flight.outputs.should-run-tests == 'true'
timeout-minutes: 5
steps:
- name: ๐ฅ Checkout Repository
uses: actions/checkout@v4
- name: ๐ข Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: ๐ฆ Install Dependencies
run: npm ci --prefer-offline --no-audit
- name: ๐ Check Package Lock Sync
run: |
echo "๐ Checking if package.json and package-lock.json are in sync..."
if npm ci --dry-run --prefer-offline --no-audit --ignore-scripts; then
echo "โ
Package files are in sync"
else
echo "โ ๏ธ Package files are out of sync - attempting to fix..."
echo "๐ฆ Running npm install to update lock file..."
npm install --package-lock-only --ignore-scripts
# Check if there are changes to commit
if git diff --exit-code package-lock.json; then
echo "โ
No changes needed to package-lock.json"
else
echo "โ package-lock.json needs to be updated"
echo "Please run 'npm install' locally and commit the" \
"updated package-lock.json"
git diff package-lock.json
exit 1
fi
fi
# ============================================================================
# QUALITY GATES
# ============================================================================
quality-gates:
name: ๐ Quality Gates
runs-on: ubuntu-latest
needs: [pre-flight, dependency-sync]
if: needs.pre-flight.outputs.should-run-tests == 'true'
timeout-minutes: 10
strategy:
matrix:
node-version: [18, 20, 22]
steps:
- name: ๐ฅ Checkout Repository
uses: actions/checkout@v4
- name: ๐ข Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: "npm"
registry-url: "https://registry.npmjs.org"
- name: ๐ฆ Install Dependencies
run: |
# Use npm install if ci fails due to sync issues
if ! npm ci --prefer-offline --no-audit --ignore-scripts; then
echo "โ ๏ธ npm ci failed, falling back to npm install..."
npm install --prefer-offline --no-audit --ignore-scripts
fi
echo "โ
Dependencies installed for Node.js ${{ matrix.node-version }}"
- name: ๐จ Build Project
run: |
npm run build
echo "โ
TypeScript compilation successful"
- name: ๐งน ESLint Check
run: |
npm run lint:check
echo "โ
ESLint validation passed"
- name: ๐
Prettier Check
run: |
npm run format:check
echo "โ
Code formatting validated"
- name: ๐ TypeScript Check
run: |
npm run type-check
echo "โ
TypeScript type checking passed"
- name: โ
Unit Tests
timeout-minutes: 5
run: |
npm run test:unit:fast
echo "โ
Unit tests completed successfully"
- name: ๐ Package Validation
run: |
npm run validate-package
echo "โ
Package validation completed"
# ============================================================================
# SECURITY SCANNING
# ============================================================================
security-scan:
name: ๐ Security Scanning
runs-on: ubuntu-latest
needs: [pre-flight, dependency-sync]
if: needs.pre-flight.outputs.should-run-security == 'true'
timeout-minutes: 10
steps:
- name: ๐ฅ Checkout Repository
uses: actions/checkout@v4
- name: ๐ข Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: ๐ฆ Install Dependencies
run: |
# Use npm install if ci fails due to sync issues
if ! npm ci --prefer-offline --no-audit --ignore-scripts; then
echo "โ ๏ธ npm ci failed, falling back to npm install..."
npm install --prefer-offline --no-audit --ignore-scripts
fi
- name: ๐ Security Audit
run: |
npm run security:check
echo "โ
Security audit completed"
- name: ๐ Dependency Vulnerability Scan
run: |
npx audit-ci --config .audit-ci.json || \
echo "โ ๏ธ Vulnerabilities found but not blocking"
echo "โ
Dependency scan completed"
# ============================================================================
# INTEGRATION VALIDATION
# ============================================================================
integration-validation:
name: ๐ Integration Validation
runs-on: ubuntu-latest
needs: [quality-gates]
timeout-minutes: 15
steps:
- name: ๐ฅ Checkout Repository
uses: actions/checkout@v4
- name: ๐ข Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: ๐ฆ Install Dependencies
run: |
# Use npm install if ci fails due to sync issues
if ! npm ci --prefer-offline --no-audit --ignore-scripts; then
echo "โ ๏ธ npm ci failed, falling back to npm install..."
npm install --prefer-offline --no-audit --ignore-scripts
fi
- name: ๐จ Build Project
run: npm run build
- name: ๐งช Run unit tests
run: npm run test:unit
- name: ๐ Generate coverage report
run: npm run test:coverage
- name: ๐ค Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage/lcov.info
flags: unittests
name: codecov-umbrella
- name: โ
Check coverage threshold
run: npm run test:coverage:check
# ============================================================================
# DOCUMENTATION & EXAMPLES
# ============================================================================
documentation:
name: ๐ Documentation & Examples
runs-on: ubuntu-latest
needs: [quality-gates]
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'
timeout-minutes: 15
steps:
- name: ๐ฅ Checkout Repository
uses: actions/checkout@v4
- name: ๐ข Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: ๐ฆ Install Dependencies
run: |
# Use npm install if ci fails due to sync issues
if ! npm ci --prefer-offline --no-audit --ignore-scripts; then
echo "โ ๏ธ npm ci failed, falling back to npm install..."
npm install --prefer-offline --no-audit --ignore-scripts
fi
- name: ๐จ Build Project
run: npm run build
- name: ๐ Pre-flight System Check
run: |
npm run pre-flight
echo "โ
Pre-flight checks completed"
- name: ๐ API Documentation Generation
run: |
npm run docs:api
echo "โ
API documentation generated with TypeDoc"
- name: ๐ Interactive Documentation Generation
run: |
npm run docs:generate
echo "โ
Interactive documentation generated successfully"
- name: ๐ Documentation Link Validation
run: |
npm run docs:test-links
echo "โ
Documentation links validated"
- name: ๐ Example Configuration Validation
run: |
npm run validate:examples
echo "โ
Example configurations validated"
- name: ๐ค Upload Documentation Artifacts
uses: actions/upload-artifact@v4
with:
name: documentation-${{ github.sha }}
path: |
docs/api/
docs/api-interactive.html
docs/API_AUTO_GENERATED.md
docs/examples/
retention-days: 30
# ============================================================================
# BUILD ARTIFACTS
# ============================================================================
build-artifacts:
name: ๐ฆ Build Artifacts
runs-on: ubuntu-latest
needs: [quality-gates, security-scan]
if: github.ref == 'refs/heads/main'
timeout-minutes: 10
steps:
- name: ๐ฅ Checkout Repository
uses: actions/checkout@v4
- name: ๐ข Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- name: ๐ฆ Install Dependencies
run: |
# Use npm install if ci fails due to sync issues
if ! npm ci --prefer-offline --no-audit --ignore-scripts; then
echo "โ ๏ธ npm ci failed, falling back to npm install..."
npm install --prefer-offline --no-audit --ignore-scripts
fi
- name: ๐จ Build Production Assets
run: |
npm run build:clean
npm run build:standalone
npm run build:templates
echo "โ
Production build completed"
- name: ๐ Enhanced Package Validation
run: |
echo "๐ Running comprehensive package validation..."
npm run validate-package
npm pack --dry-run
echo "โ
Package validation completed"
- name: ๐ฆ Create Distribution Package
run: |
mkdir -p dist/packages
npm pack --pack-destination=dist/packages
echo "โ
Distribution package created"
- name: ๐ Generate Build Report
run: |
echo "# Build Artifacts Report" > build-report.md
echo "" >> build-report.md
echo "## Build Information" >> build-report.md
echo "- **Commit:** ${{ github.sha }}" >> build-report.md
echo "- **Branch:** ${{ github.ref_name }}" >> build-report.md
echo "- **Build Date:** $(date -u)" >> build-report.md
echo "- **Node Version:** $(node --version)" >> build-report.md
echo "- **NPM Version:** $(npm --version)" >> build-report.md
echo "" >> build-report.md
echo "## Artifacts Generated" >> build-report.md
echo "- Standalone distribution in \`dist/\`" >> build-report.md
echo "- Configuration templates in \`templates/\`" >> build-report.md
echo "- API documentation in \`docs/api/\`" >> build-report.md
echo "- NPM package in \`dist/packages/\`" >> build-report.md
echo "" >> build-report.md
echo "## File Sizes" >> build-report.md
if [ -d "dist" ]; then
du -sh dist/* >> build-report.md 2>/dev/null || \
echo "No dist files" >> build-report.md
fi
echo "โ
Build report generated"
- name: ๐พ Upload Build Artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts-${{ github.sha }}
path: |
build/
dist/
templates/
docs/api/
docs/api-interactive.html
docs/API_AUTO_GENERATED.md
build-report.md
retention-days: 30
compression-level: 6
- name: ๐พ Upload Release Assets
if: github.ref == 'refs/heads/main'
uses: actions/upload-artifact@v4
with:
name: release-assets-${{ github.sha }}
path: |
dist/packages/*.tgz
dist/distribution-manifest.json
dist/README-STANDALONE.md
build-report.md
retention-days: 90
# ============================================================================
# CI STATUS SUMMARY
# ============================================================================
ci-status:
name: โ
CI Status Summary
runs-on: ubuntu-latest
needs:
- pre-flight
- dependency-sync
- quality-gates
- security-scan
- integration-validation
- documentation
- build-artifacts
if: always()
steps:
- name: ๐ CI Results Summary
run: |
echo "## ๐ CI Pipeline Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
# Job arrays split for readability
jobs=("pre-flight" "dependency-sync" "quality-gates" \
"security-scan" "integration-validation" \
"documentation" "build-artifacts")
names=("Pre-flight" "Dependency Sync" "Quality Gates" \
"Security Scan" "Integration" "Documentation" \
"Build Artifacts")
# Results array split for readability
results=(
"${{ needs.pre-flight.result }}"
"${{ needs.dependency-sync.result }}"
"${{ needs.quality-gates.result }}"
"${{ needs.security-scan.result }}"
"${{ needs.integration-validation.result }}"
"${{ needs.documentation.result }}"
"${{ needs.build-artifacts.result }}"
)
for i in "${!jobs[@]}"; do
case "${results[$i]}" in
"success")
echo "| ${names[$i]} | โ
Passed |" >> $GITHUB_STEP_SUMMARY
;;
"skipped")
echo "| ${names[$i]} | โญ๏ธ Skipped |" >> $GITHUB_STEP_SUMMARY
;;
*)
echo "| ${names[$i]} | โ Failed |" >> $GITHUB_STEP_SUMMARY
;;
esac
done
echo "" >> $GITHUB_STEP_SUMMARY
# Check critical jobs status
critical_jobs=(
"${{ needs.pre-flight.result }}"
"${{ needs.dependency-sync.result }}"
"${{ needs.quality-gates.result }}"
"${{ needs.security-scan.result }}"
)
all_critical_ok=true
for result in "${critical_jobs[@]}"; do
if [[ "$result" != "success" && "$result" != "skipped" ]]; then
all_critical_ok=false
break
fi
done
if [[ "$all_critical_ok" == "true" ]]; then
echo "๐ **CI Pipeline Successful!**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### ๐ Next Steps" >> $GITHUB_STEP_SUMMARY
echo "- Run \`npm run pre-push\` locally" >> $GITHUB_STEP_SUMMARY
echo "- Use \`npm run ci-cd:validate\` for release" \
>> $GITHUB_STEP_SUMMARY
else
echo "โ **CI Pipeline Failed!**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### ๐ง Troubleshooting" >> $GITHUB_STEP_SUMMARY
echo "- Run \`npm run pre-push\` locally" >> $GITHUB_STEP_SUMMARY
echo "- Check package.json sync" >> $GITHUB_STEP_SUMMARY
exit 1
fi