7.0.9 → 7.0.10 sudo 업데이트 실측 후 점검에서 드러난 3건.
- 정리 단계가 소스 경로(core_{ts}/extracted/{루트}) 안쪽만 지워 껍데기가
업데이트마다 남던 것을 격리 디렉토리 루트째 삭제로 바꾼다. 부모는 구버전
클래스로 돌아 다음 업데이트부터 효력이 있으므로, 신버전 코드로 도는 두 자식
(execute-upgrade-steps / execute-bundled-updates)이 파일이 없는 core_* 만
골라 치운다 — 구버전 부모에서 올라오는 업데이트도 껍데기 없이 끝난다.
- 항목별 소유권 스냅샷이 격리 디렉토리 생성 뒤에 찍혀 root 가 만든 추출본을
원본으로 기록하고 복원이 다시 root 로 되돌리던 것을, 이번 실행의 격리
디렉토리를 스냅샷에서 제외해 닫는다.
- 완료 안내문이 성공 경로에서는 동작하지 않는 hotfix:rollback-stale-files 를
가리키던 것을 --prune 재실행 안내만 남기도록 정정한다(ko/en/ja).
부수: ExecuteUpgradeStepsStandaloneTest 가 앞선 core:update 실행이 남긴
프로세스 env 플래그에 따라 결과가 갈리던 순서 의존을 setUp/tearDown 에서 제거.
102 lines
8.0 KiB
YAML
102 lines
8.0 KiB
YAML
# audit:allow test-scenario-coverage reason: 본 매니페스트는 `core:execute-upgrade-steps` 단독 실행 안전화 (사전 2단계 + 사후 3단계 자동 수행 + 5개 --skip-* 옵션) 의 시나리오 매트릭스 SSoT. 핵심 회귀 가드는 test_files 의 통과 테스트로 커버.
|
|
|
|
feature: core:execute-upgrade-steps 단독 실행 안전화 (사전·사후 단계 자동 수행 + 5개 --skip-* 옵션)
|
|
|
|
description: |
|
|
공개 이슈 [gnuboard/g7#34](https://github.com/gnuboard/g7/issues/34) (beta.3 → beta.4 우회 절차) 의 운영자 안내문이
|
|
11단계의 수동 명령 (rsync → composer dump-autoload → cache:clear →
|
|
core:execute-upgrade-steps → migrate --force → reloadCoreConfigAndResync via tinker →
|
|
sed APP_VERSION → cache:clear → module/plugin/template:update --force --source=bundled)
|
|
을 요구했던 근본 원인은 `core:execute-upgrade-steps` 가 단독 호출 시
|
|
부모 `CoreUpdateCommand` 가 수행하던 Step 9 (Migration + Resync), Step 11
|
|
(.env 버전 + 캐시 정리), 번들 확장 일괄 업데이트 prompt 를 모두 누락한 것.
|
|
|
|
본 매니페스트는 5개 누락 단계를 자식 기본값에 포함시키고, 부모 spawn 호출 시엔
|
|
5개 `--skip-*` 옵션으로 중복 회피하는 cross product 의 회귀 가드.
|
|
|
|
추가 가드 (2026-05-14): 구버전 부모(beta.5 이하) 가 신버전 자식(beta.6+) 을 spawn 할 때
|
|
`--skip-*` 5개 옵션은 모르지만 `G7_UPDATE_IN_PROGRESS=1` env 는 beta.3+ 부모부터
|
|
항상 설정한다. 자식은 env 시그널만으로도 spawn 컨텍스트를 감지하여 5단계 모두 스킵해야
|
|
한다 (옵션 부재 + non-interactive 환경에서 prompt 호출로 인한 Aborted exit=1 회귀 차단).
|
|
|
|
구성:
|
|
1. 5개 사전·사후 단계 각각의 단독 호출 / `--skip-*` 옵션 분기 검증.
|
|
2. 부모 `CoreUpdateCommand::spawnUpgradeStepsProcess` 가 자식 command 배열에
|
|
5개 옵션을 모두 전달하는지 (escapeshellarg 후 commandLine 문자열 검증).
|
|
3. `runUpgradeSteps` 본 임무는 항상 호출 (옵션 무관).
|
|
4. 5개 옵션을 모두 전달한 경우 CoreUpdateCommand spawn 시나리오 등가 — 사전·사후 미수행.
|
|
5. `G7_UPDATE_IN_PROGRESS=1` env 만으로도 5단계 모두 스킵 (구버전 부모 V-1 안전 가드).
|
|
|
|
axes:
|
|
invocation_origin: [standalone_operator, parent_spawn_with_skip_options, parent_spawn_env_only] # 누가 호출했는가
|
|
skip_migrations: [present, absent]
|
|
skip_resync: [present, absent]
|
|
skip_version_env: [present, absent]
|
|
skip_cache_clear: [present, absent]
|
|
skip_bundled_updates: [present, absent]
|
|
spawn_env_flag: [present, absent] # G7_UPDATE_IN_PROGRESS=1 시그널
|
|
force_flag: [present, absent] # bundled prompt 우회 여부
|
|
bundled_updates_count: [zero, modules_only, plugins_only, templates_only, lang_packs_only, mixed]
|
|
from_to_relation: [from_lt_to, from_eq_to_forced] # version_compare 분기
|
|
|
|
exclusions:
|
|
- { invocation_origin: parent_spawn_with_skip_options, skip_migrations: absent, reason: "부모(beta.6+) spawn 시엔 5개 옵션 모두 전달 — 일부 절단 시뮬은 인위적 비현실 분기" }
|
|
- { invocation_origin: parent_spawn_with_skip_options, skip_resync: absent, reason: "동일 — 부모 spawn 시 5개 옵션 일괄 전달" }
|
|
- { invocation_origin: parent_spawn_with_skip_options, skip_version_env: absent, reason: "동일" }
|
|
- { invocation_origin: parent_spawn_with_skip_options, skip_cache_clear: absent, reason: "동일" }
|
|
- { invocation_origin: parent_spawn_with_skip_options, skip_bundled_updates: absent, reason: "동일" }
|
|
- { invocation_origin: parent_spawn_env_only, skip_migrations: present, reason: "구버전 부모(beta.5) 는 5개 옵션을 모르므로 전달하지 않음 — 본 분기는 env 가드 단독 효과 검증" }
|
|
- { invocation_origin: parent_spawn_env_only, skip_resync: present, reason: "동일" }
|
|
- { invocation_origin: parent_spawn_env_only, skip_version_env: present, reason: "동일" }
|
|
- { invocation_origin: parent_spawn_env_only, skip_cache_clear: present, reason: "동일" }
|
|
- { invocation_origin: parent_spawn_env_only, skip_bundled_updates: present, reason: "동일" }
|
|
- { invocation_origin: parent_spawn_env_only, spawn_env_flag: absent, reason: "정의상 env_only 분기는 env=1 필수" }
|
|
- { invocation_origin: standalone_operator, spawn_env_flag: present, reason: "운영자 수동 호출은 env 미설정 — env 설정 시는 parent_spawn 분기로 분류" }
|
|
- { invocation_origin: standalone_operator, bundled_updates_count: zero, skip_bundled_updates: absent, force_flag: absent, reason: "0건 + 옵션 미사용 + force 미사용 시 prompt 발동되나 본 매트릭스의 회귀 대상은 옵션 분기뿐" }
|
|
|
|
effects:
|
|
# §1 사전 단계 자동 수행
|
|
- ExecuteUpgradeStepsCommand_invokes_runMigrations_by_default
|
|
- ExecuteUpgradeStepsCommand_skips_runMigrations_when_skip_migrations_present
|
|
- ExecuteUpgradeStepsCommand_invokes_reloadCoreConfigAndResync_by_default
|
|
- ExecuteUpgradeStepsCommand_skips_reloadCoreConfigAndResync_when_skip_resync_present
|
|
# §2 사후 단계 자동 수행
|
|
- ExecuteUpgradeStepsCommand_invokes_updateVersionInEnv_with_to_version_by_default
|
|
- ExecuteUpgradeStepsCommand_skips_updateVersionInEnv_when_skip_version_env_present
|
|
- ExecuteUpgradeStepsCommand_invokes_clearAllCaches_by_default
|
|
- ExecuteUpgradeStepsCommand_skips_clearAllCaches_when_skip_cache_clear_present
|
|
- ExecuteUpgradeStepsCommand_invokes_runBundledExtensionUpdatePrompt_by_default
|
|
- ExecuteUpgradeStepsCommand_skips_bundled_updates_when_skip_bundled_updates_present
|
|
# §3 본 임무 (runUpgradeSteps) 는 옵션 무관 항상 호출
|
|
- ExecuteUpgradeStepsCommand_always_invokes_runUpgradeSteps_regardless_of_skip_options
|
|
# §4 부모 spawn 5개 옵션 전달
|
|
- CoreUpdateCommand_spawnUpgradeStepsProcess_appends_skip_migrations_to_command_array
|
|
- CoreUpdateCommand_spawnUpgradeStepsProcess_appends_skip_resync_to_command_array
|
|
- CoreUpdateCommand_spawnUpgradeStepsProcess_appends_skip_version_env_to_command_array
|
|
- CoreUpdateCommand_spawnUpgradeStepsProcess_appends_skip_cache_clear_to_command_array
|
|
- CoreUpdateCommand_spawnUpgradeStepsProcess_appends_skip_bundled_updates_to_command_array
|
|
# §5 운영자 안내문 (resumeCommand) 호환성 — 옵션 없이도 기본값으로 안전 실행
|
|
- resume_command_without_skip_options_invokes_all_five_pre_and_post_steps_safely
|
|
# §6 구버전 부모 V-1 안전 가드 (env 시그널 단독)
|
|
- ExecuteUpgradeStepsCommand_skips_runMigrations_when_spawn_env_flag_present_without_skip_options
|
|
- ExecuteUpgradeStepsCommand_skips_reloadCoreConfigAndResync_when_spawn_env_flag_present_without_skip_options
|
|
- ExecuteUpgradeStepsCommand_skips_updateVersionInEnv_when_spawn_env_flag_present_without_skip_options
|
|
- ExecuteUpgradeStepsCommand_skips_clearAllCaches_when_spawn_env_flag_present_without_skip_options
|
|
- ExecuteUpgradeStepsCommand_skips_bundled_updates_when_spawn_env_flag_present_without_skip_options
|
|
- ExecuteUpgradeStepsCommand_env_guard_dominates_over_force_flag_for_post_steps
|
|
- ExecuteUpgradeStepsCommand_standalone_invocation_without_env_runs_all_five_steps_intact
|
|
- execute_upgrade_steps_child_reads_update_config_from_disk_when_config_is_cached
|
|
- ExecuteUpgradeStepsCommand_sweeps_empty_staging_directories_left_by_parent
|
|
|
|
test_files:
|
|
- tests/Feature/Console/Commands/ExecuteUpgradeStepsStandaloneTest.php
|
|
- tests/Feature/Console/Commands/ExecuteUpgradeStepsCommandHandoffTest.php
|
|
|
|
# 본 매트릭스의 cross product 는 수백 케이스이나, 실제 회귀 가드는 test_files 의
|
|
# 통과 테스트가 SSoT — 매니페스트는 매트릭스 SSoT 역할.
|
|
#
|
|
# 의도적 제외:
|
|
# - maintenance 모드 자동 제어 (down/up) : 단독 실행 시 운영자가 직접 제어. 매트릭스 대상 아님.
|
|
# - ownership snapshot / cleanupPending / deleteBackup : 단독 실행 컨텍스트에 해당 자원 자체가 없음.
|
|
# - composer 재실행 : 디스크 코어 파일은 이미 신버전 적용된 상태가 단독 실행의 전제.
|