-
Notifications
You must be signed in to change notification settings - Fork 0
docs: 릴리즈 메타데이터 후속 정리 #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # Changelog | ||
|
|
||
| 이 문서는 LaunchingView의 릴리즈 변경 사항을 기록합니다. | ||
|
|
||
| ## Unreleased | ||
|
|
||
| - 아직 릴리즈되지 않은 변경 사항은 여기에 기록합니다. | ||
|
|
||
| ## 0.9.1 - 2026-05-17 | ||
|
|
||
| ### Added | ||
|
|
||
| - 강제 업데이트와 종료형 공지를 앱 종료 대신 차단 화면으로 표시하는 `BlockingLaunchView` 흐름을 추가했습니다. | ||
| - fetch 취소, fetch error dismiss 후 재조회, optional update action, notice dismiss URL open 흐름을 Swift Testing 테스트로 보강했습니다. | ||
| - README에 LaunchingView의 목적, 동작 방식, 주요 컴포넌트, 설정 포인트를 한글로 보강했습니다. | ||
|
|
||
| ### Changed | ||
|
|
||
| - `LaunchingService` 의존성을 `0.9.2`로 업데이트했습니다. | ||
| - The Composable Architecture를 `1.25.5`로 업데이트했습니다. | ||
| - Swift tools를 `6.1`로 올렸습니다. | ||
| - 최소 지원 플랫폼을 iOS 16.0, macOS 13.0으로 상향했습니다. | ||
| - `ViewStore` 기반 관찰을 제거하고 `@ObservableState`, `@Presents`, `Perception` 기반 Store 관찰로 전환했습니다. | ||
| - DocC 배포 워크플로가 `swift-man/docs` 저장소의 `main` 브랜치에 `LaunchingView/` 경로로 배포하도록 정리했습니다. | ||
|
|
||
| ### Fixed | ||
|
|
||
| - fetch 실패 alert를 표시하기 전에 optional update alert와 notice alert 상태를 정리해 여러 alert binding이 동시에 활성화될 수 있는 문제를 방지했습니다. | ||
| - fetch 작업 취소 시 사용자에게 fetch error alert가 표시되지 않도록 취소 경로를 별도로 처리했습니다. | ||
| - SwiftUI view 재생성 중 Store 상태가 유실되지 않도록 Store 소유권을 안정화했습니다. | ||
|
|
||
| ## 0.9.0 - 2026-05-17 | ||
|
|
||
| ### Changed | ||
|
|
||
| - Launching reducer의 부수 효과를 TCA dependency 기반으로 분리했습니다. | ||
| - URL open 동작을 `@Dependency(\.openURL)`로 주입하도록 정리했습니다. | ||
| - `LaunchingService` 테스트 의존성을 안전하게 격리했습니다. | ||
| - XCTest 기반 테스트를 Swift Testing 기반으로 전환했습니다. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,15 +9,99 @@ DOCC_ARCHIVE_PATH="${DOCC_ARCHIVE_PATH:-./$TARGET_NAME.doccarchive}" | |
| DOCS_OUTPUT_PATH="${DOCS_OUTPUT_PATH:-./docs}" | ||
| HOSTING_BASE_PATH="${HOSTING_BASE_PATH:-$TARGET_NAME}" | ||
| BUNDLE_IDENTIFIER="${BUNDLE_IDENTIFIER:-com.swift-man.$TARGET_NAME}" | ||
| BUNDLE_VERSION="${BUNDLE_VERSION:-0.9.1}" | ||
| VERSION_FILE="${VERSION_FILE:-VERSION.txt}" | ||
| if [ -z "${BUNDLE_VERSION+x}" ] && [ -f "$VERSION_FILE" ]; then | ||
| BUNDLE_VERSION="$(tr -d '[:space:]' < "$VERSION_FILE")" | ||
| else | ||
| BUNDLE_VERSION="${BUNDLE_VERSION:-0.9.1}" | ||
| fi | ||
| if [ -z "$BUNDLE_VERSION" ]; then | ||
| echo "error: bundle version is empty" >&2 | ||
| exit 1 | ||
| fi | ||
| MINIMUM_ACCESS_LEVEL="${MINIMUM_ACCESS_LEVEL:-public}" | ||
| DUMP_SYMBOL_GRAPH_TIMEOUT_SECONDS="${DUMP_SYMBOL_GRAPH_TIMEOUT_SECONDS:-300}" | ||
| DOCC="$(xcrun --find docc)" | ||
|
|
||
| case "$DUMP_SYMBOL_GRAPH_TIMEOUT_SECONDS" in | ||
| ''|*[!0-9]*) | ||
| echo "error: DUMP_SYMBOL_GRAPH_TIMEOUT_SECONDS must be a non-negative integer" >&2 | ||
| exit 1 | ||
| ;; | ||
| esac | ||
|
|
||
| if [ ! -f Package.swift ]; then | ||
| echo "error: Package.swift not found; run this script from the package root" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ ! -d "$DOCC_CATALOG_PATH" ]; then | ||
| echo "error: DocC catalog not found at $DOCC_CATALOG_PATH" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| terminate_command() { | ||
| signal="$1" | ||
| command_pid="$2" | ||
| command_pgid="$(ps -o pgid= -p "$command_pid" 2>/dev/null | tr -d ' ')" | ||
| shell_pgid="$(ps -o pgid= -p $$ 2>/dev/null | tr -d ' ')" | ||
|
|
||
| if [ -n "$command_pgid" ] && [ "$command_pgid" != "$shell_pgid" ]; then | ||
| kill -"$signal" "-$command_pgid" 2>/dev/null || kill -"$signal" "$command_pid" 2>/dev/null || true | ||
| else | ||
| kill -"$signal" "$command_pid" 2>/dev/null || true | ||
| fi | ||
| } | ||
|
|
||
| start_command() { | ||
| perl -MPOSIX=setsid -e 'setsid() or die "setsid: $!"; exec @ARGV or die "exec: $!"' -- "$@" & | ||
| } | ||
|
|
||
| run_with_timeout() { | ||
| timeout_seconds="$1" | ||
| shift | ||
|
|
||
| if [ "$timeout_seconds" -le 0 ]; then | ||
| "$@" | ||
| return $? | ||
| fi | ||
|
|
||
| start_command "$@" | ||
| command_pid=$! | ||
| elapsed_seconds=0 | ||
|
|
||
| while kill -0 "$command_pid" 2>/dev/null; do | ||
| if [ "$elapsed_seconds" -ge "$timeout_seconds" ]; then | ||
| echo "error: command timed out after ${timeout_seconds}s: $*" >&2 | ||
| terminate_command TERM "$command_pid" | ||
| sleep 2 | ||
| terminate_command KILL "$command_pid" | ||
| wait "$command_pid" 2>/dev/null || true | ||
| return 124 | ||
| fi | ||
|
|
||
| sleep 1 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Minor] sleep 1 명령을 반복 호출하는 루프 기반의 시간 측정 방식은 프로세스 스케줄링 오버헤드로 인해 실제 설정된 timeout 시간보다 다소 늦게 감지가 이루어질 수 있습니다. 엄밀한 정밀도가 요구되는 작업은 아니나, 실제 대기 시간과 약간의 오차가 발생할 수 있음을 인지할 필요가 있습니다.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 검토했습니다. 지적 자체는 맞지만 이 스크립트의 timeout은 strict real-time 보장이 아니라 무한 대기 방지 목적이라 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Minor] Problem: Confidence score: 0.85
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 검토했습니다. timeout 정밀도 지적은 사실이지만 이 스크립트의 목적은 초 단위 hard real-time 제어가 아니라 DocC 생성이 무한 대기하지 않도록 막는 것입니다. macOS 기본 환경에 없는 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 동의합니다. 작성자분께서 남겨주신 것처럼 해당 타임아웃 처리는 실시간 수준의 정밀한 스케줄링을 위함이 아니라 무한 루프나 블로킹 현상을 방지하는 목적이 크기 때문에, 단순한 sleep 1 루프 오버헤드는 배포 워크플로 및 시스템 리소스 상 수용 가능한 수준입니다. |
||
| elapsed_seconds=$((elapsed_seconds + 1)) | ||
| done | ||
|
|
||
| wait "$command_pid" | ||
| } | ||
|
|
||
| rm -rf "$SYMBOL_GRAPH_PATH" "$DOCS_OUTPUT_PATH" "$DOCC_ARCHIVE_PATH" | ||
| mkdir -p "$SYMBOL_GRAPH_PATH" | ||
|
|
||
| swift build | ||
| if ! swift package dump-symbol-graph --minimum-access-level "$MINIMUM_ACCESS_LEVEL"; then | ||
| find "$PACKAGE_BUILD_PATH" -path "*/symbolgraph/$TARGET_NAME*.symbols.json" \ | ||
| -exec rm -f {} \; | ||
|
|
||
| dump_symbol_graph_status=0 | ||
| run_with_timeout "$DUMP_SYMBOL_GRAPH_TIMEOUT_SECONDS" \ | ||
| swift package dump-symbol-graph --minimum-access-level "$MINIMUM_ACCESS_LEVEL" || dump_symbol_graph_status=$? | ||
|
|
||
| if [ "$dump_symbol_graph_status" -eq 124 ]; then | ||
| echo "error: dump-symbol-graph timed out; aborting DocC generation" >&2 | ||
| exit 124 | ||
| elif [ "$dump_symbol_graph_status" -ne 0 ]; then | ||
| echo "warning: dump-symbol-graph exited non-zero; continuing if $TARGET_NAME symbols were emitted" >&2 | ||
| fi | ||
|
|
||
|
|
@@ -42,10 +126,13 @@ fi | |
| --output-path "$DOCS_OUTPUT_PATH" \ | ||
| --hosting-base-path "$HOSTING_BASE_PATH" | ||
|
|
||
| HOSTING_BASE_PATH="/${HOSTING_BASE_PATH#/}" | ||
| export HOSTING_BASE_PATH | ||
| STATIC_HOSTING_BASE_PATH="/${HOSTING_BASE_PATH#/}" | ||
| if [ "$STATIC_HOSTING_BASE_PATH" = "/" ]; then | ||
| STATIC_HOSTING_BASE_PATH="" | ||
| fi | ||
| export STATIC_HOSTING_BASE_PATH | ||
| perl -0pi -e ' | ||
| my $base = $ENV{"HOSTING_BASE_PATH"}; | ||
| my $base = $ENV{"STATIC_HOSTING_BASE_PATH"}; | ||
| s#href="/favicon\.ico"#href="$base/favicon.ico"#g; | ||
| s#href="/favicon\.svg"#href="$base/favicon.svg"#g; | ||
| s#var baseUrl = "/"#var baseUrl = "$base/"#g; | ||
|
|
@@ -54,6 +141,6 @@ perl -0pi -e ' | |
| ' "$DOCS_OUTPUT_PATH/index.html" | ||
|
|
||
| find "$DOCS_OUTPUT_PATH" -type f -name '*.js' \ | ||
| -exec perl -0pi -e 's/[ \t]+$//mg' {} + | ||
| -exec perl -pi -e 's/[ \t]+$//g' {} + | ||
|
|
||
| rm -rf "$DOCC_ARCHIVE_PATH" "$SYMBOL_GRAPH_PATH" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 0.9.1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Major] Problem:
terminate_command TERM이후sleep 2후terminate_command KILL를 호출하지만, 이는run_with_timeout내부에서kill -TERM을 실행한 후 바로kill -KILL를 시도하는 방식과 동일합니다. 그러나run_with_timeout는command_pid를 직접 종료하는 것이 아니라,kill -TERM을 실행한 후wait를 통해 종료를 기다리며,sleep 2후kill -KILL를 실행합니다. 이는kill -KILL가command_pid의 자식 프로세스를 포함하지 않으며,swift package dump-symbol-graph가 내부적으로 띄운 하위 프로세스가 남아 있을 수 있음을 의미합니다. Why it matters: 하위 프로세스가 남아 있으면 CI 환경이나 로컬 머신에서 리소스 경합, 메모리 누수, 빌드 실패 등의 문제가 발생할 수 있으며, 이는 지속적인 빌드 실패나 시스템 불안정을 초래할 수 있습니다. Suggested fix:run_with_timeout내부에서command_pid를 포함한 프로세스 그룹 전체를 종료하도록kill -TERM과kill -KILL를-$command_pgid로 실행해야 하며,set -m이 활성화된 상태에서command_pgid를 정확히 추출하는 것이 중요합니다. 현재terminate_command는command_pgid를ps -o pgid= -p로 추출하고 있으나,set -m이 활성화된 상태에서command_pid의 프로세스 그룹 ID를 정확히 얻을 수 있도록 보장해야 합니다. Confidence: HighConfidence score: 0.95
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
검토 후 추가 수정했습니다.
c5b3211에서 job control 기반 실행을 제거하고,perl -MPOSIX=setsid로 감시 대상 명령을 별도 session/process group에서 실행하도록 변경했습니다.terminate_command는ps -o pgid= -p "$command_pid"로 얻은 PGID에 대해TERM/KILL을 보내므로 하위 프로세스 정리 대상이 명확해졌습니다.DUMP_SYMBOL_GRAPH_TIMEOUT_SECONDS=1로 timeout 124 반환 및 관련 SwiftPM 프로세스 미잔존도 확인했습니다.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 지적은 현재 코드에는 맞지 않는 것으로 보입니다.
start_command가setsid()후 명령을 실행하고,terminate_command는ps -o pgid=로 얻은 프로세스 그룹에kill -TERM "-$command_pgid"와kill -KILL "-$command_pgid"를 보내므로 직접 자식만 종료한다는 전제는 현재 구현과 다릅니다.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 지적은 terminate_command의 동작 흐름을 오해한 것으로 보입니다. 현재 스크립트는 start_command 실행 시 setsid()를 사용해 독립된 세션을 구성하며, ps 명령으로 추출한 command_pgid를 이용해 그룹 전체(-$command_pgid)에 TERM 및 KILL 시그널을 정상 전달하고 있습니다. 따라서 자식/하위 프로세스가 유실되지 않고 안전하게 종료되므로 추가 조치 없이 유지해도 괜찮습니다.