diff --git a/.reviewbot.yml b/.reviewbot.yml index 525aefb..581ca7c 100644 --- a/.reviewbot.yml +++ b/.reviewbot.yml @@ -11,6 +11,8 @@ review: - ".gitignore" - "AGENTS.md" - "README.md" + - "CHANGELOG.md" + - "VERSION.txt" - "GeneratingDocumentationSite" - "Sources/**/*.docc/**/*.md" @@ -83,6 +85,8 @@ review: - "AGENTS.md" - ".gitignore" - "README.md" + - "CHANGELOG.md" + - "VERSION.txt" - "GeneratingDocumentationSite" - "Package.swift" - ".github/workflows/**/*.yml" diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8c99b58 --- /dev/null +++ b/CHANGELOG.md @@ -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 기반으로 전환했습니다. diff --git a/GeneratingDocumentationSite b/GeneratingDocumentationSite index 8a3f010..8da8919 100755 --- a/GeneratingDocumentationSite +++ b/GeneratingDocumentationSite @@ -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 + 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" diff --git a/VERSION.txt b/VERSION.txt new file mode 100644 index 0000000..f374f66 --- /dev/null +++ b/VERSION.txt @@ -0,0 +1 @@ +0.9.1