## Summary - replace the unsupported top-level App Store version collection with Apple's app-scoped version endpoint - add tested release-policy and availability readback for exact version/build, `AFTER_APPROVAL`, Denmark only, no preorder, and no automatic future territories - strengthen the stable `App Store Readiness` check and align Fastlane/candidate handoff with the approved 1.0.0 release policy ## Task contract `truckwash-ios-release-20260723` — R4 (`ci-policy`, `release-policy`, `credential-handling`, `branch-protection-or-rules`, `mobile-store-submission`). The user explicitly approved implementation, protected-master delivery, and the App Store release path. ## Changed files - App Store Connect client and dependency-free Node tests - App Store readiness and candidate workflows - Fastlane candidate release configuration - Apple App Store release runbook ## Verification - `node --test tests/node/app-store-connect.test.mjs` — 10 passed - `node scripts/mobile/validate-app-store.mjs --strict` — passed - `node scripts/mobile/check-permissions.mjs` — passed - App Store product-readiness Vitest — 5 passed - ESLint on changed Node files — passed - workflow YAML parsing — passed - `git diff --check` — passed - local Fastlane validation unavailable because Ruby/Bundler is not installed on this host; `App Store Readiness` runs it on GitHub ## Release target - iOS App Store - bundle `io.truckwash.app` - version `1.0.0` - App Store Connect app `6792777794` - Denmark only - automatic release after approval - no preorder or phased release for 1.0.0 The repository App Store automation switch remains disabled until this change is merged and credential health is reverified.
56 lines
1.8 KiB
Ruby
56 lines
1.8 KiB
Ruby
default_platform(:ios)
|
|
|
|
def app_store_api_key
|
|
issuer_id = ENV["APP_STORE_CONNECT_ISSUER_ID"].to_s.strip
|
|
app_store_connect_api_key(
|
|
key_id: ENV.fetch("APP_STORE_CONNECT_API_KEY_ID"),
|
|
issuer_id: issuer_id.empty? ? nil : issuer_id,
|
|
key_content: ENV.fetch("APP_STORE_CONNECT_API_PRIVATE_KEY_BASE64"),
|
|
is_key_content_base64: true,
|
|
duration: 1200,
|
|
in_house: false
|
|
)
|
|
end
|
|
|
|
platform :ios do
|
|
desc "Validate and upload the signed IPA, then wait for App Store Connect processing"
|
|
lane :upload_internal do
|
|
api_key = app_store_api_key
|
|
upload_to_testflight(
|
|
api_key: api_key,
|
|
app_identifier: ENV.fetch("IOS_BUNDLE_ID"),
|
|
ipa: ENV.fetch("IOS_IPA_PATH"),
|
|
changelog: ENV.fetch("TESTFLIGHT_WHAT_TO_TEST", "Automatisk intern build fra verificeret master."),
|
|
distribute_external: false,
|
|
notify_external_testers: false,
|
|
skip_submission: true,
|
|
skip_waiting_for_build_processing: false,
|
|
wait_processing_interval: 30,
|
|
reject_build_waiting_for_review: false
|
|
)
|
|
end
|
|
|
|
desc "Create/update the Denmark App Store candidate without submitting it for review"
|
|
lane :prepare_candidate do
|
|
api_key = app_store_api_key
|
|
deliver(
|
|
api_key: api_key,
|
|
app_identifier: ENV.fetch("IOS_BUNDLE_ID"),
|
|
app_version: ENV.fetch("IOS_MARKETING_VERSION"),
|
|
build_number: ENV.fetch("IOS_BUILD_NUMBER"),
|
|
metadata_path: "fastlane/metadata",
|
|
screenshots_path: "fastlane/screenshots",
|
|
skip_binary_upload: true,
|
|
skip_metadata: false,
|
|
skip_screenshots: false,
|
|
overwrite_screenshots: true,
|
|
force: true,
|
|
submit_for_review: false,
|
|
automatic_release: true,
|
|
phased_release: false,
|
|
run_precheck_before_submit: false,
|
|
precheck_include_in_app_purchases: false
|
|
)
|
|
end
|
|
end
|