UNPKG

@tehreet/conduit

Version:

LLM API gateway with intelligent routing, robust process management, and health monitoring

699 lines (569 loc) 18.3 kB
# CI/CD Strategy for Conduit ## Table of Contents - [Overview](#overview) - [CI/CD Goals](#cicd-goals) - [Technology Stack](#technology-stack) - [Pipeline Architecture](#pipeline-architecture) - [Branch Strategy](#branch-strategy) - [Continuous Integration](#continuous-integration) - [Continuous Deployment](#continuous-deployment) - [NPM Publishing Strategy](#npm-publishing-strategy) - [Docker Registry](#docker-registry) - [Security & Compliance](#security--compliance) - [Monitoring & Alerts](#monitoring--alerts) - [Implementation Roadmap](#implementation-roadmap) ## Overview This document outlines the comprehensive CI/CD strategy for Conduit, an intelligent LLM API gateway. Our CI/CD pipeline ensures code quality, automates testing, manages releases, and handles deployment across multiple environments. ## CI/CD Goals 1. **Automated Quality Assurance**: Ensure every commit meets quality standards 2. **Rapid Feedback**: Provide developers with quick feedback on code changes 3. **Automated Releases**: Streamline the release process with semantic versioning 4. **Zero-Downtime Deployments**: Deploy updates without service interruption 5. **Security First**: Integrate security scanning throughout the pipeline 6. **Reproducible Builds**: Ensure consistent builds across environments ## Technology Stack - **CI/CD Platform**: GitHub Actions (primary), with GitLab CI/CD as backup - **Container Registry**: GitHub Container Registry (GHCR) and Docker Hub - **NPM Registry**: npmjs.com for public package distribution - **Testing Frameworks**: Jest (unit), Playwright (E2E), Artillery (load testing) - **Code Quality**: ESLint, Prettier, TypeScript compiler, SonarCloud - **Security Scanning**: Snyk, GitHub Dependabot, OWASP Dependency Check - **Monitoring**: Datadog, Prometheus, Grafana ## Pipeline Architecture ```mermaid graph LR A[Code Push] --> B[CI Pipeline] B --> C{Branch?} C -->|main| D[Production Pipeline] C -->|develop| E[Staging Pipeline] C -->|feature/*| F[Feature Pipeline] D --> G[NPM Publish] D --> H[Docker Build] D --> I[Deploy Prod] E --> J[Deploy Staging] F --> K[PR Checks] ``` ## Branch Strategy We follow a modified GitFlow strategy: - **main**: Production-ready code, protected branch - **develop**: Integration branch for features - **feature/***: Feature development branches - **release/***: Release preparation branches - **hotfix/***: Emergency fixes for production ### Branch Protection Rules **Main Branch**: - Require PR reviews (minimum 2 approvers) - Require status checks to pass - Require branches to be up to date - Include administrators in restrictions - Restrict force pushes and deletions ## Continuous Integration ### GitHub Actions Workflow: `.github/workflows/ci.yml` ```yaml name: CI Pipeline on: push: branches: [main, develop] pull_request: branches: [main, develop] env: NODE_VERSION: '20.x' REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: # Code Quality Checks quality: runs-on: ubuntu-latest steps: - 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: Lint code run: npm run lint - name: Format check run: npm run format:check - name: Type check run: npm run typecheck - name: License check run: npx license-checker --production --onlyAllow 'MIT;Apache-2.0;BSD-3-Clause;BSD-2-Clause;ISC' # Security Scanning security: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run Snyk Security Scan uses: snyk/actions/node@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: args: --severity-threshold=high - name: Upload Snyk results uses: github/codeql-action/upload-sarif@v2 if: always() with: sarif_file: snyk.sarif # Unit Tests test-unit: runs-on: ubuntu-latest strategy: matrix: node-version: [18.x, 20.x, 22.x] steps: - 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: Run unit tests run: npm run test:unit -- --coverage - name: Upload coverage uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} flags: unit # Integration Tests test-integration: runs-on: ubuntu-latest services: redis: image: redis:7-alpine options: >- --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5 ports: - 6379:6379 steps: - 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: Run integration tests run: npm run test:integration env: REDIS_URL: redis://localhost:6379 # Build Artifacts build: needs: [quality, security, test-unit] runs-on: ubuntu-latest steps: - 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 run: npm run build - name: Package artifacts run: | tar -czf conduit-${{ github.sha }}.tar.gz dist package.json package-lock.json - name: Upload artifacts uses: actions/upload-artifact@v3 with: name: build-artifacts path: conduit-${{ github.sha }}.tar.gz retention-days: 7 # SonarCloud Analysis sonarcloud: needs: [test-unit] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: SonarCloud Scan uses: SonarSource/sonarcloud-github-action@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} ``` ### Pull Request Workflow: `.github/workflows/pr.yml` ```yaml name: PR Validation on: pull_request: types: [opened, synchronize, reopened] jobs: # PR Title Validation pr-title: runs-on: ubuntu-latest steps: - name: Check PR title uses: amannn/action-semantic-pull-request@v5 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: types: | feat fix docs style refactor perf test build ci chore revert # Size Check size-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Check bundle size uses: andresz1/size-limit-action@v1 with: github_token: ${{ secrets.GITHUB_TOKEN }} skip_step: install script: npm run size # Preview Deployment preview: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Deploy Preview uses: amondnet/vercel-action@v20 with: vercel-token: ${{ secrets.VERCEL_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }} vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} ``` ## Continuous Deployment ### Release Workflow: `.github/workflows/release.yml` ```yaml name: Release Pipeline on: push: branches: [main] workflow_dispatch: inputs: release-type: description: 'Release type' required: true default: 'patch' type: choice options: - patch - minor - major permissions: contents: write packages: write id-token: write jobs: release: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} registry-url: 'https://registry.npmjs.org' - name: Install dependencies run: npm ci - name: Build run: npm run build - name: Determine version id: version run: | if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then npm version ${{ github.event.inputs.release-type }} --no-git-tag-version else npm run semantic-release --dry-run fi echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT - name: Create Release uses: semantic-release/semantic-release@v21 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} docker: needs: release runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to GHCR uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Log in to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} ${{ secrets.DOCKERHUB_USERNAME }}/conduit tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{major}} type=sha - name: Build and push uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max deploy-production: needs: [release, docker] runs-on: ubuntu-latest environment: production steps: - name: Deploy to Production run: | # Deployment logic here echo "Deploying version ${{ needs.release.outputs.version }} to production" ``` ## NPM Publishing Strategy ### Automated NPM Publishing 1. **Version Management**: - Use [semantic-release](https://github.com/semantic-release/semantic-release) for automated versioning - Follow [Conventional Commits](https://www.conventionalcommits.org/) specification - Automatic CHANGELOG generation 2. **Publishing Configuration**: `.releaserc.json` ```json { "branches": ["main"], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", "@semantic-release/npm", [ "@semantic-release/git", { "assets": ["package.json", "package-lock.json", "CHANGELOG.md"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" } ], "@semantic-release/github" ] } ``` 3. **NPM Configuration**: `.npmrc` ```ini //registry.npmjs.org/:_authToken=${NPM_TOKEN} @tehreet:registry=https://registry.npmjs.org/ access=public save-exact=true engine-strict=true ``` 4. **Pre-publish Checklist**: - Run full test suite - Verify no security vulnerabilities - Check bundle size limits - Validate package contents with `npm pack --dry-run` - Ensure LICENSE file is included ### Beta and Canary Releases ```yaml # .github/workflows/canary.yml name: Canary Release on: push: branches: [develop] jobs: canary: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} registry-url: 'https://registry.npmjs.org' - name: Install and Build run: | npm ci npm run build - name: Publish Canary run: | npm version prerelease --preid=canary.$(git rev-parse --short HEAD) --no-git-tag-version npm publish --tag canary env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} ``` ## Docker Registry ### Multi-Registry Strategy 1. **GitHub Container Registry (GHCR)**: - Primary registry for development/staging - Integrated with GitHub permissions - Free for public repositories 2. **Docker Hub**: - Public distribution - Better global CDN - Community visibility 3. **Image Tagging Strategy**: - `latest`: Latest stable release - `v1.2.3`: Specific version - `v1.2`: Minor version (auto-updates patch) - `v1`: Major version (auto-updates minor/patch) - `canary`: Latest development build - `sha-abc1234`: Commit-specific builds ## Security & Compliance ### Security Scanning Pipeline ```yaml # .github/workflows/security.yml name: Security Audit on: schedule: - cron: '0 0 * * *' # Daily at midnight push: branches: [main, develop] jobs: audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run npm audit run: npm audit --production - 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 results uses: github/codeql-action/upload-sarif@v2 with: sarif_file: 'trivy-results.sarif' dependency-review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/dependency-review-action@v3 with: fail-on-severity: moderate ``` ### Secrets Management 1. **GitHub Secrets Required**: - `NPM_TOKEN`: NPM authentication token - `DOCKERHUB_USERNAME`: Docker Hub username - `DOCKERHUB_TOKEN`: Docker Hub access token - `SNYK_TOKEN`: Snyk authentication token - `SONAR_TOKEN`: SonarCloud token - `CODECOV_TOKEN`: Codecov token - `VERCEL_TOKEN`: Vercel deployment token 2. **Secret Rotation**: - Rotate all tokens every 90 days - Use GitHub's secret scanning - Implement least privilege principle ## Monitoring & Alerts ### CI/CD Metrics 1. **Key Metrics to Track**: - Build success rate - Average build time - Test pass rate - Deployment frequency - Mean time to recovery (MTTR) - Change failure rate 2. **Alerting Rules**: - Failed builds on main branch - Security vulnerabilities (high/critical) - Performance regression >10% - Bundle size increase >5% - Test coverage drop >2% 3. **Dashboard Configuration**: ```yaml # datadog-dashboard.yaml widgets: - title: "CI/CD Pipeline Health" type: "timeseries" requests: - q: "avg:github.actions.workflow.run.duration{workflow:ci-pipeline}" - title: "Deployment Success Rate" type: "query_value" requests: - q: "sum:deployments.success{env:production}.as_rate()" - title: "NPM Downloads" type: "timeseries" requests: - q: "sum:npm.downloads{package:@tehreet/conduit}" ``` ## Implementation Roadmap ### Phase 1: Foundation (Week 1-2) - [ ] Set up GitHub Actions workflows - [ ] Configure branch protection rules - [ ] Implement basic CI pipeline (lint, test, build) - [ ] Set up Codecov and SonarCloud ### Phase 2: Security & Quality (Week 3-4) - [ ] Integrate Snyk security scanning - [ ] Add dependency vulnerability checks - [ ] Implement bundle size monitoring - [ ] Set up license compliance checks ### Phase 3: Automated Releases (Week 5-6) - [ ] Configure semantic-release - [ ] Set up NPM publishing automation - [ ] Implement Docker multi-arch builds - [ ] Create canary release pipeline ### Phase 4: Advanced Features (Week 7-8) - [ ] Add E2E testing with Playwright - [ ] Implement load testing with Artillery - [ ] Set up preview deployments - [ ] Create rollback mechanisms ### Phase 5: Monitoring & Optimization (Week 9-10) - [ ] Configure Datadog monitoring - [ ] Create CI/CD dashboards - [ ] Implement performance budgets - [ ] Optimize pipeline performance ## Best Practices 1. **Keep Pipelines Fast**: - Parallelize independent jobs - Use caching effectively - Optimize Docker layer caching - Run only affected tests 2. **Maintain High Visibility**: - Use status badges in README - Send notifications to Slack/Discord - Create detailed deployment logs - Maintain audit trails 3. **Ensure Reproducibility**: - Pin all dependency versions - Use deterministic builds - Archive all artifacts - Tag all Docker images 4. **Practice Continuous Improvement**: - Regular pipeline reviews - Monitor and optimize costs - Update dependencies monthly - Conduct security audits quarterly ## Conclusion This CI/CD strategy provides a robust foundation for Conduit's development and deployment processes. By implementing these pipelines, we ensure code quality, automate repetitive tasks, and maintain a secure and reliable release process. Regular reviews and updates of this strategy will help us adapt to changing requirements and emerging best practices.