Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ Build a development IPA with custom xcconfig file path:
| --- | --- | --- | --- |
| `project_path` | Xcode Project (`.xcodeproj`) or Workspace (`.xcworkspace`) path. The input value sets xcodebuild's `-project` or `-workspace` option. | required | `$BITRISE_PROJECT_PATH` |
| `scheme` | Xcode Scheme name. The input value sets xcodebuild's `-scheme` option. | required | `$BITRISE_SCHEME` |
| `platform` | Platform to archive the product for. If set to `detect`, the step will try to detect the platform from the Xcode project settings. Its value sets xcodebuild's `-destination` option. Example: `-destination generic/platform=iOS Simulator`. | required | `detect` |
| `distribution_method` | Describes how Xcode should export the archive. The input value sets the method in the export options plist content. Note: In Xcode 15.3, distribution methods have been renamed. The values of this input reflect the old names. When running with Xcode 15.3 and later, the new names are passed to `xcodebuild`: - `debugging`, when `development` is selected - `app-store-connect`, when `app-store` is selected - `release-testing`, when `ad-hoc` is selected - `enterprise` is unchanged | required | `development` |
| `configuration` | Xcode Build Configuration. If not specified, the default Build Configuration will be used. The input value sets xcodebuild's `-configuration` option. | | |
| `xcconfig_content` | Build settings to override the project's build settings, using xcodebuild's `-xcconfig` option. You can't define `-xcconfig` option in `Additional options for the xcodebuild command` if this input is set. If empty, no setting is changed. When set it can be either: 1. Existing `.xcconfig` file path. Example: `./ios-sample/ios-sample/Configurations/Dev.xcconfig` 2. The contents of a newly created temporary `.xcconfig` file. (This is the default.) Build settings must be separated by newline character (`\n`). Example: ``` COMPILER_INDEX_STORE_ENABLE = NO ONLY_ACTIVE_ARCH[config=Debug][sdk=*][arch=*] = YES ``` | | `COMPILER_INDEX_STORE_ENABLE = NO` |
Expand Down
15 changes: 15 additions & 0 deletions e2e/bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ workflows:
- TEST_APP_COMMIT: ""
- BITRISE_PROJECT_PATH: Fruta.xcodeproj
- BITRISE_SCHEME: Fruta iOS
- DESTINATION: iOS
- CODE_SIGNING_METHOD: api-key
- API_KEY_PATH: $BITFALL_APPSTORECONNECT_API_KEY_URL
- API_KEY_ID: $BITFALL_APPSTORECONNECT_API_KEY_ID
Expand Down Expand Up @@ -188,6 +189,7 @@ workflows:
- TEST_APP_BRANCH: new-certificates
- BITRISE_PROJECT_PATH: ios-simple-objc/ios-simple-objc.xcodeproj
- BITRISE_SCHEME: ios-simple-objc
- DESTINATION: detect
- CODE_SIGNING_METHOD: api-key
- XCCONFIG_CONTENT: |
COMPILER_INDEX_STORE_ENABLE = NO
Expand Down Expand Up @@ -221,6 +223,7 @@ workflows:
- TEST_APP_BRANCH: master
- BITRISE_PROJECT_PATH: Fruta.xcodeproj
- BITRISE_SCHEME: Fruta iOS
- DESTINATION: detect
- CODE_SIGNING_METHOD: api-key
- MIN_DAYS_PROFILE_VALID: 0
- IPA_EXPORT_METHOD: ad-hoc
Expand All @@ -247,6 +250,7 @@ workflows:
- TEST_APP_BRANCH: manual-signing
- BITRISE_PROJECT_PATH: Fruta.xcodeproj
- BITRISE_SCHEME: Fruta iOS
- DESTINATION: detect
- CODE_SIGNING_METHOD: api-key
- MIN_DAYS_PROFILE_VALID: 0
- IPA_EXPORT_METHOD: development
Expand All @@ -272,6 +276,7 @@ workflows:
- TEST_APP_BRANCH: new-certificates
- BITRISE_PROJECT_PATH: ios-simple-objc/ios-simple-objc.xcodeproj
- BITRISE_SCHEME: ios-simple-objc
- DESTINATION: iOS
- CODE_SIGNING_METHOD: apple-id
- TEAM_ID: 72SA8V3WYL
- MIN_DAYS_PROFILE_VALID: 0
Expand All @@ -289,6 +294,7 @@ workflows:
- TEST_APP_BRANCH: entitlements
- BITRISE_PROJECT_PATH: code-sign-test.xcodeproj
- BITRISE_SCHEME: code-sign-test
- DESTINATION: detect
- CODE_SIGNING_METHOD: api-key
- MIN_DAYS_PROFILE_VALID: 0
- IPA_EXPORT_METHOD: app-store
Expand All @@ -305,6 +311,7 @@ workflows:
- TEST_APP_BRANCH: automatic
- BITRISE_PROJECT_PATH: code-sign-test.xcodeproj
- BITRISE_SCHEME: code-sign-test
- DESTINATION: detect
- CODE_SIGNING_METHOD: api-key
- MIN_DAYS_PROFILE_VALID: 0
- IPA_EXPORT_METHOD: app-store
Expand All @@ -331,6 +338,7 @@ workflows:
- TEST_APP_BRANCH: automatic
- BITRISE_PROJECT_PATH: code-sign-test.xcodeproj
- BITRISE_SCHEME: code-sign-test
- DESTINATION: detect
- CODE_SIGNING_METHOD: apple-id
- TEAM_ID: 72SA8V3WYL
- MIN_DAYS_PROFILE_VALID: 0
Expand All @@ -348,6 +356,7 @@ workflows:
- TEST_APP_COMMIT: ""
- BITRISE_PROJECT_PATH: code-sign-test.xcodeproj
- BITRISE_SCHEME: code-sign-test-Prod
- DESTINATION: detect
- CODE_SIGNING_METHOD: api-key
- MIN_DAYS_PROFILE_VALID: 0
- TEAM_ID: 72SA8V3WYL
Expand All @@ -366,6 +375,7 @@ workflows:
- TEST_APP_COMMIT: ""
- BITRISE_PROJECT_PATH: ios-simple-objc/ios-simple-objc.xcworkspace
- BITRISE_SCHEME: ios-simple-objc
- DESTINATION: detect
- CODE_SIGNING_METHOD: api-key
- MIN_DAYS_PROFILE_VALID: 0
- TEAM_ID: 72SA8V3WYL
Expand All @@ -385,6 +395,7 @@ workflows:
- TEST_APP_COMMIT: ""
- BITRISE_PROJECT_PATH: ios-simple-objc/ios-simple-objc.xcodeproj
- BITRISE_SCHEME: ios-simple-objc
- DESTINATION: detect
- CODE_SIGNING_METHOD: api-key
- MIN_DAYS_PROFILE_VALID: 0
- TEAM_ID: 72SA8V3WYL
Expand All @@ -407,6 +418,7 @@ workflows:
- TEST_APP_BRANCH: master
- BITRISE_PROJECT_PATH: code-sign-test.xcodeproj
- BITRISE_SCHEME: code-sign-test
- DESTINATION: iOS
- CODE_SIGNING_METHOD: api-key
- MIN_DAYS_PROFILE_VALID: 112
- TEAM_ID: 72SA8V3WYL
Expand All @@ -424,6 +436,7 @@ workflows:
- TEST_APP_BRANCH: master
- BITRISE_PROJECT_PATH: sample-apps-ios-workspace-swift.xcworkspace
- BITRISE_SCHEME: sample-apps-ios-workspace-swift
- DESTINATION: iOS
- CODE_SIGNING_METHOD: api-key
- MIN_DAYS_PROFILE_VALID: 0
- TEAM_ID: 72SA8V3WYL
Expand All @@ -442,6 +455,7 @@ workflows:
- TEST_APP_COMMIT: ""
- BITRISE_PROJECT_PATH: Catalyst Sample.xcodeproj
- BITRISE_SCHEME: Catalyst Sample
- DESTINATION: detect
- CODE_SIGNING_METHOD: api-key
- MIN_DAYS_PROFILE_VALID: 0
- FORCE_CODE_SIGN_IDENTITY: "Apple Development: Tooling Bot Bitrise"
Expand Down Expand Up @@ -484,6 +498,7 @@ workflows:
inputs:
- project_path: ./_tmp/$BITRISE_PROJECT_PATH
- scheme: $BITRISE_SCHEME
- platform: $DESTINATION
- automatic_code_signing: $CODE_SIGNING_METHOD
- min_profile_validity: $MIN_DAYS_PROFILE_VALID
- certificate_url_list: $BITFALL_APPLE_APPLE_CERTIFICATE_URL_LIST|$BITFALL_APPLE_IOS_CERTIFICATE_URL_LIST
Expand Down
11 changes: 6 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,12 @@ func createXcodebuildArchiver(logger log.Logger, logFormatter string) (step.Xcod

func createRunOptions(config step.Config) step.RunOpts {
return step.RunOpts{
ProjectPath: config.ProjectPath,
Scheme: config.Scheme,
Configuration: config.Configuration,
XcodeMajorVersion: config.XcodeMajorVersion,
ArtifactName: config.ArtifactName,
ProjectPath: config.ProjectPath,
Scheme: config.Scheme,
DestinationPlatform: config.DestinationPlatform,
Configuration: config.Configuration,
XcodeMajorVersion: config.XcodeMajorVersion,
ArtifactName: config.ArtifactName,

CodesignManager: config.CodesignManager,

Expand Down
18 changes: 18 additions & 0 deletions step.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,24 @@ inputs:
The input value sets xcodebuild's `-scheme` option.
is_required: true

- platform: detect
opts:
title: Platform
summary: Platform to archive the product for.
description: |-
Platform to archive the product for.
If set to `detect`, the step will try to detect the platform from the Xcode project settings.

Its value sets xcodebuild's `-destination` option.
Example: `-destination generic/platform=iOS Simulator`.
value_options:
- detect
- iOS
- watchOS
- tvOS
- visionOS
is_required: true

- distribution_method: development
opts:
title: Distribution method
Expand Down
28 changes: 23 additions & 5 deletions step/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,31 @@ import (
type Platform string

const (
iOS Platform = "iOS"
osX Platform = "OS X"
tvOS Platform = "tvOS"
watchOS Platform = "watchOS"
visionOS Platform = "visionOS"
detectPlatform Platform = "detect"
iOS Platform = "iOS"
osX Platform = "OS X"
tvOS Platform = "tvOS"
watchOS Platform = "watchOS"
visionOS Platform = "visionOS"
)

func parsePlatform(platform string) (Platform, error) {
switch strings.ToLower(platform) {
case "detect":
return detectPlatform, nil
case "ios":
return iOS, nil
case "tvos":
return tvOS, nil
case "watchos":
return watchOS, nil
case "visionos":
return visionOS, nil
default:
return "", fmt.Errorf("unknown platform: %s", platform)
}
}

func OpenArchivableProject(pth, schemeName, configurationName string) (*xcodeproj.XcodeProj, *xcscheme.Scheme, string, error) {
scheme, schemeContainerDir, err := schemeint.Scheme(pth, schemeName)
if err != nil {
Expand Down
56 changes: 35 additions & 21 deletions step/step.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type Inputs struct {
ProjectPath string `env:"project_path,file"`
Scheme string `env:"scheme,required"`
ExportMethod string `env:"distribution_method,opt[app-store,ad-hoc,enterprise,development]"`
Platform string `env:"platform,opt[detect,iOS,watchOS,tvOS,visionOS]"`

// xcodebuild configuration
Configuration string `env:"configuration"`
Expand Down Expand Up @@ -130,6 +131,7 @@ type Inputs struct {
// Config ...
type Config struct {
Inputs
DestinationPlatform Platform
XcodeMajorVersion int
XcodebuildAdditionalOptions []string
CodesignManager *codesign.Manager // nil if automatic code signing is "off"
Expand Down Expand Up @@ -199,6 +201,10 @@ func (s XcodebuildArchiveConfigParser) ProcessInputs() (Config, error) {
}

var err error
if config.DestinationPlatform, err = parsePlatform(config.Platform); err != nil {
return Config{}, fmt.Errorf("issue with input Platform: %w", err)
}

config.XcodebuildAdditionalOptions, err = shellquote.Split(inputs.XcodebuildOptions)
if err != nil {
return Config{}, fmt.Errorf("provided XcodebuildOptions (%s) are not valid CLI parameters: %s", inputs.XcodebuildOptions, err)
Expand Down Expand Up @@ -316,11 +322,12 @@ func (s *XcodebuildArchiver) EnsureDependencies() {
// RunOpts ...
type RunOpts struct {
// Shared
ProjectPath string
Scheme string
Configuration string
XcodeMajorVersion int
ArtifactName string
ProjectPath string
Scheme string
DestinationPlatform Platform
Configuration string
XcodeMajorVersion int
ArtifactName string

// Code signing, nil if automatic code signing is "off"
CodesignManager *codesign.Manager
Expand Down Expand Up @@ -426,12 +433,13 @@ func (s XcodebuildArchiver) Run(opts RunOpts) (RunResult, error) {
s.logger.Println()

archiveOpts := xcodeArchiveOpts{
ProjectPath: opts.ProjectPath,
Scheme: opts.Scheme,
Configuration: opts.Configuration,
XcodeMajorVersion: opts.XcodeMajorVersion,
ArtifactName: opts.ArtifactName,
XcodeAuthOptions: authOptions,
ProjectPath: opts.ProjectPath,
Scheme: opts.Scheme,
DestinationPlatform: opts.DestinationPlatform,
Configuration: opts.Configuration,
XcodeMajorVersion: opts.XcodeMajorVersion,
ArtifactName: opts.ArtifactName,
XcodeAuthOptions: authOptions,

PerformCleanAction: opts.PerformCleanAction,
XcconfigContent: opts.XcconfigContent,
Expand Down Expand Up @@ -784,12 +792,13 @@ func (s XcodebuildArchiveConfigParser) createCodesignManager(config Config) (cod
}

type xcodeArchiveOpts struct {
ProjectPath string
Scheme string
Configuration string
XcodeMajorVersion int
ArtifactName string
XcodeAuthOptions *xcodebuild.AuthenticationParams
ProjectPath string
Scheme string
DestinationPlatform Platform
Configuration string
XcodeMajorVersion int
ArtifactName string
XcodeAuthOptions *xcodebuild.AuthenticationParams

PerformCleanAction bool
XcconfigContent string
Expand All @@ -816,9 +825,14 @@ func (s XcodebuildArchiver) xcodeArchive(opts xcodeArchiveOpts) (xcodeArchiveRes

s.logger.TInfof("Reading xcode project")

platform, err := BuildableTargetPlatform(xcodeProj, scheme, configuration, opts.AdditionalOptions, XcodeBuild{}, s.logger)
if err != nil {
return out, fmt.Errorf("failed to read project platform: %s: %s", opts.ProjectPath, err)
if opts.DestinationPlatform == detectPlatform {
s.logger.TInfof("Platform is set to 'automatic', detecting platform from the project.")
s.logger.TWarnf("Define the platform step input manually to avoid this phase in the future.")
platform, err := BuildableTargetPlatform(xcodeProj, scheme, configuration, opts.AdditionalOptions, XcodeBuild{}, s.logger)
if err != nil {
return out, fmt.Errorf("failed to read project platform: %s: %s", opts.ProjectPath, err)
}
opts.DestinationPlatform = platform
}

s.logger.TInfof("Reading main target")
Expand Down Expand Up @@ -869,7 +883,7 @@ and use 'Export iOS and tvOS Xcode archive' step to export an App Clip.`, opts.S
archiveCmd.SetAuthentication(*opts.XcodeAuthOptions)
}

additionalOptions := generateAdditionalOptions(string(platform), opts.AdditionalOptions)
additionalOptions := generateAdditionalOptions(string(opts.DestinationPlatform), opts.AdditionalOptions)
archiveCmd.SetCustomOptions(additionalOptions)

var swiftPackagesPath string
Expand Down