FormFlex CI/CD 파이프라인 — 완전 해설

.github/workflows/depoly.yml · 각 단계가 왜 존재하는지, Puppeteer는 왜 생겼는지, dev와 prod는 어떻게 다른지


📌 먼저 — Puppeteer는 왜 추가됐나?

원래는 없었던 기능입니다

FormFlex의 핵심 기능 중 하나가 "목표 응답 수 달성 시 AI 분석 리포트 자동 이메일 발송" 입니다. 이 기능을 구현하는 방식이 Puppeteer입니다.

  1. 응답자가 설문 제출 → answerSave.js가 응답 저장 후 respondentCount 확인
  2. 임계값 도달 감지 → 응답 수 >= emailReportThreshold이고 emailReportEnabled = true이면 실행
  3. Puppeteer로 Chrome 실행 → Lambda 서버 위에서 headless Chrome을 실행해 /result?id= 페이지를 실제로 렌더링
  4. 페이지를 PDF로 변환 → ApexCharts 차트 포함한 분석 결과 페이지 전체를 A4 PDF로 캡처
  5. Gmail OAuth2로 이메일 발송 → nodemailer + OAuth2로 PDF 첨부해서 설문 소유자에게 이메일 전송

문제: 일반 Chromium은 AWS Lambda에서 실행 불가

일반 Chrome은 GUI 환경이 있는 PC를 가정하고 만들어졌습니다. Lambda는 GUI도 없고, 파일시스템도 읽기 전용이고, 용량 제한도 있어요.

그래서 @sparticuz/chromium 이라는 Lambda 전용으로 압축·최적화된 Chromium 바이너리가 필요합니다.

크기가 ~150MB에 달해서 일반 코드 zip에 넣을 수 없고 (Lambda 250MB 제한), 별도 Lambda Layer 로 올려야 합니다.


// sendPdfReport.js — 핵심 흐름

const chromium = require('@sparticuz/chromium');  // Lambda용 Chrome 엔진

const puppeteer = require('puppeteer-core');       // Chrome 조종 도구

// Lambda 위에서 headless Chrome 실행

browser = await puppeteer.launch({

  executablePath: await chromium.executablePath(), // Layer에서 Chrome 경로 찾기

  args: [...chromium.args, '--disable-dev-shm-usage'],

  headless: chromium.headless,

});

// /result?id=xxx 페이지 접속 → PDF 생성

await page.goto(`${FRONTEND_URL}/result?id=${surveyId}`);

const pdfBuffer = await page.pdf({ format: 'A4', printBackground: true });

Step 0 — Trigger

왜 모든 push에 반응하지 않나?