Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9c5a685
fix: 리뷰 목록이 cursor null을 첫 페이지로 처리
chanwoo7 Oct 4, 2026
77976b5
Merge pull request #487 from CaQuick/fix/review-cursor-null
chanwoo7 Oct 4, 2026
6856e76
fix: 커스텀 템플릿 mutation 응답에서 삭제된 슬롯 제외
chanwoo7 Oct 4, 2026
891d758
feat: 관리자 배너에 링크 대상 노출 가능 여부(linkTargetAvailable) 추가
chanwoo7 Oct 4, 2026
7bece88
Merge pull request #488 from CaQuick/fix/custom-template-deleted-slots
chanwoo7 Oct 4, 2026
471bd85
fix: 판매자가 숨김 상품 상세를 열 수 있게
chanwoo7 Oct 4, 2026
251a957
Merge pull request #489 from CaQuick/feat/admin-banner-link-target
chanwoo7 Oct 4, 2026
ba1796b
test: supertest 대상 앱을 127.0.0.1에 열어 다른 프로세스의 포트 가로채기 차단
chanwoo7 Oct 4, 2026
b55c414
test: 가로채기 spec이 실패해도 띄운 서버를 닫게
chanwoo7 Oct 4, 2026
6ab836b
Merge pull request #491 from CaQuick/fix/seller-hidden-product-detail
chanwoo7 Oct 4, 2026
a820ae2
Merge pull request #490 from CaQuick/test/supertest-loopback
chanwoo7 Oct 4, 2026
050d7e0
fix: 자격증명 버전으로 변경과 겹친 로그인·회전 세션 차단, 블랙리스트 ms 비교
chanwoo7 Oct 4, 2026
89d9133
fix: 자격증명 버전 백필 제거 — 경쟁으로 살아남은 기존 세션까지 인정하지 않게
chanwoo7 Oct 4, 2026
746d6fa
Merge pull request #492 from CaQuick/fix/credential-version-sessions
chanwoo7 Oct 4, 2026
570e8cb
ci: 테스트 샤딩·잡 병렬화·커버리지 리포트 재사용으로 CI 단축
chanwoo7 Oct 4, 2026
5fbacc0
ci: Codecov 업로드를 PR 댓글 액션 뒤로, 워크플로 spec의 셸을 실제 기본 셸로
chanwoo7 Oct 4, 2026
d3fd709
docs: README.en CI 절을 새 잡 구성으로
chanwoo7 Oct 4, 2026
ef7ed88
test: 커버리지 임계 상향 — statements 97·branches 92·functions 97·lines 98
chanwoo7 Oct 4, 2026
adadfc9
test: 반증 — 집계 잡 확인용 실패 테스트(되돌림)
chanwoo7 Oct 4, 2026
e8499c1
test: 반증 실패 테스트 되돌림
chanwoo7 Oct 4, 2026
4d05aa0
ci: node_modules 캐시 키에 .yarnrc.yml·yarn 릴리즈 포함
chanwoo7 Oct 4, 2026
2b150c1
ci: 리뷰 반영 — 샤드 보존 7일, check 권한 비움, CI 구조 문서 정리
chanwoo7 Oct 4, 2026
cb22b65
Merge pull request #494 from CaQuick/ci/parallel-shards
chanwoo7 Oct 4, 2026
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
332 changes: 284 additions & 48 deletions .github/workflows/pr-check.yml

Large diffs are not rendered by default.

34 changes: 23 additions & 11 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ Customers end up hopping between platforms, combining screenshots, edits, and ex
- Static checks: **ESLint** (strict rules plus the `boundaries` plugin enforcing feature boundaries) and **Prettier**, run by **Husky** and **lint-staged** before commit and push.
- Structural checks: **dependency-cruiser** gates layer direction and forbids cycles; **knip** reports unused code.
- Commit messages: **commitlint** enforces Conventional Commits.
- Coverage, security, dependencies: **Codecov** (patch 80%; global thresholds statements 96%, branches 86%), **CodeQL**, **Dependabot**
- Coverage, security, dependencies: **Codecov** (patch 80%; global thresholds statements 97%, branches 92%), **CodeQL**, **Dependabot**
- Repo-specific gates
- `dto:check`: SDL inputs ↔ DTO classes stay in sync
- `docs:check`: SDL description coverage
Expand Down Expand Up @@ -369,12 +369,12 @@ extend type Query {
```bash
yarn test # everything (Docker required)
yarn test src/features/order # a single domain
yarn test:cov # coverage (thresholds: statements 96 / branches 86 / functions 92 / lines 96)
yarn test:cov # coverage (thresholds: statements 97 / branches 92 / functions 97 / lines 98)
yarn test:scripts # infrastructure specs
yarn test:push --dry-run # the Jest scope pre-push would run
```

The pre-push hook runs every static check but only the Jest specs the change reaches. Changes the import graph cannot track (SDL, prisma, test infrastructure, dependencies, global wiring) fall back to the full suite. Full regression and the coverage thresholds belong to the required CI `check`. The development machine doubles as the production Mac mini and the test containers share its VM with production, so full test runs (`yarn validate`, `yarn test:cov`) go one at a time. The reasoning is in [architecture conventions §9](./docs/guide/architecture-conventions.md) (Korean).
The pre-push hook runs every static check but only the Jest specs the change reaches. Changes the import graph cannot track (SDL, prisma, test infrastructure, dependencies, global wiring) fall back to the full suite. Full regression runs in the CI `test` shards, the coverage thresholds are checked by `coverage-report` on the merged shard results, and the required `check` collects both. The development machine doubles as the production Mac mini and the test containers share its VM with production, so full test runs (`yarn validate`, `yarn test:cov`) go one at a time. The reasoning is in [architecture conventions §9](./docs/guide/architecture-conventions.md) (Korean).

When a checker or gate is added, the **refutation cases** (proving it actually blocks what it should) are the core of its tests. CI uses the same testcontainers setup, so there is little difference between local and CI environments.

Expand Down Expand Up @@ -405,14 +405,26 @@ docker compose --profile edge up -d # cloudflared (TUNNEL_

### Workflows

| Workflow | Trigger | Role |
| -------------------------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pr-check.yml` | PR · push (main/develop) | codegen, tsc, lint, docs/arch gates, dto:check (warning only; the hard gate is the pre-push hook), infrastructure specs, integration tests, coverage, and two consecutive builds (cache regression check) |
| `codeql.yml` | PR · push · weekly | CodeQL static security analysis |
| `knip.yml` · `nestjs-doctor.yml` | PR | comments with unused-code and NestJS health reports (advisory) |
| `pr-check.yml` `image` job | PR (build only) · main push (push) | builds an arm64 image alongside the tests and pushes `ghcr.io/caquick/caquick-be:<sha>` (no mutable tags) |
| `deploy.yml` | main **CI fully succeeds** · manual (rollback sha, CI-passed only) | the self-hosted runner (Mac mini) writes `.env` and `app.env` (mode 600) from secrets, then pull → migrate → worker → api → readiness wait → observability, and notifies Discord |
| `discord-notify.yml` | PR · push · issue | Discord notifications |
| Workflow | Trigger | Role |
| -------------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pr-check.yml` | PR · push (main/develop) | runs static checks, infrastructure specs, the build, the test shards and the coverage merge as parallel jobs; `check` collects the results (see job layout below) |
| `codeql.yml` | PR · push · weekly | CodeQL static security analysis |
| `knip.yml` · `nestjs-doctor.yml` | PR | comments with unused-code and NestJS health reports (advisory) |
| `pr-check.yml` `image` job | PR (build only) · main push (push) | builds an arm64 image alongside the tests and pushes `ghcr.io/caquick/caquick-be:<sha>` (no mutable tags) |
| `deploy.yml` | main **CI fully succeeds** · manual (rollback sha, CI-passed only) | the self-hosted runner (Mac mini) writes `.env` and `app.env` (mode 600) from secrets, then pull → migrate → worker → api → readiness wait → observability, and notifies Discord |
| `discord-notify.yml` | PR · push · issue | Discord notifications |

### CI job layout (`pr-check.yml`)

- Jobs run in parallel and the required `check` collects their results.
- `static`: codegen, tsc, lint, dto:check (warning only; the hard gate is the pre-push hook), docs:check, arch:check
- `scripts`: infrastructure specs (`test:scripts`)
- `build`: two consecutive builds (incremental-cache regression check)
- `test`: the full Jest suite split into 2 shards (per-shard thresholds off)
- `coverage-report`: merges the shard coverage, checks it against the `jest.config.js` thresholds (`scripts/merge-coverage.ts`) and uploads to Codecov. On a PR it also comments a comparison against the base branch
- `check` treats skipped jobs as failures, because GitHub reports a skipped job as successful and that would satisfy a required check.
- The comparison baseline is the artifact uploaded by develop/main push runs. It is only taken from successful push runs of the base branch in this repository; without one the comment shows no delta.
- `node_modules` is cached by `yarn.lock`, `package.json`, the Yarn config and release, OS and Node version. On a hit only `prisma generate` runs instead of the install.

### Flow

Expand Down
34 changes: 23 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
- 정적 검사: **ESLint**(strict 규칙 + `boundaries` 플러그인으로 feature 경계 강제) · **Prettier**. **Husky**와 **lint-staged**가 커밋·push 전에 실행합니다.
- 구조 검사: **dependency-cruiser**(레이어 방향·순환 의존 금지)가 게이트로 막고, **knip**은 사용하지 않는 코드를 리포트합니다.
- 커밋 메시지: **commitlint**가 Conventional Commits 형식을 검사합니다.
- 커버리지·보안·의존성: **Codecov**(patch 80%, 전역 statements 96% · branches 86%) · **CodeQL** · **Dependabot**
- 커버리지·보안·의존성: **Codecov**(patch 80%, 전역 statements 97% · branches 92%) · **CodeQL** · **Dependabot**
- 이 레포만의 게이트
- `dto:check`: SDL input ↔ DTO class 동기화
- `docs:check`: SDL description 커버리지
Expand Down Expand Up @@ -369,12 +369,12 @@ extend type Query {
```bash
yarn test # 전체 실행 (Docker 필요)
yarn test src/features/order # 특정 도메인만 실행
yarn test:cov # 커버리지 측정 (임계값: statements 96 / branches 86 / functions 92 / lines 96)
yarn test:cov # 커버리지 측정 (임계값: statements 97 / branches 92 / functions 97 / lines 98)
yarn test:scripts # 인프라 spec 실행
yarn test:push --dry-run # pre-push가 돌릴 jest 범위 확인
```

pre-push는 정적 검사를 모두 돌리고, jest는 변경에 닿는 spec만 실행합니다. SDL·prisma·테스트 인프라·의존성·전역 배선처럼 import 그래프로 추적할 수 없는 변경이면 전체를 돌립니다. 전체 회귀와 커버리지 임계는 CI `check`(필수 체크)가 맡습니다. 개발 머신이 운영 맥미니를 겸하고 테스트 컨테이너가 운영과 같은 VM을 나눠 쓰므로, 전체 테스트(`yarn validate`·`yarn test:cov`)는 한 번에 하나만 돌립니다. 근거는 [아키텍처 컨벤션 §9](./docs/guide/architecture-conventions.md#9-테스트-규약)에 있습니다.
pre-push는 정적 검사를 모두 돌리고, jest는 변경에 닿는 spec만 실행합니다. SDL·prisma·테스트 인프라·의존성·전역 배선처럼 import 그래프로 추적할 수 없는 변경이면 전체를 돌립니다. 전체 회귀는 CI `test` 샤드가, 커버리지 임계는 샤드 결과를 합치는 `coverage-report`가 맡고, 필수 체크 `check`가 둘을 모읍니다. 개발 머신이 운영 맥미니를 겸하고 테스트 컨테이너가 운영과 같은 VM을 나눠 쓰므로, 전체 테스트(`yarn validate`·`yarn test:cov`)는 한 번에 하나만 돌립니다. 근거는 [아키텍처 컨벤션 §9](./docs/guide/architecture-conventions.md#9-테스트-규약)에 있습니다.

검사기와 게이트를 만들 때는 "막아야 할 것을 실제로 막는지"를 확인하는 **반증 케이스**를 테스트의 본체로 둡니다. CI도 같은 testcontainers 구성으로 실행하므로 로컬과 환경 차이가 거의 없습니다.

Expand Down Expand Up @@ -405,14 +405,26 @@ docker compose --profile edge up -d # cloudflared (TUNNEL_

### 워크플로우

| Workflow | Trigger | 역할 |
| -------------------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pr-check.yml` | PR · push (main/develop) | codegen, tsc, lint, docs/arch 게이트, dto:check(경고만 — 하드 게이트는 pre-push), 인프라 spec, 전체 테스트, 커버리지, 빌드 2회(캐시 회귀 검출)를 실행합니다 |
| `codeql.yml` | PR · push · 주간 | CodeQL 정적 보안 분석을 실행합니다 |
| `knip.yml` · `nestjs-doctor.yml` | PR | 사용하지 않는 코드와 NestJS 점검 결과를 코멘트로 남깁니다(advisory) |
| `pr-check.yml` `image` job | PR(빌드만) · main push(GHCR 푸시) | 테스트와 나란히 arm64 이미지를 빌드해 `ghcr.io/caquick/caquick-be:<sha>`로 푸시합니다(가변 태그는 두지 않습니다) |
| `deploy.yml` | main **CI 전체 성공** · 수동(롤백 sha, CI 성공분만) | 셀프호스트 러너(맥미니)가 secrets로 `.env`·`app.env`(600)를 만들고 pull → migrate → worker → api → ready 대기 → 관측 순서로 배포한 뒤 Discord에 알립니다 |
| `discord-notify.yml` | PR · push · issue | Discord에 알림을 보냅니다 |
| Workflow | Trigger | 역할 |
| -------------------------------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pr-check.yml` | PR · push (main/develop) | 정적 검사, 인프라 spec, 빌드, 테스트 샤드, 커버리지 병합을 잡으로 나눠 나란히 실행하고 `check`가 결과를 모읍니다(아래 잡 구성) |
| `codeql.yml` | PR · push · 주간 | CodeQL 정적 보안 분석을 실행합니다 |
| `knip.yml` · `nestjs-doctor.yml` | PR | 사용하지 않는 코드와 NestJS 점검 결과를 코멘트로 남깁니다(advisory) |
| `pr-check.yml` `image` job | PR(빌드만) · main push(GHCR 푸시) | 테스트와 나란히 arm64 이미지를 빌드해 `ghcr.io/caquick/caquick-be:<sha>`로 푸시합니다(가변 태그는 두지 않습니다) |
| `deploy.yml` | main **CI 전체 성공** · 수동(롤백 sha, CI 성공분만) | 셀프호스트 러너(맥미니)가 secrets로 `.env`·`app.env`(600)를 만들고 pull → migrate → worker → api → ready 대기 → 관측 순서로 배포한 뒤 Discord에 알립니다 |
| `discord-notify.yml` | PR · push · issue | Discord에 알림을 보냅니다 |

### CI 잡 구성 (`pr-check.yml`)

- 잡을 나눠 나란히 돌리고, 필수 체크 `check`가 결과를 모읍니다.
- `static`: codegen, tsc, lint, dto:check(경고만 — 하드 게이트는 pre-push), docs:check, arch:check
- `scripts`: 인프라 spec(`test:scripts`)
- `build`: 빌드 2회(증분 캐시 회귀 검출)
- `test`: jest 전체를 2개 샤드로 나눠 실행(샤드별 임계는 끔)
- `coverage-report`: 샤드 커버리지를 합쳐 `jest.config.js`의 임계로 검사하고(`scripts/merge-coverage.ts`) Codecov에 올림. PR이면 base 브랜치 기준과 비교한 댓글을 남김
- `check`는 건너뛴 잡도 실패로 봅니다. GitHub는 건너뛴 잡을 성공으로 보고해 필수 체크를 통과시키기 때문입니다.
- 커버리지 비교 기준은 develop·main push 실행이 올린 아티팩트입니다. 이 레포 base 브랜치의 성공한 push 실행에서만 받고, 없으면 차이 없이 표시합니다.
- `node_modules`는 `yarn.lock`·`package.json`·yarn 설정과 릴리즈·OS·node 버전을 키로 캐시합니다. 적중하면 설치 대신 `prisma generate`만 실행합니다.

### 흐름

Expand Down
Loading
Loading