#!/usr/bin/env bash set -euo pipefail usage() { cat <<'EOF' Usage: OPENCLAW_PUSH_RELAY_BASE_URL=https://relay.example.com \ scripts/ios-beta-prepare.sh --build-number 7 [--team-id TEAMID] Prepares local beta-release inputs without touching local signing overrides: - reads package.json.version and writes apps/ios/build/Version.xcconfig - writes apps/ios/build/BetaRelease.xcconfig with canonical bundle IDs - configures the beta build for relay-backed APNs registration - regenerates apps/ios/OpenClaw.xcodeproj via xcodegen EOF } ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" IOS_DIR="${ROOT_DIR}/apps/ios" BUILD_DIR="${IOS_DIR}/build" BETA_XCCONFIG="${IOS_DIR}/build/BetaRelease.xcconfig" TEAM_HELPER="${ROOT_DIR}/scripts/ios-team-id.sh" VERSION_HELPER="${ROOT_DIR}/scripts/ios-write-version-xcconfig.sh" BUILD_NUMBER="" TEAM_ID="${IOS_DEVELOPMENT_TEAM:-}" PUSH_RELAY_BASE_URL="${OPENCLAW_PUSH_RELAY_BASE_URL:-${IOS_PUSH_RELAY_BASE_URL:-}}" PUSH_RELAY_BASE_URL_XCCONFIG="" PACKAGE_VERSION="$(cd "${ROOT_DIR}" && node -p "require('./package.json').version" 2>/dev/null || true)" prepare_build_dir() { if [[ -L "${BUILD_DIR}" ]]; then echo "Refusing to use symlinked build directory: ${BUILD_DIR}" >&2 exit 1 fi mkdir -p "${BUILD_DIR}" } write_generated_file() { local output_path="$1" local tmp_file="" if [[ -e "${output_path}" && -L "${output_path}" ]]; then echo "Refusing to overwrite symlinked file: ${output_path}" >&2 exit 1 fi tmp_file="$(mktemp "${output_path}.XXXXXX")" cat >"${tmp_file}" mv -f "${tmp_file}" "${output_path}" } validate_push_relay_base_url() { local value="$1" if [[ "${value}" =~ [[:space:]] ]]; then echo "Invalid OPENCLAW_PUSH_RELAY_BASE_URL: whitespace is not allowed." >&2 exit 1 fi if [[ "${value}" == *'$'* || "${value}" == *'('* || "${value}" == *')'* || "${value}" == *'='* ]]; then echo "Invalid OPENCLAW_PUSH_RELAY_BASE_URL: contains forbidden xcconfig characters." >&2 exit 1 fi if [[ ! "${value}" =~ ^https://[A-Za-z0-9.-]+(:([0-9]{1,5}))?(/[A-Za-z0-9._~!&*+,;:@%/-]*)?$ ]]; then echo "Invalid OPENCLAW_PUSH_RELAY_BASE_URL: expected https://host[:port][/path]." >&2 exit 1 fi local port="${BASH_REMATCH[2]:-}" if [[ -n "${port}" ]] && (( 10#${port} > 65535 )); then echo "Invalid OPENCLAW_PUSH_RELAY_BASE_URL: port must be between 1 and 65535." >&2 exit 1 fi } while [[ $# -gt 0 ]]; do case "$1" in --) shift ;; --build-number) BUILD_NUMBER="${2:-}" shift 2 ;; --team-id) TEAM_ID="${2:-}" shift 2 ;; -h|--help) usage exit 0 ;; *) echo "Unknown argument: $1" >&2 usage exit 1 ;; esac done if [[ -z "${BUILD_NUMBER}" ]]; then echo "Missing required --build-number." >&2 usage exit 1 fi if [[ -z "${TEAM_ID}" ]]; then TEAM_ID="$(IOS_ALLOW_KEYCHAIN_TEAM_FALLBACK=1 bash "${TEAM_HELPER}")" fi if [[ -z "${TEAM_ID}" ]]; then echo "Could not resolve Apple Team ID. Set IOS_DEVELOPMENT_TEAM or sign into Xcode." >&2 exit 1 fi if [[ -z "${PUSH_RELAY_BASE_URL}" ]]; then echo "Missing OPENCLAW_PUSH_RELAY_BASE_URL (or IOS_PUSH_RELAY_BASE_URL) for beta relay registration." >&2 exit 1 fi validate_push_relay_base_url "${PUSH_RELAY_BASE_URL}" # `.xcconfig` treats `//` as a comment opener. Break the URL with a helper setting # so Xcode still resolves it back to `https://...` at build time. PUSH_RELAY_BASE_URL_XCCONFIG="$( printf '%s' "${PUSH_RELAY_BASE_URL}" \ | sed 's#//#$(OPENCLAW_URL_SLASH)$(OPENCLAW_URL_SLASH)#g' )" prepare_build_dir ( bash "${VERSION_HELPER}" --build-number "${BUILD_NUMBER}" ) write_generated_file "${BETA_XCCONFIG}" <