Skip to content

feat(ios): add local beta release flow#42991

Merged
ngutman merged 6 commits intomainfrom
feat/ios-beta-release-flow
Mar 11, 2026
Merged

feat(ios): add local beta release flow#42991
ngutman merged 6 commits intomainfrom
feat/ios-beta-release-flow

Conversation

@ngutman
Copy link
Contributor

@ngutman ngutman commented Mar 11, 2026

Summary

  • add a local Fastlane beta/TestFlight flow that prepares release-only signing overrides, regenerates the Xcode project, archives, exports, and uploads from source
  • stamp iOS short version/build numbers from the beta release label and query App Store Connect for the next per-version build number
  • fix watch app beta packaging by compiling the watch app icon asset catalog and update iOS beta setup docs and package scripts

Verification

  • pnpm ios:beta:prepare -- --version 2026.3.9-beta.1 --build-number 7
  • pnpm ios:beta:archive -- --version 2026.3.9-beta.1 --build-number 7
  • pnpm ios:beta -- --version 2026.3.9-beta.1
  • uploaded TestFlight build 2026.3.9 (1) to verify the end-to-end flow

@openclaw-barnacle openclaw-barnacle bot added app: ios App: ios scripts Repository scripts labels Mar 11, 2026
@aisle-research-bot
Copy link

aisle-research-bot bot commented Mar 11, 2026

🔒 Aisle Security Analysis

We found 2 potential security issue(s) in this PR:

# Severity Title
1 🔵 Low Xcode build-setting injection via unsanitized TEAM_ID in generated BetaRelease.xcconfig
2 🔵 Low Potential build setting injection via optional include of gitignored apps/ios/build/Version.xcconfig

1. 🔵 Xcode build-setting injection via unsanitized TEAM_ID in generated BetaRelease.xcconfig

Property Value
Severity Low
CWE CWE-15
Location scripts/ios-beta-prepare.sh:23-103

Description

scripts/ios-beta-prepare.sh generates apps/ios/build/BetaRelease.xcconfig and interpolates TEAM_ID directly into xcconfig assignments without validating/sanitizing it.

  • Input: TEAM_ID can come from IOS_DEVELOPMENT_TEAM (environment) or --team-id (CLI) without any normalization.
  • Sink: TEAM_ID is written verbatim into an .xcconfig file.
  • Impact: If an attacker can influence IOS_DEVELOPMENT_TEAM/--team-id (e.g., on a shared CI runner, compromised environment, or when a higher-privileged build script runs with attacker-controlled env), they can inject newlines to add arbitrary xcconfig keys (e.g., override signing settings, bundle IDs, compiler flags) and change how the app is built/signed.

Vulnerable code (excerpt):

TEAM_ID="${IOS_DEVELOPMENT_TEAM:-}"
...
write_generated_file "${BETA_XCCONFIG}" <<EOF
OPENCLAW_DEVELOPMENT_TEAM = ${TEAM_ID}
OPENCLAW_IOS_SELECTED_TEAM = ${TEAM_ID}
EOF

Recommendation

Validate and normalize TEAM_ID before writing it into an xcconfig.

  • Strip CR/LF and surrounding whitespace
  • Enforce Apple Team ID format (^[A-Z0-9]{10}$)
  • (Optional) Apply the same validation in scripts/ios-team-id.sh for the IOS_DEVELOPMENT_TEAM fast-path

Example fix:

TEAM_ID="$(printf '%s' "${TEAM_ID}" | tr -d '\r\n' | xargs)"
if [[ ! "${TEAM_ID}" =~ ^[A-Z0-9]{10}$ ]]; then
  echo "Invalid Apple Team ID '${TEAM_ID}'. Expected 10 uppercase letters/digits." >&2
  exit 1
fi

This prevents newline-based xcconfig injection and ensures the generated build settings are well-formed.


2. 🔵 Potential build setting injection via optional include of gitignored apps/ios/build/Version.xcconfig

Property Value
Severity Low
CWE CWE-829
Location apps/ios/Config/Version.xcconfig:8

Description

apps/ios/Config/Version.xcconfig unconditionally defines version variables and then optionally includes a generated file from apps/ios/build/Version.xcconfig.

Because xcconfig files can define arbitrary Xcode build settings, a tampered or stale apps/ios/build/Version.xcconfig could:

  • Override version identifiers (OPENCLAW_*_VERSION) as intended, but also
  • Inject unrelated build settings (e.g., CODE_SIGN_ENTITLEMENTS, PRODUCT_BUNDLE_IDENTIFIER, OTHER_SWIFT_FLAGS, etc.) depending on evaluation order, potentially impacting signing/entitlements and build output integrity.

Mitigations exist (the new generator script overwrites this file and rejects symlinks), but the include still creates an implicit trust boundary around a gitignored, workspace-local artifact that may persist across builds or be influenced by CI cache/workspace reuse.

Vulnerable code:

#include? "../build/Version.xcconfig"

Recommendation

Reduce the implicit trust in workspace-local build artifacts.

Options (choose one):

  1. Remove the implicit include and instead pass the generated version settings explicitly via xcodebuild/Fastlane using XCODE_XCCONFIG_FILE pointing to a freshly-generated file in a clean temp directory.

  2. If keeping the include, harden the generator and build flow:

    • Ensure scripts/ios-write-version-xcconfig.sh is executed in all build entrypoints (CI/Fastlane/Xcode build phases).
    • Consider deleting/recreating apps/ios/build at the start of the build (after verifying it is not a symlink).
    • Validate generated file contents strictly (whitelist only OPENCLAW_GATEWAY_VERSION, OPENCLAW_MARKETING_VERSION, OPENCLAW_BUILD_VERSION) and fail the build if extra keys are present.

Example approach: generate to a temp file and use XCODE_XCCONFIG_FILE (no repo-local include):

TMP_XCCONFIG="$(mktemp -t OpenClawVersion.XXXXXX.xcconfig)"
./scripts/ios-write-version-xcconfig.sh --build-number "$BUILD_NUMBER" >"$TMP_XCCONFIG"
XCODE_XCCONFIG_FILE="$TMP_XCCONFIG" xcodebuild ...

This prevents unexpected overrides from stale or tampered apps/ios/build/Version.xcconfig.


Analyzed PR: #42991 at commit 82b38fe

Last updated on: 2026-03-11T10:48:19Z

@openclaw-barnacle openclaw-barnacle bot added size: L maintainer Maintainer-authored PR labels Mar 11, 2026
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 11, 2026

Greptile Summary

This PR introduces a complete local Fastlane-based iOS beta release flow covering prepare, archive, and TestFlight upload stages, along with version stamping, watch app icon fix, and bundle ID corrections. The end-to-end flow has been verified with a successful TestFlight upload.

Key changes:

  • New beta_archive and beta Fastlane lanes with shared prepare_beta_context helper; old single-lane implementation replaced
  • scripts/ios-beta-prepare.sh stamps project.yml version fields, writes a temporary BetaRelease.xcconfig, and regenerates the Xcode project via xcodegen
  • scripts/ios-sync-version.ts patches CFBundleShortVersionString and CFBundleVersion in apps/ios/project.yml in-place
  • Bundle IDs corrected from ai.openclaw.ios* to ai.openclaw.client* in Signing.xcconfig
  • Watch app target gains ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon to fix beta packaging
  • apps/ios/project.yml is permanently modified by the prepare step and left dirty in the working tree; developers should revert it after each release run to avoid accidentally committing release version numbers

Confidence Score: 4/5

  • Safe to merge — the flow has been verified end-to-end; remaining issues are design limitations and defensive-coding gaps rather than blocking bugs.
  • The PR has a confirmed successful TestFlight upload and the core logic is sound. The main concern is that beta_archive unconditionally requires ASC API credentials even when a build number is explicitly provided, which is surprising for an offline-archive use case. Additionally, project.yml is left dirty after every prepare run, risking accidental version commits. Neither issue breaks the primary workflow, but both could catch contributors off-guard.
  • apps/ios/fastlane/Fastfile (ASC credential gating in prepare_beta_context) and scripts/ios-beta-prepare.sh (missing empty TEAM_ID guard).

Last reviewed commit: 824d720

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6ad9645a4b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ngutman ngutman force-pushed the feat/ios-beta-release-flow branch from 6e4f061 to 82b38fe Compare March 11, 2026 10:31
@ngutman ngutman merged commit 2d91284 into main Mar 11, 2026
26 checks passed
@ngutman ngutman deleted the feat/ios-beta-release-flow branch March 11, 2026 10:32
@ngutman
Copy link
Contributor Author

ngutman commented Mar 11, 2026

Merged via squash.

Thanks @ngutman!

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 82b38fe93b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +245 to +246
needs_api_key = require_api_key || beta_build_number_needs_asc_auth?
api_key = needs_api_key ? asc_api_key : nil

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Load Fastlane .env before preparing explicit beta archives

When IOS_BETA_BUILD_NUMBER is provided for beta_archive, prepare_beta_context skips asc_api_key, but asc_api_key is currently the only place that calls load_env_file("fastlane/.env"). That means values like IOS_DEVELOPMENT_TEAM in .env are never loaded in this path, so scripts/ios-beta-prepare.sh can fail team resolution on machines without usable Xcode/keychain team discovery even though the team is configured in .env. This regresses the documented explicit-build archive flow in environments that rely on .env for team configuration.

Useful? React with 👍 / 👎.

hydro13 pushed a commit to andyliu/openclaw that referenced this pull request Mar 11, 2026
Merged via squash.

Prepared head SHA: 82b38fe
Co-authored-by: ngutman <[email protected]>
Co-authored-by: ngutman <[email protected]>
Reviewed-by: @ngutman
Treedy2020 pushed a commit to Treedy2020/openclaw that referenced this pull request Mar 11, 2026
Merged via squash.

Prepared head SHA: 82b38fe
Co-authored-by: ngutman <[email protected]>
Co-authored-by: ngutman <[email protected]>
Reviewed-by: @ngutman
mrosmarin added a commit to mrosmarin/openclaw that referenced this pull request Mar 11, 2026
* main: (49 commits)
  fix(agents): add nodes to owner-only tool policy fallbacks
  fix(gateway): propagate real gateway client into plugin subagent runtime
  fix(gateway): enforce caller-scope subsetting in device.token.rotate
  fix(terminal): stabilize skills table width across Terminal.app and iTerm (openclaw#42849)
  fix(models): guard optional model input capabilities  (openclaw#42096)
  macOS/onboarding: prompt for remote gateway auth tokens (openclaw#43100)
  fix(macos): use foundationValue when serializing browser proxy POST body (openclaw#43069)
  feat(ios): add local beta release flow (openclaw#42991)
  docs(changelog): update context pruning PR reference
  fix(context-pruning): cover image-only tool-result pruning
  fix(context-pruning): prune image-containing tool results instead of skipping them (openclaw#41789)
  fix(agents): include azure-openai in Responses API store override (openclaw#42934)
  fix(telegram): fall back on ambiguous first preview sends
  fix(telegram): prevent duplicate messages with slow LLM providers (openclaw#41932)
  Providers: add Opencode Go support (openclaw#42313)
  fix(sandbox): sanitize Docker env before marking OPENCLAW_CLI (openclaw#42256)
  macOS: add chat model selector and persist thinking (openclaw#42314)
  fix: clear pnpm prod audit vulnerabilities
  fix(build): restore full gate
  fix(gateway): split conversation reset from admin reset
  ...
dhoman pushed a commit to dhoman/chrono-claw that referenced this pull request Mar 11, 2026
Merged via squash.

Prepared head SHA: 82b38fe
Co-authored-by: ngutman <[email protected]>
Co-authored-by: ngutman <[email protected]>
Reviewed-by: @ngutman
ahelpercn pushed a commit to ahelpercn/openclaw that referenced this pull request Mar 12, 2026
Merged via squash.

Prepared head SHA: 82b38fe
Co-authored-by: ngutman <[email protected]>
Co-authored-by: ngutman <[email protected]>
Reviewed-by: @ngutman
Ruijie-Ysp pushed a commit to Ruijie-Ysp/clawdbot that referenced this pull request Mar 12, 2026
Merged via squash.

Prepared head SHA: 82b38fe
Co-authored-by: ngutman <[email protected]>
Co-authored-by: ngutman <[email protected]>
Reviewed-by: @ngutman
leozhengliu-pixel pushed a commit to leozhengliu-pixel/openclaw that referenced this pull request Mar 13, 2026
Merged via squash.

Prepared head SHA: 82b38fe
Co-authored-by: ngutman <[email protected]>
Co-authored-by: ngutman <[email protected]>
Reviewed-by: @ngutman
plabzzxx pushed a commit to plabzzxx/openclaw that referenced this pull request Mar 13, 2026
Merged via squash.

Prepared head SHA: 82b38fe
Co-authored-by: ngutman <[email protected]>
Co-authored-by: ngutman <[email protected]>
Reviewed-by: @ngutman
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: ios App: ios maintainer Maintainer-authored PR scripts Repository scripts size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant