From eb2b35ef361906d2ea4be7d2508730b12e3c99ad Mon Sep 17 00:00:00 2001 From: HeuJung Date: Thu, 2 Jul 2026 17:19:23 +0900 Subject: [PATCH] =?UTF-8?q?chore(release):=207.0.1=20=EC=B6=9C=EC=8B=9C?= =?UTF-8?q?=EC=9D=BC=20=EC=98=A4=EB=8A=98=EB=A1=9C=20=EC=A1=B0=EC=A0=95=20?= =?UTF-8?q?+=20=EA=B3=B5=EA=B0=9C=20=EC=86=8C=EC=8A=A4=20=EB=82=B4?= =?UTF-8?q?=EB=B6=80=20=EB=8B=A8=EC=84=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 출시일: CHANGELOG [7.0.1] 및 엔진 CHANGELOG(v1.52.0/v1.51.0) 를 2026-07-02(오늘)로 조정 - 공개 release 포함 소스의 내부 이슈번호 정리: - 공개 이슈는 gnuboard/g7 명시 형식으로 정규화 - 내부 이슈번호는 서술문으로 일반화 - 코드 주석의 내부 역할 호칭("")을 중립 표현으로 일반화 --- CHANGELOG.md | 2 +- app/Console/Commands/Core/CoreUpdateCommand.php | 4 ++-- app/Services/CoreUpdateService.php | 2 +- resources/js/core/template-engine/CHANGELOG.md | 4 ++-- .../__tests__/spec/actionRecipeEngine.test.ts | 8 ++++---- .../layout-editor/spec/actionRecipeEngine.ts | 2 +- .../core/template-engine/layout-editor/spec/specTypes.ts | 2 +- .../Feature/Console/CoreUpdateCommandSpawnFailureTest.php | 4 ++-- .../Playwright/specs/checkout-pg-dynamic-dispatch.spec.ts | 2 +- .../Extension/Helpers/FilePermissionHelperSymlinkTest.php | 2 +- tests/scenarios/core-update-spawn-failure-mode.yaml | 8 ++++---- 11 files changed, 20 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 885802a3..e34eaa56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ 형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며, [Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다. -## [7.0.1] - 2026-07-01 +## [7.0.1] - 2026-07-02 ### Changed diff --git a/app/Console/Commands/Core/CoreUpdateCommand.php b/app/Console/Commands/Core/CoreUpdateCommand.php index dec79206..fb381c94 100644 --- a/app/Console/Commands/Core/CoreUpdateCommand.php +++ b/app/Console/Commands/Core/CoreUpdateCommand.php @@ -877,7 +877,7 @@ class CoreUpdateCommand extends Command * - `[STEPS_EXECUTED]` 신호 미수신 (`$stepsExecuted === null`) → fail-fast. * 이전 버전 자식 (신호 미발행) 또는 silent skip 의심. * - executed=0 인데 **discovered>0** → fail-fast. 범위 내에 스텝 파일이 실제로 - * 존재하는데 자식이 하나도 실행하지 못함 (이슈 #28 silent skip — 케이스 A). + * 존재하는데 자식이 하나도 실행하지 못함 (gnuboard/g7#28 silent skip — 케이스 A). * - executed=0 이고 **discovered=0** → 정상 통과. 해당 from~to 범위에 스텝 파일이 * 애초에 없는 릴리즈 (예: 데이터/설정 변경 없는 패치). from0 또는 discovered 신호 부재) + from0: 스텝 파일이 있는데 자식이 실행 못함 (이슈 #28 케이스 A). + // discovered>0: 스텝 파일이 있는데 자식이 실행 못함 (gnuboard/g7#28 케이스 A). // discovered=null: 구버전 자식 (discovered 미발행) — 레거시 판정 유지. if ($stepsExecuted === 0 && $stepsDiscovered !== 0 diff --git a/app/Services/CoreUpdateService.php b/app/Services/CoreUpdateService.php index 0cc8c6af..b3523eff 100644 --- a/app/Services/CoreUpdateService.php +++ b/app/Services/CoreUpdateService.php @@ -1662,7 +1662,7 @@ class CoreUpdateService // 범위 내에서 발견된 스텝 파일 수(discovered)를 먼저 통지한다. // 호출자(spawn 자식)는 이 값으로 "스텝 파일이 애초에 없어 0건(정상)" 과 "스텝 파일은 - // 있는데 실행이 0건(비정상 — 이슈 #28 silent skip)" 을 구분한다. onStep 은 실제 실행 + // 있는데 실행이 0건(비정상 — gnuboard/g7#28 silent skip)" 을 구분한다. onStep 은 실제 실행 // 건마다 호출되므로 executed 수만 세며, discovered 는 실행 전에 1회 통지한다. $onDiscovered?->__invoke(count($steps)); diff --git a/resources/js/core/template-engine/CHANGELOG.md b/resources/js/core/template-engine/CHANGELOG.md index c6da28e9..3d7f0643 100644 --- a/resources/js/core/template-engine/CHANGELOG.md +++ b/resources/js/core/template-engine/CHANGELOG.md @@ -5,7 +5,7 @@ > > 형식: [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/) -## [engine-v1.52.0] - 2026-07-01 +## [engine-v1.52.0] - 2026-07-02 ### Changed @@ -16,7 +16,7 @@ - `devtools-entry.ts` + `vite.config.devtools.js`(신규) — DevTools 번들 엔트리/빌드. React external → `window.React` 단일 인스턴스, `G7DevToolsCore` 는 shim(`devtools/__runtime-shims/`)으로 메인 번들과 공유(재번들 0바이트, 싱글톤 동일성). - `core:build` — 엔진 + 편집기 + DevTools 3개 번들 순차 빌드. `--watch` 는 3개 `vite build --watch` 병렬. -## [engine-v1.51.0] - 2026-07-01 +## [engine-v1.51.0] - 2026-07-02 ### Changed diff --git a/resources/js/core/template-engine/layout-editor/__tests__/spec/actionRecipeEngine.test.ts b/resources/js/core/template-engine/layout-editor/__tests__/spec/actionRecipeEngine.test.ts index 9a82e283..8d523d1c 100644 --- a/resources/js/core/template-engine/layout-editor/__tests__/spec/actionRecipeEngine.test.ts +++ b/resources/js/core/template-engine/layout-editor/__tests__/spec/actionRecipeEngine.test.ts @@ -273,7 +273,7 @@ describe('requestPgPayment — placeholder 핸들러 build/match 라운드트립 // 회귀 — "+동작 추가" 로 결제 진입을 고르면 ActionAddPicker 가 buildAction(recipe, {}) 로 빈 값 // 빌드한다. placeholder 핸들러({{paymentHandler}})가 빈 값에서 undefined 로 떨어져 사라지면 - // handler 없는 액션이 되어 "알 수 없는 동작"(advanced)으로 강등된다(PO 제보). 빈 빌드에서도 + // handler 없는 액션이 되어 "알 수 없는 동작"(advanced)으로 강등된다(제보 회귀). 빈 빌드에서도 // handler placeholder 는 보존돼야 추가 직후 친화 카드로 매칭되고 사용자가 칩으로 채울 수 있다. it('빈 값 빌드(+동작 추가) — placeholder 핸들러가 보존되어 handler 가 사라지지 않는다', () => { const recipe = recipes.find((r) => r.id === 'requestPgPayment')!; @@ -290,14 +290,14 @@ describe('requestPgPayment — placeholder 핸들러 build/match 라운드트립 expect(m?.recipeId).toBe('requestPgPayment'); }); - // 회귀(PO 제보) — 핸들러 필드를 데이터 칩으로 바꾸고 결제 데이터는 비워두면, buildAction 이 + // 회귀(제보) — 핸들러 필드를 데이터 칩으로 바꾸고 결제 데이터는 비워두면, buildAction 이 // 미입력 required pgPaymentData 를 떨궈 params 가 사라진다. 그러면 fingerprint(pgPaymentData) - // 가 깨져 친화 카드가 [고급]으로 강등됐다(PO: "변경하니 고급으로 넘어간다"). required placeholder + // 가 깨져 친화 카드가 [고급]으로 강등됐다("변경하니 고급으로 넘어간다"). required placeholder // param 은 빈 값이어도 토큰을 보존해 fingerprint 를 유지하고, 핸들러를 어떤 칩으로 바꿔도 친화 // 카드가 유지돼야 한다(핸들러 필드 바인딩 가능성 ↔ greedy 가드 공존). it('핸들러를 임의 칩으로 바꾸고 데이터는 비워도 requestPgPayment 친화 카드 유지 (고급 강등 금지)', () => { const recipe = recipes.find((r) => r.id === 'requestPgPayment')!; - // 핸들러만 데이터 칩으로 채우고 pgPaymentData 는 미입력(빈 값) — PO 시나리오. + // 핸들러만 데이터 칩으로 채우고 pgPaymentData 는 미입력(빈 값) — 제보 시나리오. const action = buildAction(recipe, { paymentHandler: '{{checkoutData?.data?.temp_order_id}}' }); // required pgPaymentData 가 토큰으로 보존돼 params 가 살아있어야 한다. expect(action.handler).toBe('{{checkoutData?.data?.temp_order_id}}'); diff --git a/resources/js/core/template-engine/layout-editor/spec/actionRecipeEngine.ts b/resources/js/core/template-engine/layout-editor/spec/actionRecipeEngine.ts index 52c1b835..211bb24e 100644 --- a/resources/js/core/template-engine/layout-editor/spec/actionRecipeEngine.ts +++ b/resources/js/core/template-engine/layout-editor/spec/actionRecipeEngine.ts @@ -221,7 +221,7 @@ export function buildAction( // required param 의 sole-binding 토큰이 미입력으로 떨어지면 build 틀의 토큰을 복원한다. 이런 recipe // (결제 진입)는 matchAction 의 구조 fingerprint(placeholderRecipeStructureMatches)가 params 의 // 토큰 존재에 의존하므로, 핸들러 필드를 임의 데이터 칩으로 바꾸고 다른 required 값을 비워둬도 친화 - // 카드가 [고급]으로 강등되지 않게 토큰을 유지한다(PO 제보 회귀). 일반 recipe(리터럴 핸들러, + // 카드가 [고급]으로 강등되지 않게 토큰을 유지한다(제보 회귀). 일반 recipe(리터럴 핸들러, // apiCall 등)는 미입력 required 를 그대로 떨궈 깔끔한 JSON 정책을 지킨다 — 그쪽은 핸들러 일치만으로 // 매칭되므로 토큰 보존이 필요 없다. if (recipe.build.handler.includes('{{')) { diff --git a/resources/js/core/template-engine/layout-editor/spec/specTypes.ts b/resources/js/core/template-engine/layout-editor/spec/specTypes.ts index dbad71b8..d2e47e04 100644 --- a/resources/js/core/template-engine/layout-editor/spec/specTypes.ts +++ b/resources/js/core/template-engine/layout-editor/spec/specTypes.ts @@ -119,7 +119,7 @@ export interface EditorSpec { * 다크 모드 표현 선언 — (편집기 프리뷰 다크 격리). * * 템플릿이 어떤 방식으로 다크 모드를 표현하는지 선언한다(라이브러리 중립). - * 편집기 프리뷰는 PO admin 환경의 `html.dark` 조상과 독립적으로 라이트/다크를 + * 편집기 프리뷰는 관리자 admin 환경의 `html.dark` 조상과 독립적으로 라이트/다크를 * 보여줘야 하는데(조상 `.dark` 가 프리뷰 라이트 격리를 깸), 코어 CSS 서빙 API 가 * 이 선언대로 편집기용 CSS 의 다크 셀렉터를 프리뷰 전용 마커로 치환해 서빙한다. * 일반 사용자 페이지 CSS 는 원본 그대로(무영향). 미선언/`none` 이면 다크 탭 비노출. diff --git a/tests/Feature/Console/CoreUpdateCommandSpawnFailureTest.php b/tests/Feature/Console/CoreUpdateCommandSpawnFailureTest.php index a6550b1a..fbbe5c43 100644 --- a/tests/Feature/Console/CoreUpdateCommandSpawnFailureTest.php +++ b/tests/Feature/Console/CoreUpdateCommandSpawnFailureTest.php @@ -12,7 +12,7 @@ use Tests\TestCase; /** * `spawn_failure_mode` + `[STEPS_EXECUTED]` 신호 + stale 메모리 가드 회귀 테스트 (§2/§2.1/§6). * - * 회귀 시나리오 (이슈 #28): + * 회귀 시나리오 (gnuboard/g7#28): * - spawn 자식 실패 → in-process fallback 진입 → 부모 메모리 stale → upgrade step * 안에서 신규 메서드 호출 fatal (예: `Call to undefined method ensureWritableDirectories()`) * @@ -128,7 +128,7 @@ class CoreUpdateCommandSpawnFailureTest extends TestCase public function spawn_자식_범위내_스텝이_있는데_0건_실행이면_abort_throw_한다(): void { // 범위 내에 스텝 파일이 실제로 존재(discovered>0)하는데 executed=0 인 경우 — - // 이전 버전 자식이 신규 스텝을 놓치고 silent skip 한 이슈 #28 케이스 (케이스 A). + // 이전 버전 자식이 신규 스텝을 놓치고 silent skip 한 gnuboard/g7#28 케이스 (케이스 A). // 이 경우에만 fail-fast 를 발동해야 한다. // // 재현: 스텝 파일은 존재하나 자식의 runUpgradeSteps 가 executed 를 0 으로 보고하도록, diff --git a/tests/Playwright/specs/checkout-pg-dynamic-dispatch.spec.ts b/tests/Playwright/specs/checkout-pg-dynamic-dispatch.spec.ts index 1c085947..d7c77d2c 100644 --- a/tests/Playwright/specs/checkout-pg-dynamic-dispatch.spec.ts +++ b/tests/Playwright/specs/checkout-pg-dynamic-dispatch.spec.ts @@ -20,7 +20,7 @@ * 라운드트립으로 런타임 동작 검증. * - 백엔드(OrderResponsePaymentHandlerTest.php, 6건 green): provider→응답 * pg_payment_handler 매핑, 미선언 시 키 부재. - * 브라우저 실측은 PG 샌드박스가 구성된 환경에서 PO 가 직접 수행한다. + * 브라우저 실측은 PG 샌드박스가 구성된 환경에서 직접 수행한다. * * 활성화 전 사전 작업: * 1. checkout 결제하기 버튼에 data-testid="checkout-submit-order" diff --git a/tests/Unit/Extension/Helpers/FilePermissionHelperSymlinkTest.php b/tests/Unit/Extension/Helpers/FilePermissionHelperSymlinkTest.php index 799083fb..2a59e048 100644 --- a/tests/Unit/Extension/Helpers/FilePermissionHelperSymlinkTest.php +++ b/tests/Unit/Extension/Helpers/FilePermissionHelperSymlinkTest.php @@ -10,7 +10,7 @@ use Tests\TestCase; /** * `FilePermissionHelper::copyDirectory` / `removeOrphanItems` 의 symlink 보존 동작 회귀 가드. * - * 회귀 시나리오 (이슈 #28 + 본 계획 §1): + * 회귀 시나리오 (gnuboard/g7#28): * - 코어 자동 롤백 시 `public/storage` symlink 가 target 디렉토리 내용으로 추적 복사되어 * symlink 가 일반 디렉토리로 변질 → 운영자가 `storage:link` 재실행 필요 * - `removeOrphanItems` 가 source 부재 symlink 를 디렉토리로 인식하여 target 의 모든 파일을 diff --git a/tests/scenarios/core-update-spawn-failure-mode.yaml b/tests/scenarios/core-update-spawn-failure-mode.yaml index 2cf2111f..6b21b922 100644 --- a/tests/scenarios/core-update-spawn-failure-mode.yaml +++ b/tests/scenarios/core-update-spawn-failure-mode.yaml @@ -24,7 +24,7 @@ description: | 4. V-1 안전 작성 패턴 docs + audit rule `upgrade-step-vone-safety` (warning) — upgrade step 안의 `app(*Service|*Manager|*Repository::class)` 호출을 reviewer 에게 surface. - 분기 개정 (2026-07-02 #432 후속): `child_silent_skip_zero_steps` 를 discovered 축으로 + 분기 개정 (discovered 축 세분화): `child_silent_skip_zero_steps` 를 discovered 축으로 세분화. 범위 내 스텝 파일이 애초에 없어 0건인 경우(discovered=0)를 정상 통과로 재분류하여, 스텝이 필요 없는 패치 릴리즈(예: 7.0.0→7.0.1) 를 실패로 오판하던 결함을 차단. @@ -44,7 +44,7 @@ exclusions: - { spawn_branch: proc_open_disabled, parent_memory_version: equal_to_to, reason: "proc_open 비활성 시점에 부모는 항상 fromVersion 메모리 — equal 케이스 시뮬 불가" } - { from_to_relation: from_eq_to_forced, spawn_branch: child_zero_steps_with_discovered, reason: "from==to + force 케이스는 step 0건이 정상 동작이므로 silent skip 가드 미트리거" } - { child_process_origin: beta_4_or_earlier, steps_executed_signal: present_positive, reason: "beta.5 이전 자식은 [STEPS_EXECUTED] 신호 자체를 모름 — present_positive 시뮬 불가" } - - { child_process_origin: beta_4_or_earlier, steps_discovered_signal: discovered_positive, reason: "discovered 필드는 #432 후속 신버전 자식만 발행 — 구버전 자식은 항상 absent" } + - { child_process_origin: beta_4_or_earlier, steps_discovered_signal: discovered_positive, reason: "discovered 필드는 신버전 자식만 발행 — 구버전 자식은 항상 absent" } - { child_process_origin: beta_4_or_earlier, steps_discovered_signal: discovered_zero, reason: "동일 — 구버전 자식은 discovered 필드 미발행(absent)" } - { spawn_branch: child_zero_steps_no_step_files, steps_discovered_signal: discovered_positive, reason: "스텝 파일 부재 브랜치는 정의상 discovered=0 — positive 모순" } - { spawn_branch: child_zero_steps_with_discovered, steps_discovered_signal: discovered_zero, reason: "스텝 파일 존재 브랜치는 정의상 discovered>0 — zero 모순" } @@ -61,9 +61,9 @@ effects: - ExecuteUpgradeStepsCommand_does_not_emit_STEPS_EXECUTED_on_handoff_exit - spawnUpgradeStepsProcess_parses_STEPS_EXECUTED_with_positive_count_returns_true - spawnUpgradeStepsProcess_missing_STEPS_EXECUTED_dispatches_to_failSpawnWithMode - # discovered 기반 분기 (#432 후속) — executed=0 을 discovered 로 구분 + # discovered 기반 분기 — executed=0 을 discovered 로 구분 - handleSpawnExit_zero_executed_zero_discovered_returns_true # 케이스 B: 스텝 파일 부재 정상 통과 - - handleSpawnExit_zero_executed_positive_discovered_dispatches_to_failSpawnWithMode # 케이스 A: #28 silent skip + - handleSpawnExit_zero_executed_positive_discovered_dispatches_to_failSpawnWithMode # 케이스 A: gnuboard/g7#28 silent skip - handleSpawnExit_zero_executed_null_discovered_from_lt_to_dispatches_to_failSpawnWithMode # 구버전 자식 레거시 판정 - spawnUpgradeStepsProcess_no_step_files_returns_true_even_when_from_lt_to # 7.0.0→7.0.1 실증 - runUpgradeSteps_notifies_discovered_zero_when_no_step_in_range