From 151a6d9f5d699d6332a2105feeb1db15aaeae553 Mon Sep 17 00:00:00 2001 From: 0xprathamesh Date: Sun, 15 Mar 2026 15:19:48 +0530 Subject: [PATCH] feat:ci-cd --- .dockerignore | 10 +++++ .github/workflows/ci.yml | 89 ++++++++++++++++++++++++++++++++++++++++ Dockerfile | 36 ++++++++++++++++ docker-compose.yml | 69 +++++++++++++++++++++++++++++++ 4 files changed, 204 insertions(+) create mode 100644 .dockerignore create mode 100644 .github/workflows/ci.yml create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..bd27f12 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +node_modules +dist +.env +.env.* +.git +.github +.cursor +coverage +npm-debug.log* +yarn-error.log* diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e9b4c40 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,89 @@ +name: CI + +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + NODE_VERSION: "20" + +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - name: Checkout + 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: Prisma generate + run: npx prisma generate + env: + DATABASE_URL: "postgresql://placeholder:placeholder@localhost:5432/placeholder?schema=public" + + - name: Build + run: npm run build + + - name: Run tests + run: npm test + continue-on-error: true + + docker: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: false + tags: agent-execution-engine:ci + cache-from: type=gha + cache-to: type=gha,mode=max + + # Only on push to main/master (never on PR). Concurrency ensures one run per branch/PR. + docker-push: + runs-on: ubuntu-latest + needs: [build-and-test] + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: | + ${{ secrets.DOCKERHUB_USERNAME }}/agent-execution-engine:latest + ${{ secrets.DOCKERHUB_USERNAME }}/agent-execution-engine:sha-${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f868a9a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +# syntax=docker/dockerfile:1.7 + +FROM node:20-alpine AS builder + +WORKDIR /app + +COPY package*.json ./ +RUN npm ci + +COPY tsconfig.json prisma.config.ts ./ +COPY prisma ./prisma +COPY src ./src + +RUN npx prisma generate +RUN npm run build +RUN npm prune --omit=dev + +FROM node:20-alpine AS production + +WORKDIR /app + +RUN apk add --no-cache dumb-init wget + +ENV NODE_ENV=production + +COPY --from=builder --chown=node:node /app/package*.json ./ +COPY --from=builder --chown=node:node /app/node_modules ./node_modules +COPY --from=builder --chown=node:node /app/dist ./dist +COPY --from=builder --chown=node:node /app/prisma ./prisma + +USER node + +EXPOSE 3000 + +ENTRYPOINT ["dumb-init", "--"] +CMD ["node", "dist/server.js"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9bcdf6e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,69 @@ +version: "3.9" + +services: + api: + build: + context: . + target: production + image: agent-execution-engine:latest + env_file: + - .env + command: ["node", "dist/server.js"] + ports: + - "${PORT}:${PORT}" + healthcheck: + test: + [ + "CMD-SHELL", + "wget -qO- http://127.0.0.1:${PORT}/health >/dev/null || exit 1", + ] + interval: 15s + timeout: 5s + retries: 5 + start_period: 20s + restart: unless-stopped + init: true + read_only: true + tmpfs: + - /tmp + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + ulimits: + nofile: + soft: 65536 + hard: 65536 + logging: + options: + max-size: "10m" + max-file: "3" + networks: + - app_net + + worker: + image: agent-execution-engine:latest + depends_on: + - api + env_file: + - .env + command: ["node", "dist/worker.js"] + restart: unless-stopped + init: true + read_only: true + tmpfs: + - /tmp + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + logging: + options: + max-size: "10m" + max-file: "3" + networks: + - app_net + +networks: + app_net: + driver: bridge