From d2a997f47dbe836ce3d8c4ede20e2ff9e6dbf92a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Sep 2025 01:23:17 -0300 Subject: [PATCH 01/21] configs --- .dockerignore | 9 ++++++ .github/workflows/cicd.yml | 60 ++++++++++++++++++++++++++++++++++++++ Dockerfile | 30 +++++++++++++++++++ docker-compose.yml | 11 +++++++ src/main.ts | 19 ++++++++++++ 5 files changed, 129 insertions(+) create mode 100644 .dockerignore create mode 100644 .github/workflows/cicd.yml create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..aebcb97 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +node_modules +dist +.git +.gitignore +Dockerfile* +docker-compose*.yml +npm-debug.log +.env +README.md diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml new file mode 100644 index 0000000..faf3c2b --- /dev/null +++ b/.github/workflows/cicd.yml @@ -0,0 +1,60 @@ +name: CI/CD – exdev-apply-api + +on: + push: + branches: ["master"] # cámbialo si despliegas otra rama + workflow_dispatch: {} # permite correrlo manualmente + +permissions: + contents: read + packages: write + +concurrency: + group: deploy-${{ github.ref_name }} + cancel-in-progress: true + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build & Push image + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ghcr.io/${{ github.repository }}:latest + + - name: Deploy over SSH + uses: appleboy/ssh-action@v1.2.0 + with: + host: ${{ secrets.SSH_HOST }} # ej: 18.231.166.7 + username: ${{ secrets.SSH_USER }} # ej: ubuntu o ec2-user + key: ${{ secrets.SSH_PRIVATE_KEY }} # llave privada que creaste + port: ${{ secrets.SSH_PORT || 22 }} + script: | + set -e + if [ ! -d /opt/exdev-apply-api ]; then + mkdir -p /opt/exdev-apply-api + cd /opt/exdev-apply-api + git clone https://github.com/${{ github.repository }} . + else + cd /opt/exdev-apply-api + git fetch --all + git checkout -B ${{ github.ref_name }} origin/${{ github.ref_name }} + fi + + docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} + docker compose -f docker-compose.yml pull + docker compose -f docker-compose.yml up -d --remove-orphans + docker image prune -f diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..bab0eff --- /dev/null +++ b/Dockerfile @@ -0,0 +1,30 @@ +# ---------- Dep stage ---------- +FROM node:24-alpine AS deps +WORKDIR /app +COPY package*.json ./ +RUN npm ci + +# ---------- Build stage ---------- +FROM node:24-alpine AS build +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . +# Si usas nest-cli.json/tsconfig*.json, se copian arriba con "COPY . ." +RUN npm run build + +# ---------- Prod deps (solo prod) ---------- +FROM node:24-alpine AS prod-deps +WORKDIR /app +COPY package*.json ./ +RUN npm ci --omit=dev + +# ---------- Runner ---------- +FROM node:24-alpine AS runner +WORKDIR /app +ENV NODE_ENV=production +COPY --from=prod-deps /app/node_modules ./node_modules +COPY --from=build /app/dist ./dist + + +EXPOSE 3000 +CMD ["node", "dist/main.js"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d05d3be --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3.9" + +services: + exdev-apply-api: + image: ghcr.io//:latest + container_name: exdev-apply-api + restart: unless-stopped + ports: + - "3001:3000" + env_file: + - /opt/exdev-apply-api/.env \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index f8d5795..8f81f73 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,27 @@ import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; +import { ValidationPipe } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create(AppModule); + const WEB_ORIGINS = [ + 'https://exdev.cl', + 'http://localhost:5000', + 'http://localhost:3000' + ]; + + app.enableCors({ + origin: (origin, cb) => { + // permite herramientas como Postman (sin origin) + if (!origin) return cb(null, true); + cb(null, WEB_ORIGINS.includes(origin)); + }, + methods: ['GET','POST'], + allowedHeaders: ['Content-Type','Authorization'], + credentials: false, + optionsSuccessStatus: 204, + }); + await app.listen(process.env.PORT ? Number(process.env.PORT) : 3000); } bootstrap(); From 3002eb1dfdc969e0a1884438931ba5c20ffaa293 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Sep 2025 01:57:59 -0300 Subject: [PATCH 02/21] yml --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index d05d3be..be529d1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.9" services: exdev-apply-api: - image: ghcr.io//:latest + image: ghcr.io/ianbattistoni/exdev-apply-api:latest container_name: exdev-apply-api restart: unless-stopped ports: From 0bd4eb3974cf0013266a718ad5a1f6e8b223bce3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Sep 2025 02:09:00 -0300 Subject: [PATCH 03/21] test --- .github/workflows/cicd.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index faf3c2b..b2b7fcc 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -58,3 +58,5 @@ jobs: docker compose -f docker-compose.yml pull docker compose -f docker-compose.yml up -d --remove-orphans docker image prune -f + + \ No newline at end of file From ab554ef09afcee50bc5be4f381e76c37e833f5fc Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Sep 2025 02:09:48 -0300 Subject: [PATCH 04/21] test2 --- .github/workflows/cicd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index b2b7fcc..6a27550 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -59,4 +59,4 @@ jobs: docker compose -f docker-compose.yml up -d --remove-orphans docker image prune -f - \ No newline at end of file + From ab8f48eab191b033722da29072967e93b49d378e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Sep 2025 02:16:07 -0300 Subject: [PATCH 05/21] ajustes --- .github/workflows/cicd.yml | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 6a27550..a4392fc 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -2,6 +2,8 @@ name: CI/CD – exdev-apply-api on: push: + branches: ["master"] + pull_request: branches: ["master"] # cámbialo si despliegas otra rama workflow_dispatch: {} # permite correrlo manualmente @@ -16,10 +18,8 @@ concurrency: jobs: build-and-deploy: runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - name: Log in to GHCR uses: docker/login-action@v3 @@ -28,26 +28,37 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Compute tag + id: meta + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + echo "TAG=pr-${{ github.event.number }}" >> $GITHUB_OUTPUT + else + echo "TAG=latest" >> $GITHUB_OUTPUT + fi + - name: Build & Push image uses: docker/build-push-action@v6 with: context: . push: true - tags: ghcr.io/${{ github.repository }}:latest + tags: ghcr.io/${{ github.repository }}:${{ steps.meta.outputs.TAG }} - name: Deploy over SSH + # evita forks (no hay secrets) + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false) uses: appleboy/ssh-action@v1.2.0 with: - host: ${{ secrets.SSH_HOST }} # ej: 18.231.166.7 - username: ${{ secrets.SSH_USER }} # ej: ubuntu o ec2-user - key: ${{ secrets.SSH_PRIVATE_KEY }} # llave privada que creaste + host: ${{ secrets.SSH_HOST }} + username: ${{ secrets.SSH_USER }} + key: ${{ secrets.SSH_PRIVATE_KEY }} port: ${{ secrets.SSH_PORT || 22 }} script: | set -e if [ ! -d /opt/exdev-apply-api ]; then mkdir -p /opt/exdev-apply-api cd /opt/exdev-apply-api - git clone https://github.com/${{ github.repository }} . + git clone https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} . else cd /opt/exdev-apply-api git fetch --all @@ -55,8 +66,15 @@ jobs: fi docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} + + # Define la imagen a usar según el evento: + if [ "${{ github.event_name }}" = "pull_request" ]; then + export IMAGE=ghcr.io/${{ github.repository }}:pr-${{ github.event.number }} + else + export IMAGE=ghcr.io/${{ github.repository }}:latest + fi + docker compose -f docker-compose.yml pull docker compose -f docker-compose.yml up -d --remove-orphans docker image prune -f - From 0dff5356ba80c7e41fd527e3807f31372ab536c2 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Sep 2025 02:22:59 -0300 Subject: [PATCH 06/21] ajustes2 --- .github/workflows/cicd.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index a4392fc..4aa3344 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -42,7 +42,9 @@ jobs: with: context: . push: true - tags: ghcr.io/${{ github.repository }}:${{ steps.meta.outputs.TAG }} + tags: | + ghcr.io/${{ github.repository }}:latest + ghcr.io/${{ github.repository }}:pr-${{ github.event_number }} - name: Deploy over SSH # evita forks (no hay secrets) From 4c7d8336ad39fd2bb6f6cea15e9e91e270d4b9c9 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Sep 2025 02:30:08 -0300 Subject: [PATCH 07/21] ajustes3 --- .github/workflows/cicd.yml | 34 +++++----------------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 4aa3344..19b82df 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -3,8 +3,6 @@ name: CI/CD – exdev-apply-api on: push: branches: ["master"] - pull_request: - branches: ["master"] # cámbialo si despliegas otra rama workflow_dispatch: {} # permite correrlo manualmente permissions: @@ -28,27 +26,14 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Compute tag - id: meta - run: | - if [ "${{ github.event_name }}" = "pull_request" ]; then - echo "TAG=pr-${{ github.event.number }}" >> $GITHUB_OUTPUT - else - echo "TAG=latest" >> $GITHUB_OUTPUT - fi - - - name: Build & Push image + - name: Build & Push image (:latest) uses: docker/build-push-action@v6 with: context: . push: true - tags: | - ghcr.io/${{ github.repository }}:latest - ghcr.io/${{ github.repository }}:pr-${{ github.event_number }} + tags: ghcr.io/ianbattistoni/exdev-apply-api:latest # todo en minúsculas - name: Deploy over SSH - # evita forks (no hay secrets) - if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false) uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.SSH_HOST }} @@ -60,23 +45,14 @@ jobs: if [ ! -d /opt/exdev-apply-api ]; then mkdir -p /opt/exdev-apply-api cd /opt/exdev-apply-api - git clone https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} . + git clone https://github.com/IanBattistoni/exdev-apply-api . else cd /opt/exdev-apply-api git fetch --all - git checkout -B ${{ github.ref_name }} origin/${{ github.ref_name }} + git checkout -B master origin/master fi docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} - - # Define la imagen a usar según el evento: - if [ "${{ github.event_name }}" = "pull_request" ]; then - export IMAGE=ghcr.io/${{ github.repository }}:pr-${{ github.event.number }} - else - export IMAGE=ghcr.io/${{ github.repository }}:latest - fi - docker compose -f docker-compose.yml pull docker compose -f docker-compose.yml up -d --remove-orphans - docker image prune -f - + docker image prune -f \ No newline at end of file From d24b3af2ef3f3a2a856597103836b799a6e5f7b4 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 30 Sep 2025 23:40:21 -0300 Subject: [PATCH 08/21] prueba --- docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index be529d1..8200a7b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,4 +8,5 @@ services: ports: - "3001:3000" env_file: - - /opt/exdev-apply-api/.env \ No newline at end of file + - /opt/exdev-apply-api/.env + \ No newline at end of file From a4d0e9e75dd91c6357b8b7dd7c7717a517b0fbb5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 30 Sep 2025 23:52:00 -0300 Subject: [PATCH 09/21] fix: cicd --- .github/workflows/cicd.yml | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 19b82df..2fd8e12 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -33,7 +33,7 @@ jobs: push: true tags: ghcr.io/ianbattistoni/exdev-apply-api:latest # todo en minúsculas - - name: Deploy over SSH + - name: Deploy over SSH (only master) uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.SSH_HOST }} @@ -42,17 +42,21 @@ jobs: port: ${{ secrets.SSH_PORT || 22 }} script: | set -e - if [ ! -d /opt/exdev-apply-api ]; then - mkdir -p /opt/exdev-apply-api - cd /opt/exdev-apply-api - git clone https://github.com/IanBattistoni/exdev-apply-api . + APP_DIR=/opt/exdev-apply-api + REPO=IanBattistoni/exdev-apply-api + + + if [ ! -d "$APP_DIR/.git" ]; then + rm -rf "$APP_DIR" + mkdir -p "$APP_DIR" + git clone https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$REPO "$APP_DIR" else - cd /opt/exdev-apply-api - git fetch --all - git checkout -B master origin/master + git -C "$APP_DIR" fetch --all + git -C "$APP_DIR" checkout -B master origin/master fi + docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} - docker compose -f docker-compose.yml pull - docker compose -f docker-compose.yml up -d --remove-orphans + docker compose -f "$APP_DIR/docker-compose.yml" pull + docker compose -f "$APP_DIR/docker-compose.yml" up -d --remove-orphans docker image prune -f \ No newline at end of file From 10e417b5857e53ce95343927007afe2781b556de Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 30 Sep 2025 23:59:35 -0300 Subject: [PATCH 10/21] fix: cicd2 --- .github/workflows/cicd.yml | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 2fd8e12..022f860 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -44,18 +44,26 @@ jobs: set -e APP_DIR=/opt/exdev-apply-api REPO=IanBattistoni/exdev-apply-api + SHA=${{ github.sha }} + + # Asegura permisos correctos (por si alguna vez vuelve a quedar con root) + sudo mkdir -p "$APP_DIR" + sudo chown -R $USER:$USER "$APP_DIR" - if [ ! -d "$APP_DIR/.git" ]; then - rm -rf "$APP_DIR" - mkdir -p "$APP_DIR" - git clone https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$REPO "$APP_DIR" + # Inicializa repo EN ese directorio (no se borra .env) + git -C "$APP_DIR" init + git -C "$APP_DIR" remote add origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$REPO + git -C "$APP_DIR" fetch --depth=1 origin master + git -C "$APP_DIR" checkout -B master origin/master else - git -C "$APP_DIR" fetch --all + git -C "$APP_DIR" fetch --all --depth=1 git -C "$APP_DIR" checkout -B master origin/master fi - + # (Opcional) alinear exactamente al commit que se buildéo + git -C "$APP_DIR" checkout "$SHA" || true + docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} docker compose -f "$APP_DIR/docker-compose.yml" pull docker compose -f "$APP_DIR/docker-compose.yml" up -d --remove-orphans From 4e6a6aa8a8eff0769b34b33543adffa2ae3ab421 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Oct 2025 00:51:47 -0300 Subject: [PATCH 11/21] fix: db --- docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 8200a7b..d6ecdab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,4 +9,5 @@ services: - "3001:3000" env_file: - /opt/exdev-apply-api/.env - \ No newline at end of file + extra_hosts: + - "host.docker.internal:host-gateway" \ No newline at end of file From d0dcf6f72da8e3c018556ead1e72201df94fca2d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Oct 2025 01:05:04 -0300 Subject: [PATCH 12/21] get postulaciones --- src/applications/applications.controller.ts | 4 ++ src/applications/applications.service.ts | 47 +++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/applications/applications.controller.ts b/src/applications/applications.controller.ts index c786f69..1623ca3 100644 --- a/src/applications/applications.controller.ts +++ b/src/applications/applications.controller.ts @@ -9,4 +9,8 @@ export class ApplicationsController { create(@Body() body: any){ return this.applicationsService.create(body); } + @Get() + findAll() { + return this.applicationsService.findAll(); + } } diff --git a/src/applications/applications.service.ts b/src/applications/applications.service.ts index e012969..58aa6ca 100644 --- a/src/applications/applications.service.ts +++ b/src/applications/applications.service.ts @@ -69,4 +69,51 @@ async create(body: any){ } } + async findAll() { + const countSql = `SELECT COUNT(*)::int AS total FROM postulaciones;`; + + const listSql = ` + SELECT + id, + nombre_completo, + rut, + edad, + correo_institucional, + campus, + carrera, + anio_ingreso, + anio_actual, + area_interes1, + area_interes2, + area_interes3, + ayudantias, + horas_disponibles_semanales, + motivo_postulacion, + proyecto_idea, + portafolio, + postulacion_conjunta, + pitch, + apodo, + created_at, + updated_at + FROM postulaciones + ORDER BY created_at DESC; + `; + + try { + const [countRes, listRes] = await Promise.all([ + this.pool.query(countSql), + this.pool.query(listSql), + ]); + + return { + totalPostulaciones: countRes.rows[0].total as number, + postulaciones: listRes.rows, + }; + } catch (err: any) { + const { status, body } = buildErrorExceptionPayload(err); + throw new HttpException(body, status, { cause: err }); + } + } + } From f6dd999d0cf12b1cbaad66ca739d01f037cd180c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Nov 2025 18:39:41 -0300 Subject: [PATCH 13/21] add url cors --- src/main.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 8f81f73..020d338 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,7 +7,8 @@ async function bootstrap() { const WEB_ORIGINS = [ 'https://exdev.cl', 'http://localhost:5000', - 'http://localhost:3000' + 'http://localhost:3000', + 'https://tomas.exdev.cl' ]; app.enableCors({ From fa4b7ae9bd334b0e7cddbc71a6799ccd93b85d1d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Nov 2025 22:35:26 -0300 Subject: [PATCH 14/21] fix cache get --- src/main.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main.ts b/src/main.ts index 020d338..32b362f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -4,16 +4,28 @@ import { ValidationPipe } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create(AppModule); + + //desactivar cache + const expressApp = app.getHttpAdapter().getInstance(); + expressApp.set('etag', false); + const WEB_ORIGINS = [ 'https://exdev.cl', + 'https://www.exdev.cl', 'http://localhost:5000', 'http://localhost:3000', - 'https://tomas.exdev.cl' + 'https://tomas.exdev.cl', + 'https://www.tomas.exdev.cl' ]; - + app.use((req, res, next) => { + res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate'); + res.setHeader('Pragma', 'no-cache'); + res.setHeader('Expires', '0'); + next(); + }); app.enableCors({ origin: (origin, cb) => { - // permite herramientas como Postman (sin origin) + if (!origin) return cb(null, true); cb(null, WEB_ORIGINS.includes(origin)); }, From 875e545609d9a75342c2df815d17807e80769990 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Nov 2025 00:27:54 -0300 Subject: [PATCH 15/21] fix methods main --- src/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 32b362f..b08510b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -29,7 +29,7 @@ async function bootstrap() { if (!origin) return cb(null, true); cb(null, WEB_ORIGINS.includes(origin)); }, - methods: ['GET','POST'], + methods: ['GET','POST','OPTIONS'], allowedHeaders: ['Content-Type','Authorization'], credentials: false, optionsSuccessStatus: 204, From 4771473119640de28e4ad30bd04db39db0c39805 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Sep 2026 01:17:51 -0300 Subject: [PATCH 16/21] migracion --- .env.example | 7 +++++++ .github/workflows/cicd.yml | 21 +++++++++++---------- docker-compose.yml | 10 +++++----- 3 files changed, 23 insertions(+), 15 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..f569e51 --- /dev/null +++ b/.env.example @@ -0,0 +1,7 @@ +# Copy this file to .env locally or to the server as /opt/exdev-api/.env. +# Never commit real credentials. +NODE_ENV=development +PORT=3001 +# For local `npm run start:dev`, use 127.0.0.1 or localhost. +# For Docker Compose on the VM, use host.docker.internal and PostgreSQL's VM port. +DATABASE_URL=postgresql://exdev_website:CHANGE_ME@127.0.0.1:5432/exdev_staging_db diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 022f860..1920df6 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -1,8 +1,8 @@ -name: CI/CD – exdev-apply-api +name: CI/CD – exdev-api on: push: - branches: ["master"] + branches: ["develop"] workflow_dispatch: {} # permite correrlo manualmente permissions: @@ -16,6 +16,7 @@ concurrency: jobs: build-and-deploy: runs-on: ubuntu-latest + environment: staging steps: - uses: actions/checkout@v4 @@ -31,9 +32,9 @@ jobs: with: context: . push: true - tags: ghcr.io/ianbattistoni/exdev-apply-api:latest # todo en minúsculas + tags: ghcr.io/exdevutem/exdev-api:latest - - name: Deploy over SSH (only master) + - name: Deploy over SSH (staging/develop) uses: appleboy/ssh-action@v1.2.0 with: host: ${{ secrets.SSH_HOST }} @@ -42,8 +43,8 @@ jobs: port: ${{ secrets.SSH_PORT || 22 }} script: | set -e - APP_DIR=/opt/exdev-apply-api - REPO=IanBattistoni/exdev-apply-api + APP_DIR=/opt/exdev-api + REPO=exdevutem/exdev-api SHA=${{ github.sha }} # Asegura permisos correctos (por si alguna vez vuelve a quedar con root) @@ -54,11 +55,11 @@ jobs: # Inicializa repo EN ese directorio (no se borra .env) git -C "$APP_DIR" init git -C "$APP_DIR" remote add origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$REPO - git -C "$APP_DIR" fetch --depth=1 origin master - git -C "$APP_DIR" checkout -B master origin/master + git -C "$APP_DIR" fetch --depth=1 origin develop + git -C "$APP_DIR" checkout -B develop origin/develop else git -C "$APP_DIR" fetch --all --depth=1 - git -C "$APP_DIR" checkout -B master origin/master + git -C "$APP_DIR" checkout -B develop origin/develop fi # (Opcional) alinear exactamente al commit que se buildéo @@ -67,4 +68,4 @@ jobs: docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} docker compose -f "$APP_DIR/docker-compose.yml" pull docker compose -f "$APP_DIR/docker-compose.yml" up -d --remove-orphans - docker image prune -f \ No newline at end of file + docker image prune -f diff --git a/docker-compose.yml b/docker-compose.yml index d6ecdab..cac29d6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,13 @@ version: "3.9" services: - exdev-apply-api: - image: ghcr.io/ianbattistoni/exdev-apply-api:latest - container_name: exdev-apply-api + exdev-api: + image: ghcr.io/exdevutem/exdev-api:latest + container_name: exdev-api restart: unless-stopped ports: - "3001:3000" env_file: - - /opt/exdev-apply-api/.env + - /opt/exdev-api/.env extra_hosts: - - "host.docker.internal:host-gateway" \ No newline at end of file + - "host.docker.internal:host-gateway" From 721641c91a6c43559cb415c4b647d5286259f115 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Sep 2026 01:28:15 -0300 Subject: [PATCH 17/21] fixx --- .github/workflows/cicd.yml | 54 +++++++++++++------------------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 1920df6..b628a71 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -14,9 +14,8 @@ concurrency: cancel-in-progress: true jobs: - build-and-deploy: + build-and-push: runs-on: ubuntu-latest - environment: staging steps: - uses: actions/checkout@v4 @@ -34,38 +33,21 @@ jobs: push: true tags: ghcr.io/exdevutem/exdev-api:latest - - name: Deploy over SSH (staging/develop) - uses: appleboy/ssh-action@v1.2.0 - with: - host: ${{ secrets.SSH_HOST }} - username: ${{ secrets.SSH_USER }} - key: ${{ secrets.SSH_PRIVATE_KEY }} - port: ${{ secrets.SSH_PORT || 22 }} - script: | - set -e - APP_DIR=/opt/exdev-api - REPO=exdevutem/exdev-api - SHA=${{ github.sha }} - - # Asegura permisos correctos (por si alguna vez vuelve a quedar con root) - sudo mkdir -p "$APP_DIR" - sudo chown -R $USER:$USER "$APP_DIR" - - if [ ! -d "$APP_DIR/.git" ]; then - # Inicializa repo EN ese directorio (no se borra .env) - git -C "$APP_DIR" init - git -C "$APP_DIR" remote add origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$REPO - git -C "$APP_DIR" fetch --depth=1 origin develop - git -C "$APP_DIR" checkout -B develop origin/develop - else - git -C "$APP_DIR" fetch --all --depth=1 - git -C "$APP_DIR" checkout -B develop origin/develop - fi - - # (Opcional) alinear exactamente al commit que se buildéo - git -C "$APP_DIR" checkout "$SHA" || true + deploy-staging: + needs: build-and-push + runs-on: self-hosted + environment: staging + steps: + - uses: actions/checkout@v4 - docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} - docker compose -f "$APP_DIR/docker-compose.yml" pull - docker compose -f "$APP_DIR/docker-compose.yml" up -d --remove-orphans - docker image prune -f + - name: Deploy locally on staging runner + shell: bash + run: | + set -euo pipefail + APP_DIR=/opt/exdev-api + mkdir -p "$APP_DIR" + cp docker-compose.yml "$APP_DIR/docker-compose.yml" + docker login ghcr.io -u "${{ github.actor }}" -p "${{ secrets.GITHUB_TOKEN }}" + docker compose -f "$APP_DIR/docker-compose.yml" pull + docker compose -f "$APP_DIR/docker-compose.yml" up -d --remove-orphans + docker image prune -f From 5971602489e06216c99b28eb4d62a6797beb6962 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Sep 2026 02:01:18 -0300 Subject: [PATCH 18/21] add reviewers --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..b1e79bc --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @IanBattistoni @Im-Fran From a8e47a2b877e993d209087d3c83dfe8706d55287 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 18 Sep 2026 12:14:36 -0300 Subject: [PATCH 19/21] add url dev --- src/main.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.ts b/src/main.ts index b08510b..ea97106 100644 --- a/src/main.ts +++ b/src/main.ts @@ -10,6 +10,7 @@ async function bootstrap() { expressApp.set('etag', false); const WEB_ORIGINS = [ + 'https://dev.exdev.cl', 'https://exdev.cl', 'https://www.exdev.cl', 'http://localhost:5000', @@ -38,3 +39,4 @@ async function bootstrap() { await app.listen(process.env.PORT ? Number(process.env.PORT) : 3000); } bootstrap(); + From ad51070f98a4c53088550b5165c0e9c51b459111 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 18 Sep 2026 22:15:34 -0300 Subject: [PATCH 20/21] config env prod --- .github/workflows/cicd.yml | 49 ++++++++++++++++++++++++++++++++------ docker-compose.yml | 3 ++- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index b628a71..b474b74 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -2,8 +2,8 @@ name: CI/CD – exdev-api on: push: - branches: ["develop"] - workflow_dispatch: {} # permite correrlo manualmente + branches: [develop, master] + workflow_dispatch: {} permissions: contents: read @@ -26,28 +26,63 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build & Push image (:latest) + - name: Build and push image uses: docker/build-push-action@v6 with: context: . push: true - tags: ghcr.io/exdevutem/exdev-api:latest + tags: ghcr.io/exdevutem/exdev-api:${{ github.ref_name }} deploy-staging: + if: github.ref_name == 'develop' needs: build-and-push - runs-on: self-hosted + runs-on: [self-hosted, staging] environment: staging steps: - uses: actions/checkout@v4 - - name: Deploy locally on staging runner + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Deploy staging + shell: bash + run: | + set -euo pipefail + APP_DIR=/opt/exdev-api + mkdir -p "$APP_DIR" + cp docker-compose.yml "$APP_DIR/docker-compose.yml" + export IMAGE_TAG=develop + docker compose -f "$APP_DIR/docker-compose.yml" pull + docker compose -f "$APP_DIR/docker-compose.yml" up -d --remove-orphans + docker image prune -f + + deploy-production: + if: github.ref_name == 'master' + needs: build-and-push + runs-on: [self-hosted, production] + environment: production + steps: + - uses: actions/checkout@v4 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Deploy production shell: bash run: | set -euo pipefail APP_DIR=/opt/exdev-api mkdir -p "$APP_DIR" cp docker-compose.yml "$APP_DIR/docker-compose.yml" - docker login ghcr.io -u "${{ github.actor }}" -p "${{ secrets.GITHUB_TOKEN }}" + export IMAGE_TAG=master docker compose -f "$APP_DIR/docker-compose.yml" pull docker compose -f "$APP_DIR/docker-compose.yml" up -d --remove-orphans docker image prune -f diff --git a/docker-compose.yml b/docker-compose.yml index cac29d6..c8198fd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: "3.9" services: exdev-api: - image: ghcr.io/exdevutem/exdev-api:latest + image: ghcr.io/exdevutem/exdev-api:${IMAGE_TAG:-latest} container_name: exdev-api restart: unless-stopped ports: @@ -11,3 +11,4 @@ services: - /opt/exdev-api/.env extra_hosts: - "host.docker.internal:host-gateway" + From 584635ad8ce5564e1c83435e099ed21ca191ee6f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 18 Sep 2026 22:22:01 -0300 Subject: [PATCH 21/21] fix --- .github/workflows/cicd.yml | 90 +++++++++++++++++++++++++------------- docker-compose.yml | 14 ++++++ 2 files changed, 73 insertions(+), 31 deletions(-) create mode 100644 docker-compose.yml diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index faf3c2b..b474b74 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -1,9 +1,9 @@ -name: CI/CD – exdev-apply-api +name: CI/CD – exdev-api on: push: - branches: ["master"] # cámbialo si despliegas otra rama - workflow_dispatch: {} # permite correrlo manualmente + branches: [develop, master] + workflow_dispatch: {} permissions: contents: read @@ -14,12 +14,10 @@ concurrency: cancel-in-progress: true jobs: - build-and-deploy: + build-and-push: runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - name: Log in to GHCR uses: docker/login-action@v3 @@ -28,33 +26,63 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build & Push image + - name: Build and push image uses: docker/build-push-action@v6 with: context: . push: true - tags: ghcr.io/${{ github.repository }}:latest + tags: ghcr.io/exdevutem/exdev-api:${{ github.ref_name }} + + deploy-staging: + if: github.ref_name == 'develop' + needs: build-and-push + runs-on: [self-hosted, staging] + environment: staging + steps: + - uses: actions/checkout@v4 - - name: Deploy over SSH - uses: appleboy/ssh-action@v1.2.0 + - name: Log in to GHCR + uses: docker/login-action@v3 with: - host: ${{ secrets.SSH_HOST }} # ej: 18.231.166.7 - username: ${{ secrets.SSH_USER }} # ej: ubuntu o ec2-user - key: ${{ secrets.SSH_PRIVATE_KEY }} # llave privada que creaste - port: ${{ secrets.SSH_PORT || 22 }} - script: | - set -e - if [ ! -d /opt/exdev-apply-api ]; then - mkdir -p /opt/exdev-apply-api - cd /opt/exdev-apply-api - git clone https://github.com/${{ github.repository }} . - else - cd /opt/exdev-apply-api - git fetch --all - git checkout -B ${{ github.ref_name }} origin/${{ github.ref_name }} - fi - - docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} - docker compose -f docker-compose.yml pull - docker compose -f docker-compose.yml up -d --remove-orphans - docker image prune -f + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Deploy staging + shell: bash + run: | + set -euo pipefail + APP_DIR=/opt/exdev-api + mkdir -p "$APP_DIR" + cp docker-compose.yml "$APP_DIR/docker-compose.yml" + export IMAGE_TAG=develop + docker compose -f "$APP_DIR/docker-compose.yml" pull + docker compose -f "$APP_DIR/docker-compose.yml" up -d --remove-orphans + docker image prune -f + + deploy-production: + if: github.ref_name == 'master' + needs: build-and-push + runs-on: [self-hosted, production] + environment: production + steps: + - uses: actions/checkout@v4 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Deploy production + shell: bash + run: | + set -euo pipefail + APP_DIR=/opt/exdev-api + mkdir -p "$APP_DIR" + cp docker-compose.yml "$APP_DIR/docker-compose.yml" + export IMAGE_TAG=master + docker compose -f "$APP_DIR/docker-compose.yml" pull + docker compose -f "$APP_DIR/docker-compose.yml" up -d --remove-orphans + docker image prune -f diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c8198fd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.9" + +services: + exdev-api: + image: ghcr.io/exdevutem/exdev-api:${IMAGE_TAG:-latest} + container_name: exdev-api + restart: unless-stopped + ports: + - "3001:3000" + env_file: + - /opt/exdev-api/.env + extra_hosts: + - "host.docker.internal:host-gateway" +