Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ChatPDF Environment Variables
# Copy this file to .env.local and fill in your actual values

# Cohere API Configuration
COHERE_API_KEY=your_cohere_api_key_here

# Supabase Database Configuration
SUPABASE_URL=your_supabase_url_here
SUPABASE_KEY=your_supabase_anon_key_here

# JWT Authentication
JWT_SECRET=your_jwt_secret_here

# Server Configuration
PORT=3000

# Clerk Authentication (optional)
CLERK_SECRET_KEY=your_clerk_secret_key_here
142 changes: 142 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
name: CI/CD Pipeline

on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]

jobs:
test:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.x, 20.x]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest

- name: Cache dependencies
uses: actions/cache@v3
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Lint code
run: bun run lint:check

- name: Run tests
run: bun test
env:
NODE_ENV: test
JWT_SECRET: test-secret-key-for-ci

- name: Check build
run: |
timeout 10s bun start &
sleep 5
curl -f http://localhost:3000/z || exit 1

security:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Run security audit
run: |
npm audit --audit-level high

- name: Run Snyk security scan
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

docker:
needs: [test, security]
runs-on: ubuntu-latest
if: 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: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
chatpdf/api:latest
chatpdf/api:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max

deploy-staging:
needs: [docker]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/develop'
environment: staging

steps:
- name: Deploy to staging
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.STAGING_HOST }}
username: ${{ secrets.STAGING_USERNAME }}
key: ${{ secrets.STAGING_SSH_KEY }}
script: |
cd /opt/chatpdf
docker-compose pull
docker-compose up -d
sleep 10
curl -f http://localhost:3000/z

deploy-production:
needs: [docker]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
environment: production

steps:
- name: Deploy to production
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.PRODUCTION_HOST }}
username: ${{ secrets.PRODUCTION_USERNAME }}
key: ${{ secrets.PRODUCTION_SSH_KEY }}
script: |
cd /opt/chatpdf
docker-compose pull
docker-compose up -d --no-deps chatpdf
sleep 15
curl -f http://localhost:3000/z

- name: Notify deployment
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
channel: '#deployments'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
if: always()
38 changes: 38 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
FROM oven/bun:1-alpine AS base

# Set working directory
WORKDIR /app

# Create non-root user for security
RUN addgroup -g 1001 -S nodejs && \
adduser -S chatpdf -u 1001

# Copy package files
COPY package.json bun.lock* ./

# Install dependencies
RUN bun install --frozen-lockfile --production && \
rm -rf /root/.bun/cache

# Copy source code
COPY --chown=chatpdf:nodejs . .

# Remove development files
RUN rm -rf .git .github tests *.md docs/DEVELOPMENT.md

# Switch to non-root user
USER chatpdf

# Expose the application port
EXPOSE 3000

# Add health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/z || exit 1

# Set environment variables
ENV NODE_ENV=production
ENV PORT=3000

# Start the application
CMD ["bun", "start"]
Loading