expo / expo/eas-cli

generate_gymfile_from_template emits Apple-deprecated "ad-hoc" export method, rejected by Xcode 26+

Open Beginner friendly
#4,040 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
1.4k
Forks
236
Avg merge
3d 1h
Merged PRs (30d)
91

Description

### Summary

`packages/build-tools/src/steps/functions/generateGymfileFromTemplate.ts`'s `DEFAULT_CREDENTIALS_TEMPLATE` populates the Gymfile's `export_options` `method:` field from `EXPORT_METHOD`, which is set here:

```js
...(credentials
? {
KEYCHAIN_PATH: credentials.keychainPath,
EXPORT_METHOD: credentials.distributionType,
}
: {}),
```

For an internal-distribution / ad-hoc build, `credentials.distributionType` stringifies to `"ad-hoc"`. As of Xcode 15.4, Apple's own `IDEDistribution` tool deprecated that command-line name in favor of `"release-testing"` (see fastlane/fastlane#22028, which quotes the exact Xcode message: *"Command line name 'ad-hoc' is deprecated. Use 'release-testing' instead."*). Xcode 26+ now hard-rejects the old value at export time:

```
exportArchive exportOptionsPlist error for key "method" expected one {} but found ad-hoc
```

### Reproduction

- SDK 56 project (`expo@~56.0.14`), iOS build with `credentialsSource: "remote"`, `distribution: "internal"`.
- Confirmed via elimination across multiple builds, ruling out every other variable first:
- Verified this is **not** downstream of anything else: signing (`DEVELOPMENT_TEAM`), entitlements/capabilities, and `CFBundleShortVersionString` version-matching were all independently broken and fixed first, on our own extension targets (Watch app + two extensions) — none of that affected this error.
- Verified this is **not** image-recency-dependent: reproduced identically on both `macos-tahoe-26.4-xcode-26.4` (the SDK-56-aliased default) and `macos-tahoe-26.5-xcode-26.6` (`latest`), with `fastlane`/`gym` at `2.236.1` on the latter — the newest available combination at the time of testing.
- Archive itself succeeds cleanly (all targets compile, sign, and version-match); only the export step fails, and only on this one value.

### Expected

`EXPORT_METHOD` (and therefore the generated Gymfile's `method:` value) should resolve to `"release-testing"` for an ad-hoc/internal-distribution build under Xcode 15.4+, matching Apple's own renamed value, instead of the legacy `"ad-hoc"` string.

### Workaround in use

Supplying a custom `template` input to `generate_gymfile_from_template` (via a custom build config), byte-identical to `DEFAULT_CREDENTIALS_TEMPLATE` except the `method:` line hardcoded to `"release-testing"`. Happy to remove this workaround once a fix ships — flagging so it can be prioritized and so others hitting the same SDK56 + Xcode 26 combination can find it.

Contributor guide

Open the contributing guide

Research direction

Start in packages/build-tools/src/steps/functions/generateGymfileFromTemplate.ts and inspect DEFAULT_CREDENTIALS_TEMPLATE alongside the credentials mapping that sets EXPORT_METHOD. Verify how an internal-distribution credential becomes the generated Gymfile method, then update the behavior so it uses release-testing instead of the deprecated ad-hoc value while preserving other distribution methods.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, typescript
Domain
build-system, mobile
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.