openclaw/scripts/ios-write-version-xcconfig.sh
Josh Avant cd2724e432
feat(release): automate iOS and Android store releases (#158807)
Add manually triggered iOS Store Release and Android Store Release workflows with the same local release commands. Derive store versions and OpenAI release notes at build time, retain recovery artifacts, and avoid generated metadata commits.

Pin queued releases to their dispatch commit, qualify native iOS behavior before signing, and improve Android screenshots and interrupted artifact recovery.

Validation includes focused release/planner tests, workflow and type checks, native iOS qualification, Android screenshot capture, and historical release-note exercises. CI failure attribution and remaining hosted release verification are documented in the PR.

Closes #158806
2026-09-26 06:28:29 -05:00

148 lines
3.8 KiB
Bash
Executable file

#!/bin/bash
set -euo pipefail
usage() {
cat <<'EOF'
Usage:
scripts/ios-write-version-xcconfig.sh [--version 2026.7.2] [--revision 1] [--build-number 3]
Writes apps/ios/build/Version.xcconfig from root package.json or explicit --version:
- OPENCLAW_IOS_VERSION = exact canonical iOS version
- OPENCLAW_MARKETING_VERSION = short iOS/App Store version
- OPENCLAW_BUILD_VERSION = explicit build number or local numeric fallback
EOF
}
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source "${ROOT_DIR}/scripts/lib/build-metadata.sh"
IOS_DIR="${ROOT_DIR}/apps/ios"
BUILD_DIR="${IOS_DIR}/build"
VERSION_XCCONFIG="${IOS_DIR}/build/Version.xcconfig"
VERSION_HELPER="${ROOT_DIR}/scripts/ios-version.ts"
IOS_VERSION=""
MARKETING_VERSION=""
BUILD_NUMBER=""
APP_STORE_REVISION=""
RELEASE_VERSION=""
RESOLVED_GIT_COMMIT=""
RESOLVED_BUILD_TIMESTAMP=""
require_option_value() {
local option="$1"
local value="${2-}"
if [[ -z "${value}" || "${value}" == --* ]]; then
echo "Missing value for ${option}." >&2
usage >&2
exit 1
fi
}
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}"
}
while [[ $# -gt 0 ]]; do
case "$1" in
--)
shift
;;
--build-number)
require_option_value "$1" "${2-}"
BUILD_NUMBER="${2:-}"
shift 2
;;
--revision)
require_option_value "$1" "${2-}"
APP_STORE_REVISION="${2:-}"
shift 2
;;
--version)
require_option_value "$1" "${2-}"
RELEASE_VERSION="${2:-}"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown argument: $1" >&2
usage
exit 1
;;
esac
done
VERSION_HELPER_ARGS=(--shell)
if [[ -n "${RELEASE_VERSION}" ]]; then
VERSION_HELPER_ARGS+=(--version "${RELEASE_VERSION}")
fi
if [[ -n "${APP_STORE_REVISION}" ]]; then
if [[ -z "${RELEASE_VERSION}" ]]; then
echo "--revision requires an explicit --version." >&2
exit 1
fi
VERSION_HELPER_ARGS+=(--revision "${APP_STORE_REVISION}")
fi
while IFS='=' read -r key value; do
case "${key}" in
OPENCLAW_IOS_VERSION)
IOS_VERSION="${value}"
;;
OPENCLAW_MARKETING_VERSION)
MARKETING_VERSION="${value}"
;;
esac
done < <(cd "${ROOT_DIR}" && node --import tsx "${VERSION_HELPER}" "${VERSION_HELPER_ARGS[@]}")
if [[ -z "${IOS_VERSION}" || -z "${MARKETING_VERSION}" ]]; then
echo "Unable to resolve iOS version metadata." >&2
exit 1
fi
if [[ -z "${BUILD_NUMBER}" ]]; then
BUILD_NUMBER="$(cd "${ROOT_DIR}" && git rev-list --count HEAD 2>/dev/null || printf '0')"
fi
if [[ ! "${BUILD_NUMBER}" =~ ^[0-9]+$ ]]; then
echo "Invalid build number '${BUILD_NUMBER}'. Expected digits only." >&2
exit 1
fi
RESOLVED_GIT_COMMIT="$(openclaw_resolve_git_commit "${ROOT_DIR}")"
RESOLVED_BUILD_TIMESTAMP="$(openclaw_resolve_build_timestamp)"
prepare_build_dir
write_generated_file "${VERSION_XCCONFIG}" <<EOF
// Auto-generated by scripts/ios-write-version-xcconfig.sh.
// Local version override; do not commit.
OPENCLAW_IOS_VERSION = ${IOS_VERSION}
OPENCLAW_MARKETING_VERSION = ${MARKETING_VERSION}
OPENCLAW_BUILD_VERSION = ${BUILD_NUMBER}
OPENCLAW_GIT_COMMIT = ${RESOLVED_GIT_COMMIT}
OPENCLAW_BUILD_TIMESTAMP = ${RESOLVED_BUILD_TIMESTAMP}
EOF
echo "Prepared iOS version settings: ios=${IOS_VERSION} marketing=${MARKETING_VERSION} build=${BUILD_NUMBER} commit=${RESOLVED_GIT_COMMIT} built=${RESOLVED_BUILD_TIMESTAMP}"