From 125b26084533f6ffae14828230e859e5e6b51d88 Mon Sep 17 00:00:00 2001 From: Nick <25382531+kiku-jw@users.noreply.github.com> Date: Sat, 29 Aug 2026 20:45:59 +0300 Subject: [PATCH] chore: prepare Hourleaf 1.0.5 release --- AppStore/README.md | 2 +- AppStore/metadata/en-US/description.txt | 3 + AppStore/metadata/en-US/keywords.txt | 2 +- AppStore/metadata/en-US/promotional_text.txt | 2 +- AppStore/metadata/en-US/release_notes.txt | 2 +- AppStore/metadata/ru/description.txt | 3 + AppStore/metadata/ru/keywords.txt | 2 +- AppStore/metadata/ru/promotional_text.txt | 2 +- AppStore/metadata/ru/release_notes.txt | 2 +- AppStore/metadata/uk/description.txt | 3 + AppStore/metadata/uk/keywords.txt | 2 +- AppStore/metadata/uk/promotional_text.txt | 2 +- AppStore/metadata/uk/release_notes.txt | 2 +- AppStore/release-checklist.md | 58 ++++++++++++++++++-- AppStore/release-monitoring.md | 19 +++++++ AppStore/review-notes.md | 17 ++++++ Hourleaf.xcodeproj/project.pbxproj | 12 ++-- README.md | 1 + scripts/test-verify-release-readiness.sh | 8 +-- scripts/verify-release-readiness.sh | 8 +-- 20 files changed, 124 insertions(+), 28 deletions(-) diff --git a/AppStore/README.md b/AppStore/README.md index e890206..4af42fc 100644 --- a/AppStore/README.md +++ b/AppStore/README.md @@ -9,7 +9,7 @@ App Store Connect only after the matching archive is verified. - Platform record: iOS with an embedded watchOS companion app - App Store name: `Hourleaf: Ministry Hours` - Bundle identifier: `com.kikuai.hourleaf` -- Source candidate: `1.0.4` (`17`) +- Source candidate: `1.0.5` (`18`) - Primary language: English (U.S.) - Localizations: English (U.S.), Russian, Ukrainian - Primary category: Productivity diff --git a/AppStore/metadata/en-US/description.txt b/AppStore/metadata/en-US/description.txt index 46a68d6..ef6b80c 100644 --- a/AppStore/metadata/en-US/description.txt +++ b/AppStore/metadata/en-US/description.txt @@ -4,6 +4,8 @@ Record service or credit time in seconds, add an optional note, and review every On Apple Watch, choose service or credit, set hours and minutes with the Digital Crown, and save the entry to your iPhone. +With Siri and Shortcuts, you can record a spoken number of minutes or prepare monthly report text without opening Hourleaf. The report action only reads the calculated report; it never changes entries or sends anything. + Hourleaf includes: • Fast entry for service and credit time @@ -13,6 +15,7 @@ Hourleaf includes: • Service-year progress toward a 600-hour goal • Monthly and inactivity reminders you control • Apple Watch entry +• Siri and Shortcuts for voice entry and report text • Local backup, restore, and CSV export/import • English, Russian, and Ukrainian diff --git a/AppStore/metadata/en-US/keywords.txt b/AppStore/metadata/en-US/keywords.txt index 3e18d58..807b171 100644 --- a/AppStore/metadata/en-US/keywords.txt +++ b/AppStore/metadata/en-US/keywords.txt @@ -1 +1 @@ -service,field,pioneer,publisher,preaching,bible,study,report,credit,tracker,volunteer,ledger +service,field,pioneer,publisher,preaching,bible,study,report,credit,tracker,siri,shortcut diff --git a/AppStore/metadata/en-US/promotional_text.txt b/AppStore/metadata/en-US/promotional_text.txt index ed4baad..468dc5a 100644 --- a/AppStore/metadata/en-US/promotional_text.txt +++ b/AppStore/metadata/en-US/promotional_text.txt @@ -1 +1 @@ -Record ministry and credit time in seconds, see your service-year progress, prepare monthly reports, and add time from Apple Watch. +Record ministry time with Siri or Apple Watch, prepare monthly reports with Shortcuts, and keep every entry private on your devices. diff --git a/AppStore/metadata/en-US/release_notes.txt b/AppStore/metadata/en-US/release_notes.txt index 66f6669..cff7e07 100644 --- a/AppStore/metadata/en-US/release_notes.txt +++ b/AppStore/metadata/en-US/release_notes.txt @@ -1 +1 @@ -Small and medium widgets show this month's service, credit, and Bible studies; the medium widget also shows progress toward 600 hours. Siri now asks exactly how many minutes to record, and service and credit use separate reliable actions. +Prepare a monthly report with Shortcuts without changing your records. Settings now makes it easy to share Hourleaf, leave an App Store rating, and open the guide in English, Russian, or Ukrainian. diff --git a/AppStore/metadata/ru/description.txt b/AppStore/metadata/ru/description.txt index d85128d..0bd8664 100644 --- a/AppStore/metadata/ru/description.txt +++ b/AppStore/metadata/ru/description.txt @@ -4,6 +4,8 @@ Hourleaf — простой и приватный способ вести учё На Apple Watch выберите служение или кредит, установите часы и минуты колёсиком Digital Crown и сохраните запись на iPhone. +С помощью Siri и «Быстрых команд» можно надиктовать количество минут или подготовить текст месячного отчёта, не открывая Hourleaf. Действие отчёта только читает рассчитанный результат: оно не меняет записи и ничего не отправляет. + В Hourleaf есть: • Быстрое добавление служения и кредита @@ -13,6 +15,7 @@ Hourleaf — простой и приватный способ вести учё • Прогресс к цели 600 часов за служебный год • Настраиваемые месячные напоминания и напоминания после перерыва • Ввод с Apple Watch +• Siri и «Быстрые команды» для голосового ввода и текста отчёта • Локальная резервная копия, восстановление, экспорт и импорт CSV • Русский, украинский и английский языки diff --git a/AppStore/metadata/ru/keywords.txt b/AppStore/metadata/ru/keywords.txt index 0f534a0..6de19b1 100644 --- a/AppStore/metadata/ru/keywords.txt +++ b/AppStore/metadata/ru/keywords.txt @@ -1 +1 @@ -проповедь,пионер,возвещатель,изучение,Библия,календарь,кредит,отчёт,журнал,виджет,голосом +проповедь,пионер,возвещатель,изучение,Библия,календарь,кредит,отчёт,журнал,виджет,голосом,команды diff --git a/AppStore/metadata/ru/promotional_text.txt b/AppStore/metadata/ru/promotional_text.txt index 19201c2..0089c57 100644 --- a/AppStore/metadata/ru/promotional_text.txt +++ b/AppStore/metadata/ru/promotional_text.txt @@ -1 +1 @@ -Записывайте служение и кредит за секунды, следите за прогрессом служебного года, готовьте месячный отчёт и добавляйте время с Apple Watch. +Записывайте служение через Siri или Apple Watch, готовьте месячные отчёты в «Быстрых командах» и храните записи приватно на своих устройствах. diff --git a/AppStore/metadata/ru/release_notes.txt b/AppStore/metadata/ru/release_notes.txt index 39cb027..62caa55 100644 --- a/AppStore/metadata/ru/release_notes.txt +++ b/AppStore/metadata/ru/release_notes.txt @@ -1 +1 @@ -Малый и средний виджеты показывают служение, кредит и изучения Библии за месяц; средний также показывает прогресс к 600 часам. Siri теперь прямо спрашивает «Сколько минут?», а служение и кредит записываются отдельными надёжными действиями. +Теперь месячный отчёт можно подготовить в «Быстрых командах», не изменяя записи. В настройках стало проще поделиться Hourleaf, оставить оценку в App Store и открыть инструкцию на русском, украинском или английском. diff --git a/AppStore/metadata/uk/description.txt b/AppStore/metadata/uk/description.txt index 3c7c2e2..0d394a0 100644 --- a/AppStore/metadata/uk/description.txt +++ b/AppStore/metadata/uk/description.txt @@ -4,6 +4,8 @@ Hourleaf — простий і приватний спосіб вести обл На Apple Watch виберіть служіння або кредит, установіть години та хвилини коліщатком Digital Crown і збережіть запис на iPhone. +За допомогою Siri й «Команд» можна продиктувати кількість хвилин або підготувати текст місячного звіту, не відкриваючи Hourleaf. Дія звіту лише читає розрахований результат: вона не змінює записів і нічого не надсилає. + У Hourleaf є: • Швидке додавання служіння та кредиту @@ -13,6 +15,7 @@ Hourleaf — простий і приватний спосіб вести обл • Прогрес до цілі 600 годин за службовий рік • Налаштовувані місячні нагадування та нагадування після перерви • Введення з Apple Watch +• Siri й «Команди» для голосового введення та тексту звіту • Локальна резервна копія, відновлення, експорт та імпорт CSV • Українська, російська й англійська мови diff --git a/AppStore/metadata/uk/keywords.txt b/AppStore/metadata/uk/keywords.txt index 66f55c8..bb98a09 100644 --- a/AppStore/metadata/uk/keywords.txt +++ b/AppStore/metadata/uk/keywords.txt @@ -1 +1 @@ -проповідь,піонер,вісник,вивчення,Біблія,календар,кредит,звіт,журнал,віджет,голосом +проповідь,піонер,вісник,вивчення,Біблія,календар,кредит,звіт,журнал,віджет,голосом,команди diff --git a/AppStore/metadata/uk/promotional_text.txt b/AppStore/metadata/uk/promotional_text.txt index ff28c10..ffd3739 100644 --- a/AppStore/metadata/uk/promotional_text.txt +++ b/AppStore/metadata/uk/promotional_text.txt @@ -1 +1 @@ -Записуйте служіння та кредит за лічені секунди, стежте за прогресом службового року, готуйте місячний звіт і додавайте час з Apple Watch. +Записуйте служіння через Siri або Apple Watch, готуйте місячні звіти в «Командах» і зберігайте записи приватно на своїх пристроях. diff --git a/AppStore/metadata/uk/release_notes.txt b/AppStore/metadata/uk/release_notes.txt index 7d3dad1..82e60e1 100644 --- a/AppStore/metadata/uk/release_notes.txt +++ b/AppStore/metadata/uk/release_notes.txt @@ -1 +1 @@ -Малий і середній віджети показують служіння, кредит і вивчення Біблії за місяць; середній також показує прогрес до 600 годин. Siri тепер прямо запитує «Скільки хвилин?», а служіння й кредит записуються окремими надійними діями. +Тепер місячний звіт можна підготувати в «Командах», не змінюючи записів. У налаштуваннях стало простіше поділитися Hourleaf, залишити оцінку в App Store і відкрити інструкцію українською, російською або англійською. diff --git a/AppStore/release-checklist.md b/AppStore/release-checklist.md index 184c95e..34f3641 100644 --- a/AppStore/release-checklist.md +++ b/AppStore/release-checklist.md @@ -1,10 +1,60 @@ # Hourleaf delivery checklist -## Active release: 1.0.4 (17) +## Active release: 1.0.5 (18) -This active section is the maintained release contract. It is superseded when -the next version becomes the source candidate; dated receipts below remain -immutable history. +This active section is the maintained release contract. Dated receipts below +remain immutable history. + +### Scope and source + +- [x] All iPhone, WidgetKit, and Watch shipping configurations use version + `1.0.5` build `18`. +- [x] The read-only monthly-report Shortcut, localized Share/Rate actions, + Ukrainian guide routing, and delayed once-per-version review request are + merged to `main`. +- [x] English, Russian, and Ukrainian metadata describes only implemented + behavior and passes the repository character-limit guard. + +### Automated verification + +- [x] Focused App Intent suite passes: 30 of 30 tests. +- [x] Focused localized settings accessibility test passes in English, + Russian, and Ukrainian. +- [x] Full CI passes on the exact merged tree: 531 unit/integration tests and + 53 app-owned UI tests, with zero failures (run `33264052461`). +- [x] Release guard, guard self-test, local installer self-test, and diff checks + pass. + +### Physical acceptance + +- [ ] Install the separate local-development bundle on the physical iPhone; + do not replace the App Store/TestFlight bundle or touch its ledger. +- [ ] Verify Share Hourleaf, Rate Hourleaf, and Ukrainian guide routing. +- [ ] Prepare one synthetic monthly report through Shortcuts and confirm the + returned text is correct and the ledger is unchanged. +- [ ] Mark a synthetic report sent and verify the review request path does not + interrupt the action or repeat in the same app version. StoreKit may + legitimately suppress the system prompt. +- [ ] Verify the medium Continuity widget on Mac if the nearby-iPhone gallery + exposes the current Hourleaf widget. + +### Owner-controlled distribution + +- [ ] Wait for the submitted `1.0.4` (`17`) review to resolve; approval and + public availability are separate readbacks. +- [ ] Create and inspect the signed `1.0.5` (`18`) App Store archive only after + physical acceptance. +- [ ] Upload build `18`, wait for processing, and attach it to a new version + only after a fresh owner-controlled release gate. +- [ ] Save EN/RU/UK metadata and reviewer notes, submit, and verify the displayed + review status. +- [ ] Publish the matching EN/RU/UK website and campaign links only when the + advertised build is actually available. + +## Submitted release: 1.0.4 (17) + +This section is retained as the release record for the version currently in +App Review. It does not claim approval or public availability. ### Source and package diff --git a/AppStore/release-monitoring.md b/AppStore/release-monitoring.md index 73bad81..1af854f 100644 --- a/AppStore/release-monitoring.md +++ b/AppStore/release-monitoring.md @@ -75,6 +75,25 @@ Convert only concrete, reproducible work into the existing Hourleaf roadmap Issue. Never reply as the user, promise a date, or disclose reviewer information without a separate owner-approved response. +## Acquisition measurement + +Use App Store Connect campaign links and aggregate storefront metrics only. +Hourleaf does not add an attribution SDK, device identifier, account, tracking +pixel, or per-user event log. + +- Keep one campaign token per owned surface: `web-en`, `web-ru`, `web-uk`, and + `github`. +- Generate the provider token in App Store Connect; never invent it. Read back + each final URL before publishing it in the website or README. +- Record the public version, observation window, product-page views, first-time + downloads, and conversion rate in the canonical Issue. A metric is unknown + when Apple withholds a small cohort; do not infer zero or identify a person. +- Compare at least seven days of organic baseline with the same window after + campaign links go live. Do not claim adoption from GitHub clones, CI traffic, + an upload, an approval, or a single owner installation. +- Paid ads, creator outreach, and community posting require their own bounded + owner decision; they are not part of the default release process. + ## Release closeout A release is closed only when the canonical Issue contains provider readback diff --git a/AppStore/review-notes.md b/AppStore/review-notes.md index b6e0f91..8e8f553 100644 --- a/AppStore/review-notes.md +++ b/AppStore/review-notes.md @@ -4,6 +4,23 @@ This file is the maintained source for the App Review Information Notes field. Update it when the review path, shipped capabilities, or verified physical-device matrix changes. Keep private reviewer contact details only in App Store Connect. +## Version 1.0.5 candidate update + +Build 18 adds a read-only monthly-report action for Apple Shortcuts, localized +Share Hourleaf and Rate Hourleaf actions in Settings, and correct Ukrainian +guide routing. The report action returns only the existing calculated report +text, requires local device authentication, compares the ledger before and +after reading, never changes an entry, and never sends anything. Hourleaf may +ask for an App Store rating only after the user successfully marks a report as +sent; the native StoreKit request waits two seconds, is cancelled if the user +leaves the screen, and is attempted at most once per app version. This update +adds no account, purchase, backend, third-party SDK, sensitive-data permission, +or new data category. + +Physical-device acceptance and the final build-18 test matrix are still +pending. Keep the paste-ready 1.0.4 notes below unchanged until those checks +pass and build 18 is actually selected for submission. + ## Version 1.0.4 update Build 17 adds small and medium Hourleaf widgets and makes Siri entry diff --git a/Hourleaf.xcodeproj/project.pbxproj b/Hourleaf.xcodeproj/project.pbxproj index 727817b..dce44a4 100644 --- a/Hourleaf.xcodeproj/project.pbxproj +++ b/Hourleaf.xcodeproj/project.pbxproj @@ -301,16 +301,16 @@ /* Begin XCBuildConfiguration section */ A10000000000000000000080 /* Debug */ = {isa = XCBuildConfiguration; buildSettings = {ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu17; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ("DEBUG=1", "$(inherited)"); HOURLEAF_APP_BUNDLE_IDENTIFIER = com.kikuai.hourleaf; HOURLEAF_APP_GROUP_IDENTIFIER = group.com.kikuai.hourleaf; HOURLEAF_QUICK_ENTRY_URL_SCHEME = hourleaf; HOURLEAF_QUICK_SURFACES_BUNDLE_IDENTIFIER = com.kikuai.hourleaf.quick-surfaces; HOURLEAF_WATCH_BUNDLE_IDENTIFIER = com.kikuai.hourleaf.watchkitapp; IPHONEOS_DEPLOYMENT_TARGET = 17.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; A10000000000000000000081 /* Release */ = {isa = XCBuildConfiguration; buildSettings = {ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu17; GCC_NO_COMMON_BLOCKS = YES; HOURLEAF_APP_BUNDLE_IDENTIFIER = com.kikuai.hourleaf; HOURLEAF_APP_GROUP_IDENTIFIER = group.com.kikuai.hourleaf; HOURLEAF_QUICK_ENTRY_URL_SCHEME = hourleaf; HOURLEAF_QUICK_SURFACES_BUNDLE_IDENTIFIER = com.kikuai.hourleaf.quick-surfaces; HOURLEAF_WATCH_BUNDLE_IDENTIFIER = com.kikuai.hourleaf.watchkitapp; IPHONEOS_DEPLOYMENT_TARGET = 17.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; VALIDATE_PRODUCT = YES; }; name = Release; }; - A10000000000000000000082 /* Debug */ = {isa = XCBuildConfiguration; buildSettings = {ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Hourleaf/Hourleaf.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 17; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = Hourleaf/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0.4; PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_APP_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; - A10000000000000000000083 /* Release */ = {isa = XCBuildConfiguration; buildSettings = {ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Hourleaf/Hourleaf.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 17; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = Hourleaf/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0.4; PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_APP_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; + A10000000000000000000082 /* Debug */ = {isa = XCBuildConfiguration; buildSettings = {ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Hourleaf/Hourleaf.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = Hourleaf/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0.5; PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_APP_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; + A10000000000000000000083 /* Release */ = {isa = XCBuildConfiguration; buildSettings = {ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Hourleaf/Hourleaf.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = Hourleaf/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0.5; PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_APP_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; A10000000000000000000084 /* Debug */ = {isa = XCBuildConfiguration; buildSettings = {BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.kikuai.hourleaf.tests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 1; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Hourleaf.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Hourleaf"; }; name = Debug; }; A10000000000000000000085 /* Release */ = {isa = XCBuildConfiguration; buildSettings = {BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.kikuai.hourleaf.tests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 1; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Hourleaf.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Hourleaf"; }; name = Release; }; A10000000000000000000086 /* Debug */ = {isa = XCBuildConfiguration; buildSettings = {CODE_SIGN_STYLE = Automatic; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.kikuai.hourleaf.uitests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 1; TEST_TARGET_NAME = Hourleaf; }; name = Debug; }; A10000000000000000000087 /* Release */ = {isa = XCBuildConfiguration; buildSettings = {CODE_SIGN_STYLE = Automatic; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.kikuai.hourleaf.uitests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 1; TEST_TARGET_NAME = Hourleaf; }; name = Release; }; - A10000000000000000000088 /* Debug */ = {isa = XCBuildConfiguration; buildSettings = {APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_ENTITLEMENTS = HourleafQuickSurfaces/HourleafQuickSurfaces.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 17; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = HourleafQuickSurfaces/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../../Frameworks"; MARKETING_VERSION = 1.0.4; PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_QUICK_SURFACES_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; - A10000000000000000000089 /* Release */ = {isa = XCBuildConfiguration; buildSettings = {APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_ENTITLEMENTS = HourleafQuickSurfaces/HourleafQuickSurfaces.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 17; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = HourleafQuickSurfaces/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../../Frameworks"; MARKETING_VERSION = 1.0.4; PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_QUICK_SURFACES_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; - A20000000000000000000088 /* Debug */ = {isa = XCBuildConfiguration; buildSettings = {ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 17; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = Hourleaf; INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = "$(HOURLEAF_APP_BUNDLE_IDENTIFIER)"; INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0.4; PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_WATCH_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 10.0; }; name = Debug; }; - A20000000000000000000089 /* Release */ = {isa = XCBuildConfiguration; buildSettings = {ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 17; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = Hourleaf; INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = "$(HOURLEAF_APP_BUNDLE_IDENTIFIER)"; INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0.4; PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_WATCH_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 10.0; }; name = Release; }; + A10000000000000000000088 /* Debug */ = {isa = XCBuildConfiguration; buildSettings = {APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_ENTITLEMENTS = HourleafQuickSurfaces/HourleafQuickSurfaces.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = HourleafQuickSurfaces/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../../Frameworks"; MARKETING_VERSION = 1.0.5; PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_QUICK_SURFACES_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; + A10000000000000000000089 /* Release */ = {isa = XCBuildConfiguration; buildSettings = {APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_ENTITLEMENTS = HourleafQuickSurfaces/HourleafQuickSurfaces.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = HourleafQuickSurfaces/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../../Frameworks"; MARKETING_VERSION = 1.0.5; PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_QUICK_SURFACES_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; + A20000000000000000000088 /* Debug */ = {isa = XCBuildConfiguration; buildSettings = {ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = Hourleaf; INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = "$(HOURLEAF_APP_BUNDLE_IDENTIFIER)"; INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0.5; PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_WATCH_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 10.0; }; name = Debug; }; + A20000000000000000000089 /* Release */ = {isa = XCBuildConfiguration; buildSettings = {ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 18; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = Hourleaf; INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = "$(HOURLEAF_APP_BUNDLE_IDENTIFIER)"; INFOPLIST_KEY_WKRunsIndependentlyOfCompanionApp = NO; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0.5; PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_WATCH_BUNDLE_IDENTIFIER)"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_STRICT_CONCURRENCY = complete; SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 10.0; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ diff --git a/README.md b/README.md index 5a9732e..25e5795 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ prepares monthly reports without an account or remote backend. - Fast service and credit entry on iPhone - Direct hours-and-minutes entry with the Digital Crown on Apple Watch +- Siri and Shortcuts for spoken minute entry and read-only monthly report text - List and calendar history with editing and reversible deletion - Monthly report preparation and system sharing - Service-year progress toward the 600-hour goal diff --git a/scripts/test-verify-release-readiness.sh b/scripts/test-verify-release-readiness.sh index f6a7fcb..84f4838 100755 --- a/scripts/test-verify-release-readiness.sh +++ b/scripts/test-verify-release-readiness.sh @@ -258,14 +258,14 @@ assert_failure_contains "extension privacy manifest has an unexpected NSPrivacyA reset_fixture replace_in_file \ "$fixture_root/Hourleaf.xcodeproj/project.pbxproj" \ - 's/MARKETING_VERSION = 1.0.4;/MARKETING_VERSION = 0.9.0;/g' -assert_failure_contains "all shipping targets must use marketing version 1.0.4" + 's/MARKETING_VERSION = 1.0.5;/MARKETING_VERSION = 0.9.0;/g' +assert_failure_contains "all shipping targets must use marketing version 1.0.5" reset_fixture replace_in_file \ "$fixture_root/Hourleaf.xcodeproj/project.pbxproj" \ - 's/CURRENT_PROJECT_VERSION = 17;/CURRENT_PROJECT_VERSION = 16;/g' -assert_failure_contains "all shipping targets must use build number 17" + 's/CURRENT_PROJECT_VERSION = 18;/CURRENT_PROJECT_VERSION = 17;/g' +assert_failure_contains "all shipping targets must use build number 18" reset_fixture replace_in_file \ diff --git a/scripts/verify-release-readiness.sh b/scripts/verify-release-readiness.sh index 75d0672..680d5ce 100755 --- a/scripts/verify-release-readiness.sh +++ b/scripts/verify-release-readiness.sh @@ -275,12 +275,12 @@ watch_bundle_config_count="$(grep -F 'PRODUCT_BUNDLE_IDENTIFIER = "$(HOURLEAF_WA watch_deployment_count="$(grep -F 'WATCHOS_DEPLOYMENT_TARGET = 10.0;' "$project_file" | wc -l | tr -d '[:space:]' || true)" [[ "$watch_deployment_count" == "2" ]] \ || fail "HourleafWatch must support watchOS 10 or later in both configurations" -release_version_count="$(grep -Fo 'MARKETING_VERSION = 1.0.4;' "$project_file" | wc -l | tr -d '[:space:]' || true)" +release_version_count="$(grep -Fo 'MARKETING_VERSION = 1.0.5;' "$project_file" | wc -l | tr -d '[:space:]' || true)" [[ "$release_version_count" == "6" ]] \ - || fail "all shipping targets must use marketing version 1.0.4" -release_build_count="$(grep -Fo 'CURRENT_PROJECT_VERSION = 17;' "$project_file" | wc -l | tr -d '[:space:]' || true)" + || fail "all shipping targets must use marketing version 1.0.5" +release_build_count="$(grep -Fo 'CURRENT_PROJECT_VERSION = 18;' "$project_file" | wc -l | tr -d '[:space:]' || true)" [[ "$release_build_count" == "6" ]] \ - || fail "all shipping targets must use build number 17" + || fail "all shipping targets must use build number 18" grep -Fq 'forInfoDictionaryKey: "CFBundleShortVersionString"' "$settings_file" \ || fail "Settings must read the installed version from bundle metadata" if grep -Eq 'LabeledContent\([^)]*settings\.version[^)]*value:[[:space:]]*"[0-9]+\.[0-9]+\.[0-9]+"' "$settings_file"; then