diff --git a/.gitignore b/.gitignore
index d960e531..e904de4a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@ test-*
.DS_Store
*.orig
/examples
+TEST-*
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a046398e..00470ab5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,9 @@ Changelog
See [GitHub releases](https://github.com/jenkinsci/xcode-plugin/releases)
+#### Version 2.0.15 (14th Mar 2021)
+- ##### Moved information in the AppleWWDRCA.cer file from the local file system to credentials.
+
#### Version 2.0.14 (14th Nov 2019)
- ##### Fix backward compatibility problem at Import Developer Profile.
diff --git a/README.md b/README.md
index 421834f1..c838657b 100644
--- a/README.md
+++ b/README.md
@@ -19,12 +19,9 @@ A problem, An idea ?
*Please use our tasks and issues tracker to report bugs, improvements or
new feature.*
-- [Report a
- bug](https://issues.jenkins-ci.org/secure/CreateIssueDetails!init.jspa?Create=Create&components=16124&pid=10172&issuetype=1)
-- [Ask for a new
- feature](https://issues.jenkins-ci.org/secure/CreateIssueDetails!init.jspa?Create=Create&components=16124&pid=10172&issuetype=2)
-- [Ask for an improvement of an existing
- feature](https://issues.jenkins-ci.org/secure/CreateIssueDetails!init.jspa?Create=Create&components=16124&pid=10172&issuetype=4)
+- [Report a bug](https://issues.jenkins.io/secure/CreateIssueDetails!init.jspa?Create=Create&components=16124&pid=10172&issuetype=1)
+- [Ask for a new feature](https://issues.jenkins.io/secure/CreateIssueDetails!init.jspa?Create=Create&components=16124&pid=10172&issuetype=2)
+- [Ask for an improvement of an existing feature](https://issues.jenkins.io/secure/CreateIssueDetails!init.jspa?Create=Create&components=16124&pid=10172&issuetype=4)
Also if you want to propose some code change using a Github pull
request, please open also a Jira issue. It is easier for developers to
@@ -41,21 +38,22 @@ credentials.
After that, the information for accessing the keychain must be
registered in the credentials.
+#### Features
+
This plugin adds the ability to call Xcode command line tools to
automate build and packaging iOS applications (iPhone, iPad, ...).
-#### Features
-
##### Versioning
This builder can invoke agvtool to dynamically update the
-`CFBundleVersion` (a.k.a. Technical Version) or
-`CFBundleShortVersionString` (a.k.a. Marketing Version). It supports all
-macros from the . For example the value `${BUILD_NUMBER`} will be
-replaced with the current build number. We advice you to generate a
+`CFBundleVersion` (a.k.a. Technical Version) and
+`CFBundleShortVersionString` (a.k.a. Marketing Version).
+It supports all macros beginning from the '$'.
+For example the value `${BUILD_NUMBER}` will be replaced with the current build number.
+We advice you to generate a
unique value for each build for the `CFBundleVersion` if you want for
-example deploy it into a private store. In that case you can use for
-example : `${JOB_NAME}-${BUILD_NUMBER`}
+example deploy it into a private store.
+In that case you can use for example : `${JOB_NAME}-${BUILD_NUMBER}`
##### Building
@@ -68,8 +66,7 @@ to perform a clean before the build phase.
The builder can be used to package the .app into a .ipa. Since a .app is
actually a directory, it can be awkward to work with and, especially,
distribute. We can simplify this by packaging the .app into a single
-.ipa file, which is just a
-zip file with a well-known internal structure
+.ipa file, which is just a zip file with a well-known internal structure
##### Signing
@@ -79,7 +76,7 @@ process.
###### Allowing Jenkins to stage developer profile
This plugin builds on top of to allow you to store your Apple Developer
-Profile (\*.developerprofile) file. [This file contains a code signing
+Profile (*.developerprofile) file. [This file contains a code signing
private key, corresponding developer/distribution certificates, and
mobile provisioning
profiles](http://stackoverflow.com/questions/15154211/what-data-are-stored-in-developer-profile-file-exported-from-xcode).
@@ -88,7 +85,7 @@ XCode](http://stackoverflow.com/questions/10404931/copying-keys-and-certificates
To upload the developer profile into Jenkins, go to "Manage Credentials"
in the system configuration page, and select "Apple Developer Profile"
-from the "Add" button. See for further details.
+from the "Add" button. See HELP for further details.
To use this profile for signing, add "Import developer profile" as a
build step before you run xcode, and select the developer profile to
@@ -127,23 +124,26 @@ and graphs.
##### Sample of the configuration panel
-![](docs/images/40d7bd30d112f7b90d88d57fce45ecb2abe29c2e.png)
+![](docs/images/ScreenShot_2021-04-19_13.25.38.png)
#### Documentation
##### Installation guide
-Obviously, the build machine has to be an OSX machine with XCode
+Obviously, the build machine has to be an macOS X machine with Xcode
developer tools installed.
Certificates, Identities and Provisions must be installed on the build
-machine separately.
+machine separately.
+
+(This has been improved in the latest version of the plugin.
+You can distribute the "Developer Profile" from the master node to the slave nodes by performing "Import Developer Profile" on the master node prior to the build step.)
+
Just install the latest version of the plugin from the update center and
-configure a freestyle job (see \#Usage Guide) that will use your OSX
-node (If your central instance isn't running under OSX).
-If xcode related binaries aren't stored in the default location, update
-the global configuration of the plugin (Manage Jenkins -\> Configure
+configure a freestyle job (see #Usage Guide) that will use your OSX node (If your central instance isn't running under macOS X).
+If Xcode related binaries aren't stored in the default location, update
+the global configuration of the plugin (Manage Jenkins -> Configure
System)
-![](docs/images/46781a5731ff4fb8b72f4d780b2b02a402f34a2e.png)
+![](docs/images/ScreenShot_2021-04-19_14.17.49.png)
If you want to use multiple versions of Xcode to build your application,
use ’Global Tool Configuration’ to register the distinguished name and
@@ -165,14 +165,82 @@ which is useful for distributing with multiple Jenkins nodes.
| Parameter | Pipeline Parameter | Since version | Description |
|-------------------------------|----------------------------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| Developer Profile | profileId | 2.0.1 | Select the developer profile you exported from Xcode Preference to import into the keychain. Developer profile must be registered with Jenkins in advance by "Credentials". If you do not select this column, you can specify the identifier of the developer profile registered in "Credentials" with the next "Developer Profile ID". |
+| Developer Profile | profileId | 2.0.1 | Select the developer profile you exported from Xcode Preference to import into the keychain. Developer profile must be registered with Jenkins in advance by "Credentials". |
| Import into existing Keychain | importIntoExistingKeychain | 2.0.6 | If it is checked, the developer profile will be imported into the existing keychain. If not checked, create a new key chain with the file name "jenkins-" + "job name" newly, and import the developer profile into this. (In this case, a random character string is automatically generated and used for the password) |
-| Target keychain | keychainId | 2.0.13 | The ID of the configured keychain to use to import certificates from developer profile to sign the package. |
-| Target keychain | keychainName This has been deprecated and has now been replaced by "keychainId".| 2.0.6 | The name of the configured keychain to use to import certificates from developer profile to sign the package. |
+| Target keychain | keychainId | 2.0.13 | The ID of the configured keychain to use to import certificates from developer profile to sign the package. |
+| Target keychain | ~~keychainName~~ This has been deprecated and has now been replaced by "keychainId".| 2.0.6 | The name of the configured keychain to use to import certificates from developer profile to sign the package. |
| Keychain path | keychainPath | 2.0.6 | Keychain path to import developer profile. |
| Keychain password | keychainPwd | 2.0.6 | Password to unlock keychain importing developer profile. |
+| AppleWWDRCA | appleWWDRCAcertId | 2.0.15 | Select the AppleWWDRCA (Intermediate Certificate) you exported from macOS keychain to import into the Jenkins node(s) keychain. AppleWWDRCA must be registered with Jenkins in advance by "Credentials". |
+
+###### How to export AppleWWDRCA (Intermediate Certificate) from your macOS keychain
+
+If you have an environment where you use Xcode on a daily basis and you can code sign your app using Xcode,
+you will have the necessary Apple WWDRCA intermediate certificate in your macOS keychain.
+You can export this using KeychainAccess utility.
+
+When exporting Apple WWDRCA (intermediate certificate) from macOS keychain,
+include all "Apple Worldwide Developer Relations Certification Authority" (expired in 2023 and expired in 2030) and "Apple Developer ID Certification Authority" as follows. Select and export.
+
+![Select certificates](docs/images/ScreenShot_2021-04-13_21.04.34.png)
+
+Choose "Export 3 items" from context menu.
+
+![Select export items](docs/images/ScreenShot_2021-04-13_21.05.45.png)
+
+Select "Certificate (.cer)" for "File format:" when exporting.
+
+![export certificates](docs/images/ScreenShot_2021-04-13_21.06.34.png)
+
+If the Jenkins node is in a remote location like a cloud service,
+In an environment where the WWDRCA intermediate certificate is not installed on your macOS,
+you can download the certificate from the "Certificate Authority page"(https://www.apple.com/certificateauthority/) of the Apple Developer Portal and use it.
+
+![Select certificates](docs/images/ScreenShot_2021-04-13_22.39.25.png)
+
+The file downloaded from the Apple Developer Portal (extension .cer) has a binary format DER format,
+so use the openssl command to convert it to BASE64 encoded text and combine the three downloaded files into one file.
+
+```shell
+% (openssl x509 -in ~/Downloads/DeveloperIDCA.cer -inform der -out - && \
+openssl x509 -in ~/Downloads/AppleWWDRCA.cer -inform der -out - && \
+openssl x509 -in ~/Downloads/AppleWWDRCAG3.cer -inform der -out -) > AppleWWDRCA.cer
+```
+
+Whether you export the certificate using Keychain Access or convert and combine the files downloaded from the Apple Developer Portal,
+the resulting AppleWWDRCA.cer file will have the same content.
+
+###### How to import AppleWWDRCA (Intermediate Certificate) to your Jenkins certificates.
+
+Select "Manage Jenkins" on the dashboard.
+
+![Select Manage Jenkins](docs/images/ScreenShot_2021-04-13_21.58.10.png)
+
+Select "Manage Credentials".
+
+![Select Manage Credentials](docs/images/ScreenShot_2021-04-13_21.58.31.png)
+
+You can add new credentials to your "global" domain by clicking "(grobal)" from "Stores scoped to Jenkins"
+and selecting "Add Credentials" from the top left of the displayed page.
-Limitations
+![Select (grobal)](docs/images/ScreenShot_2021-04-13_21.59.20.png)
+
+And then click "Add Credentials".
+
+![Select Add Credentials](docs/images/ScreenShot_2021-04-13_22.00.05.png)
+
+For "Kind", select "Apple Worldwide Developer Relations Certification Authority".
+Then click "Choose file".
+
+![Select Choose file](docs/images/ScreenShot_2021-04-13_22.03.30.png)
+
+Select and upload the certificate file (.cer) that you previously exported from Keychain
+or downloaded from the Apple Developer Portal.
+
+![Select .cer file from chooser](docs/images/ScreenShot_2021-04-13_22.03.04.png)
+
+
+###### Limitations
The Xcode Integration Plugin has the function of importing the secret
key and certificate of the developer account into the temporary key
@@ -180,7 +248,7 @@ chain, but as the constraint of macOS can not handle different key chain
for each session, the job handling the key chain If you execute them in
parallel, this will not work properly.
-As one of workarounds, it is impossible to limit the maximum number of
+As one of workarounds, it is possible to limit the maximum number of
jobs around Jenkins' node to 1 and to execute multiple nodes with
different macOS accounts.
@@ -189,7 +257,8 @@ different macOS accounts.
Add the XCode build step to a free-style project and set the target
(e.g. `MyApp`), configuration (e.g. `Release`) and check the build IPA
and update version number options. This will give you a single,
-versioned .ipa file. You can also select to clean the project before a
+versioned .ipa file.
+You can also select to clean the project before a
build; while this will make sure that the project is starting from a
clean state, it will make large projects take a lot longer.
@@ -197,72 +266,77 @@ clean state, it will make large projects take a lot longer.
Add the XCode build step and this time specify your unit test target
(e.g. `MyAppTests`), configuration (e.g. `Debug`) and the SDK (e.g.
-`Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.1.sdk/`).
+`Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.4.sdk/`).
+The SDK path is specified relative to the Xcode directory (which can be specified with the environment variable `DEVELOPER_DIR` and can be confirmed with the` xcode-select -p` command).
Leave all the checkboxes unselected. The SDK needs to be supplied here
as the unit tests will only be run when building under the simulator's
-SDK.
-Check the "Publish JUnit test result report" option in the project
+SDK.
+
+The following items do not exist in the current version, and instead determine whether to output a test report based on whether "ResultBundlePath" is specified. (If ResultBundlePath is empty, no report will be output.)
+~~Check the "Publish JUnit test result report" option in the project
config and set the value `"*``/test-reports/``*.xml"` under "Test report
-XMLs". This will tell Jenkins to pick up the JUnit-format test reports.
+XMLs". This will tell Jenkins to pick up the JUnit-format test reports.~~
###### XCode Builder configuration parameters
| Parameter | Pipeline Parameter | Since version | Description |
|-------------------------------|---------------------------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-|Xcode Workspace File |xcodeWorkspaceFile |1.2 |Only needed if you want to compile a workspace instead of a project. It takes precedence over 'Xcode Project File' setting and this job 'configuration' parameter."|
-|Xcode Tools Version |xcodeName |2.0.3 |You can select the version of Xcode set by 'Global Tool Configuration' by plugin setting. If you choose the 'System Default' for Xcode version, plugin will not do anything, so you can switch Xcode using environment variable 'DEVELOPER_DIR' as well.
-|Xcode Schema File |xcodeSchema |1.2 |Needed if you want to compile for a specific schema instead of a target, or if you want to generate an archive or an IPA.|
-|Xcode Project File |xcodeProjectFile |1.0 |If there is more than one XCode project file in the project path, you will need to specify the file name of the project you wish to build. If you need to build all project, you will need to create an XCode build step for each one manually.|
-|Xcode Project Directory |xcodeProjectPath |1.0 |This is the relative path from the workspace to the directory that contains the XCode project file. You only need to supply this value if the XCode project you wish to build is not in the root of the workspace.|
+|Development Team |developmentTeamName |1.4 |The name of the configured development team to use to sign the package. As of XCode 8.3, this is required now to sign an ipa (which now uses xcodebuilder). A development team can be configured here by specifying a Development Team ID, or by creating one in the jenkins global configuration.|
+|Development Team ID |developmentTeamID |1.4 |Specifey the ID of the Apple development team to use to sign the IPA when 'Development Team' is not selected.|
+|Xcode Tools Version |xcodeName |2.0.3 |You can select the version of Xcode set by 'Global Tool Configuration' by 'Manage Jenkins'. If you choose the 'System Default' for Xcode version, plugin will not do anything, so you can switch Xcode using environment variable 'DEVELOPER_DIR' as well.
|Use Legacy Build System? |useLegacyBuildSystem |2.0.9 |Use the old 'Legacy Build System' instead of 'New Build System' of Xcode 9 and later.|
-|Upload Symbols? |uploadSymbols |2.0.3 |If Checked, include symbols in IPA exporting for App Store. The default is "Yes" (check is on).|
-|Upload Bitcode? |uploadBitcode |2.0.3 |If Checked, include bitcode in IPA exporting for App Store. The default is "Yes" (check is on).|
-|Unlock Keychain? |unlockKeychain |1.0 |Automatically unlock the keychain before signing the archive?|
-|Thinning |thinning |2.0.3 |Set this to thin the packages for one or more devices in Xcode when exporting IPA by methods other than App Store.
Available options are:
- \ (Xcode export non-thinned generic application), - (Xcode export universal applications and all available thinning variants), -Or for a model identifier a specific device (eg "iPhone 7, 1"). The default is \.|
-|Technical version |cfBundleVersionValue |1.0 |This will set the CFBundleVersion to the specified string. Supports all macros and also environment and build variables from the Token Macro Plugin. For example the value ${BUILD_NUMBER} will be replaced with the current build number. We advice you to generate a unique value for each build if you want for example deploy it into a private store. In that case you can use for example : ${JOB_NAME}-${BUILD_NUMBER}|
|Target |target |1.0 |The target to build. If left empty, this will build all targets in the project. If you wish to build your binary and the unit test module, it is best to do this as two separate steps each with their own target. This was, the iPhone Simulator SDK can be specified for the unit tests.|
-|SYMROOT |symRoot |1.1 |You only need to supply this value if you want to specify the SYMROOT path to use. If empty, the default SYMROOT path will be used (it could be different depending of your Xcode version). Supports all macros and also environment and build variables from the Token Macro Plugin. For example you can use the value : ${WORKSPACE}/build|
-|Strip Swift Symbols? |stripSwiftSymbols |2.0.5 |If checked, symbols be stripped from Swift libraries when exporting the application to IPA.|
-|SDK |sdk |1.0 |You only need to supply this value if you want to specify the SDK to build against. If empty, the SDK will be determined by XCode. If you wish to run OCUnit tests, you will need to use the iPhone Simulator's SDK, for example: /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.1.sdk/|
-|ResultBundlePath |resultBundlePath |2.0.11 |Leave empty, it will not output a test result and will not analyze the test results. relative to the project-directory.|
-|Provisioning profiles UUID |provisioningProfiles: [provisioningProfileUUID] |2.0.1 |Specify the UUID or Specifire of the provisioning profile to use to sign the application. If the location of the provisioning profile is set instead of the UUID or Specifire, read the UUID from the provisioning profile and use that value.
-|Provisioning Profiles Bundle ID|provisioningProfiles: [provisioningProfileAppId] |2.0.1 |Specify the Bundle ID of the application for which code sign to be performed. If the location of the Info.plist file contained in the compiled archive is set instead of the Bundle ID, read the Bundle ID from the Info.plist file and use that value. Provide version number and run avgtool? provideApplicationVersion 1.4 Provide version number and run avgtool before invoking the build.
-|Pack on demand resources? |~~embedOnDemandResourcesAssetPacksInBundle~~ assetPacksInBundle| 2.0.3 |Export settings for non App Store. If the application is using on demand resources and this item is on, the asset pack is included in the application bundle, so you can test the app without the server hosting the asset pack. If assetPacksBaseURL is not specified, the default is YES (check is on).|
-|Pack application, build and sign .ipa? |buildIpa |1.0 |The target to build. If left empty, this will build all targets in the project. If you wish to build your binary and the unit test module, it is best to do this as two separate steps each with their own target. This was, the iPhone Simulator SDK can be specified for the unit tests.|
-|Output directory |ipaOutputDirectory |1.4 |The output directory for the .ipa file, relative to the build directory.|
-|On demand resources asset URL |~~onDemandResourcesAssetPacksBaseURL~~ assetPacksBaseURL |2.0.3 |Export settings for non-App Store. If the application is using an on demand resource and assetPacksInBundle is not YES, this must be the base URL that specifies the host of the asset pack. This will set up the app to download the asset pack from the specified URL. |
+|Interpret As Regular Expression|interpretTargetAsRegEx |1.4 |Build all entries listed under the "Targets:" section of the xcodebuild -list output that match the regexp.|
+|Clean before build? |cleanBeforeBuild |1.0 |This will delete the build directories before invoking the build. This will force the rebuilding of ALL dependencies and can make large projects take a lot longer.|
+|Allow failing build results? |allowFailingBuildResults |1.4 |Checking this option will prevent this build step from failing if xcodebuild exits with a non-zero return code.|
|No Console Log? |noConsoleLog |2.0.1 |Checking this option will not log xcode build output to console output.|
-|New bundle ID |bundleID |1.4 |The new bundle ID. Usually something like com.companyname.projectname.|
-|Marketing version |cfBundleShortVersionStringValue|1.0 |This will set the CFBundleShortVersionString to the specified string. Supports all macros and also environment and build variables from the Token Macro Plugin.|
-|Manual signing? |manualSigning This has been deprecated and has now been replaced by "signingMethod".|2.0.1 |For this option you need to manually specify the combination of Provisioning profile UUID and BundleID. This will be useful if you want to change the combination of Provisioning Profile and Certificate used for CodeSign when you build the application.|
-|Manifest Plist URL |ipaManifestPlistUrl |1.5 |The base URL to use to create a Manifest Plist. If omitted no Manifest Plist will be generated.|
|Logfile Output directory |logfileOutputDirectory |2.0.1 |Specify the directory to output the log of xcodebuild. If you leave it blank, it will be output to "project directory/builds/${BUILD_NUMBER}/log" with other logs. If an output path is specified, it is output as a xcodebuild.log file in a relative directory under the "build output directory"|
-|Keychain path |keychainPath |1.0 |The path of the keychain to use to retrieve certificates to sign the package (default : ${HOME}/Library/Keychains/login.keychain).|
-|Keychain password |keychainPwd |1.0 |The password of the keychain to use to retrieve certificates to sign the package.|
-|Keychain Id |keychainId |2.0.13 |The ID of the configured keychain to use to retrieve certificates to sign the package.|
-|Keychain name |keychainName This has been deprecated and has now been replaced by "keychainId".|1.4 |The name of the configured keychain to use to retrieve certificates to sign the package.|
-|Interpret As Regular Expression|interpretTargetAsRegEx |1.4 |Build all entries listed under the "Targets:" section of the xcodebuild -list output that match the regexp.|
-|Info.plist path |bundleIDInfoPlistPath |1.4 |The path to the info.plist file which contains the CFBundleIdentifier of your project. Usually something like: ${WORKSPACE}/ProjectName/Project-Info.plist|
+|ResultBundlePath |resultBundlePath |2.0.11 |Set the output directory of test results. Leave empty, it will not output a test result and will not analyze the test results. relative to the project-directory.|
+|Clean ResultBundlePath? |cleanResultBundlePath |2.0.11 |This will delete the ResultBundlePath before invoking the build.|
+|Configuration |configuration |1.0 |This is the name of the configuration as defined in the XCode project. By default there are Debug and Release configurations.|
+|Xcode Schema File |xcodeSchema |1.2 |Needed if you want to compile for a specific schema instead of a target, or if you want to generate an archive or an IPA.|
|Generate Archive? |generateArchive |2.0 |Checking this option will generate an xcarchive of the specified scheme. A workspace and scheme are are also needed for archives.|
-|Full size image URL |fullSizeImageURL |2.0.3 |Export settings for non App Store. Specify the URL of the image (512 x 512 pixels) of the icon to be displayed when installing the application using manifest.plist.|
+|Pack application, build and sign .ipa?|buildIpa |1.0 |If this is checked, it will generate a single packed .ipa file from xcarchive. The .ipa file is used to distribute the app on test sites and upload it to the App Store.|
|Export method |ipaExportMethod |1.4 |The export method of the .app to generate the .ipa file. Should be one in 'development', 'ad-hoc', 'enterprise' or 'app-store'.|
-|Display image URL |displayImageURL |2.0.3 |Export settings for non App Store. Specify the URL of the image (57 x 57 pixels) of the icon to be displayed when installing the application using manifest.plist.|
-|Development Team ID |developmentTeamID |1.4 |The ID of the Apple development team to use to sign the IPA If 'Development Team' is not selected.|
-|Development Team |developmentTeamName |1.4 |The name of the configured development team to use to sign the package. As of XCode 8.3, this is required now to sign an ipa (which now uses xcodebuilder). A development team can be configured here by specifying a Development Team ID, or by creating one in the jenkins global configuration.|
-|Custom xcodebuild arguments |xcodebuildArguments |1.3 |Passing custom arguments is convenient when you need to change some project options for Jenkins build, but don't want them to persist in project file. For example when running application tests, following settings often are nice fit: GCC_SYMBOLS_PRIVATE_EXTERN=NO COPY_PHASE_STRIP=NO. Otherwise Release build will usually fail because it won't be able to find application symbols to link with test bundle. Arguments are currently separated by space, enclosing them in quotes won't help.|
-|Copy provisioning profile |copyProvisioningProfile |2.0.7 |If Checked, and the filename of provisioning profile is specified in "Provisioning profile UUID", the specified file is copied to a predetermined place. ("/Users/${HOME}/Library/MobileDevice/Provisioning Profiles/") This can be used to overwrite the contents of the developer profile or system settings in the provisioning profile in the project deployed from SCM etc. If the provisioning profile UUID or Specifire is set in "provisioning profile UUID", it does not do anything. The default is "Yes" (check is on)|
-|Configuration |configuration |1.0 |This is the name of the configuration as defined in the XCode project. By default there are Debug and Release configurations.|
+|.ipa filename pattern |ipaName |1.4 |A pattern for the ipa file name. You may use ${VERSION} and ${BUILD_DATE} (yyyy.MM.dd) in this string|
+|Output directory |ipaOutputDirectory |1.4 |The output directory for the .ipa file, relative to the build directory.|
+|Upload Bitcode? |uploadBitcode |2.0.3 |If Checked, include bitcode in IPA exporting for App Store. The default is "Yes" (check is on).|
+|Upload Symbols? |uploadSymbols |2.0.3 |If Checked, include symbols in IPA exporting for App Store. The default is "Yes" (check is on).|
|Compile Bitcode? |compileBitcode |2.0.3 |If checked, Xcode will recompiling Bitcode and exporting IPA for the non App Store. The default is "Yes" (check is on).|
+|Thinning |thinning |2.0.3 |Set this to thin the packages for one or more devices in Xcode when exporting IPA by methods other than App Store.
Available options are: - \ (Xcode export non-thinned generic application), - (Xcode export universal applications and all available thinning variants), - Or for a model identifier a specific device (eg "iPhone 7,1"). The default is \.|
+|Pack on demand resources? |~~embedOnDemandResourcesAssetPacksInBundle~~ assetPacksInBundle| 2.0.3 |Export settings for non App Store. If the application is using on demand resources and this item is on, the asset pack is included in the application bundle, so you can test the app without the server hosting the asset pack. If assetPacksBaseURL is not specified, the default is YES (check is on).|
+|On demand resources asset URL |~~onDemandResourcesAssetPacksBaseURL~~ assetPacksBaseURL |2.0.3 |Export settings for non-App Store. If the application is using an on demand resource and assetPacksInBundle is not YES, this must be the base URL that specifies the host of the asset pack. This will set up the app to download the asset pack from the specified URL. |
+|Application URL |appURL |2.0.3 |Specify the URL for installing the application when creating the manifest.plist that is necessary when OTA installing the application from Web pages or email.|
+|Display image URL |displayImageURL |2.0.3 |Export settings for non App Store. Specify the URL of the image (57 x 57 pixels) of the icon to be displayed when installing the application using manifest.plist.|
+|Full size image URL |fullSizeImageURL |2.0.3 |Export settings for non App Store. Specify the URL of the image (512 x 512 pixels) of the icon to be displayed when installing the application using manifest.plist.|
+|Asset pack URL |assetPackManifestURL |2.0.3 |Export settings for non-App Store App. If the application is using on-demand resources and the application will installing OTA with manifest.plist, this must be the base URL that specifies the host of the asset pack. This will set up the app to download the asset pack from the specified URL.|
+|Strip Swift Symbols? |stripSwiftSymbols |2.0.5 |If checked, symbols be stripped from Swift libraries when exporting the application to IPA.|
+|~~Manual signing?~~ |~~manualSigning~~ This has been deprecated and has now been replaced by "signingMethod".|2.0.1 |For this option you need to manually specify the combination of Provisioning profile UUID and BundleID. This will be useful if you want to change the combination of Provisioning Profile and Certificate used for CodeSign when you build the application.|
|Code signing settings |signingMethod |2.0.7 |This attribute can take one of the following three values. "automatic" (Check "Automatic Signing") Checking this option will automatically generate Provisioning Profile and certificates for signing application. However, please be aware that using this function will automatically create Provisioning profile and certificates as necessary, so that old Provisioning profile and certificates will be invalid at that time. "manual" (Check "Manual signing") For this option you need to manually specify the combination of Provisioning profile UUID and BundleID. This will be useful if you want to change the combination of Provisioning Profile and Certificate used for CodeSign when you build the application. "readFromProject" (Check "Read from Xcode Project") With this option, it automatically retrieve and sets the combination of BundleID and Provisioning profile UUID from the Xcode project file. This is useful when you want to take over the combination of BundleID and Provisioning profile UUID that you used in the Xcode project (GUI).|
-|Clean test reports? |cleanTestReports |1.3 |This will delete the processed test reports before invoking the build. Usually it is a good idea only to do it in test targets, otherwise if other Xcode target is built before tests – the build will fail to collect test reports.|
-|Clean ResultBundlePath? |cleanResultBundlePath |2.0.11 |This will delete the ResultBundlePath before invoking the build.|
-|Clean before build? |cleanBeforeBuild |1.0 |This will delete the build directories before invoking the build. This will force the rebuilding of ALL dependencies and can make large projects take a lot longer.|
+|Bundle ID |provisioningProfiles: [provisioningProfileAppId] |2.0.1 |Specify the Bundle ID of the application for which code sign to be performed. If the location of the Info.plist file contained in the compiled archive is set instead of the Bundle ID, read the Bundle ID from the Info.plist file and use that value.|
+|Provisioning Profiles | | | |
+|Provisioning profiles UUID |provisioningProfiles: [provisioningProfileUUID] |2.0.1 |Specify the UUID or Specifire of the provisioning profile to use to sign the application. If the location of the provisioning profile is set instead of the UUID or Specifire, read the UUID from the provisioning profile and use that value.
+|Copy provisioning profile |copyProvisioningProfile |2.0.7 |If Checked, and the filename of provisioning profile is specified in "Provisioning profile UUID", the specified file is copied to a predetermined place. ("/Users/${HOME}/Library/MobileDevice/Provisioning Profiles/") This can be used to overwrite the contents of the developer profile or system settings in the provisioning profile in the project deployed from SCM etc. If the provisioning profile UUID or Specifire is set in "provisioning profile UUID", it does not do anything. The default is "Yes" (check is on)|
|Change bundle ID? |changeBundleID |1.4 |Checking this option will replace the bundle identifier. You will need to specify which bundle ID (CFBundleIdentifier) to use and where is the Info.plist file located. This is handy for example when you want to use a different code signing identity in your development projects.|
+|New bundle ID |bundleID |1.4 |The new bundle ID. Usually something like com.companyname.projectname.|
+|Info.plist path |bundleIDInfoPlistPath |1.4 |The path to the info.plist file which contains the CFBundleIdentifier of your project. Usually something like: ${WORKSPACE}/ProjectName/Project-Info.plist|
+|Unlock Keychain? |unlockKeychain |1.0 |Automatically unlock the keychain before signing the archive?|
+|Keychain |keychainId |2.0.13 |The ID of the configured keychain info to use to retrieve certificates to sign the package. Register the keychain information in "credentials" before using it.|
+|~~Keychain name~~ |~~keychainName~~ This has been deprecated and has now been replaced by "keychainId".|1.4 |The name of the configured keychain to use to retrieve certificates to sign the package.|
+|Keychain path |keychainPath |1.0 |The path of the keychain to use to retrieve certificates to sign the package (default : ${HOME}/Library/Keychains/login.keychain).|
+|Keychain password |keychainPwd |1.0 |The password of the keychain to use to retrieve certificates to sign the package.|
+|Clean test reports? |cleanTestReports |1.3 |This will delete the processed test reports before invoking the build. Usually it is a good idea only to do it in test targets, otherwise if other Xcode target is built before tests – the build will fail to collect test reports.|
+|SDK |sdk |1.0 |You only need to supply this value if you want to specify the SDK to build against. If empty, the SDK will be determined by XCode. If you wish to run OCUnit tests, you will need to use the iPhone Simulator's SDK, for example: /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.1.sdk/|
+|SYMROOT |symRoot |1.1 |You only need to supply this value if you want to specify the SYMROOT path to use. If empty, the default SYMROOT path will be used (it could be different depending of your Xcode version). Supports all macros and also environment and build variables from the Token Macro Plugin. For example you can use the value : ${WORKSPACE}/build|
+|Custom xcodebuild arguments |xcodebuildArguments |1.3 |Passing custom arguments is convenient when you need to change some project options for Jenkins build, but don't want them to persist in project file. For example when running application tests, following settings often are nice fit: GCC_SYMBOLS_PRIVATE_EXTERN=NO COPY_PHASE_STRIP=NO. Otherwise Release build will usually fail because it won't be able to find application symbols to link with test bundle. Arguments are currently separated by space, enclosing them in quotes won't help.|
+|Xcode Workspace File |xcodeWorkspaceFile |1.2 |Only needed if you want to compile a workspace instead of a project. It takes precedence over 'Xcode Project File' setting and this job 'configuration' parameter.|
+|Xcode Project Directory |xcodeProjectPath |1.0 |This is the relative path from the workspace to the directory that contains the XCode project file. You only need to supply this value if the XCode project you wish to build is not in the root of the workspace.|
+|Xcode Project File |xcodeProjectFile |1.0 |If there is more than one XCode project file in the project path, you will need to specify the file name of the project you wish to build. If you need to build all project, you will need to create an XCode build step for each one manually.|
|Build output directory |buildDir |1.2 |The value to use for CONFIGURATION_BUILD_DIR setting (BUILD_DIR in >= 2.0.0). You only need to supply this value if you want the product of the XCode build to be in a location other than the one specified in project settings and this job 'SYMROOT' parameter. Supports all macros and also environment and build variables from the Token Macro Plugin. For example you can use the value : ${WORKSPACE}/build|
-|Asset pack URL |assetPackManifestURL |2.0.3 |Export settings for non-App Store App. If the application is using on-demand resources and the application will installing OTA with manifest.plist, this must be the base URL that specifies the host of the asset pack. This will set up the app to download the asset pack from the specified URL.|
-|Application URL |appURL |2.0.3 |Specify the URL for installing the application when creating the manifest.plist that is necessary when OTA installing the application from Web pages or email.|
-|Allow failing build results? |allowFailingBuildResults |1.4 |Checking this option will prevent this build step from failing if xcodebuild exits with a non-zero return code.|
-|.ipa filename pattern |ipaName |1.4 |A pattern for the ipa file name. You may use ${VERSION} and ${BUILD_DATE} (yyyy.MM.dd) in this string|
+|Technical version |cfBundleVersionValue |1.0 |This will set the CFBundleVersion to the specified string. Supports all macros and also environment and build variables from the Token Macro Plugin. For example the value ${BUILD_NUMBER} will be replaced with the current build number. We advice you to generate a unique value for each build if you want for example deploy it into a private store. In that case you can use for example : ${JOB_NAME}-${BUILD_NUMBER}|
+|Provide version number and run avgtool?|provideApplicationVersion|1.4 |Provide version number and run avgtool before invoking the build.|
+|Marketing version |cfBundleShortVersionStringValue|1.0 |This will set the CFBundleShortVersionString to the specified string. Supports all macros and also environment and build variables from the Token Macro Plugin.|
+|~~Manifest Plist URL~~ |~~ipaManifestPlistUrl~~ This was deprecated in 2.0.3.|1.5 |The base URL to use to create a Manifest Plist. If omitted no Manifest Plist will be generated.|
###### Setting up a Export IPA step
@@ -286,34 +360,34 @@ archive output in the Xcode Build step.
|Upload Symbols? |uploadSymbols |2.0.3 |If Checked, include symbols in IPA exporting for App Store. The default is "Yes" (check is on).
|Compile Bitcode? |compileBitcode |2.0.3 |If checked, Xcode will recompiling Bitcode and exporting IPA for the non App Store. The default is "Yes" (check is on).
|Thinning |thinning |2.0.3 |Set this to thin the packages for one or more devices in Xcode when exporting IPA by methods other than App Store.
Available options are: (Xcode export non-thinned generic application), (Xcode export universal applications and all available thinning variants), Or for a model identifier a specific device (eg "iPhone 7, 1").
The default is .
-|Pack on demand resources? |assetPacksInBundle |2.0.3 |Export settings for non App Store. If the application is using on demand resources and this item is on, the asset pack is included in the application bundle, so you can test the app without the server hosting the asset pack. If assetPacksBaseURL is not specified, the default is YES (check is on).
-|On demand resources asset URL |assetPacksBaseURL |2.0.3 |Export settings for non-App Store. If the application is using an on demand resource and assetPacksInBundle is not YES, this must be the base URL that specifies the host of the asset pack. This will set up the app to download the asset pack from the specified URL.
+|Pack on demand resources? |~~assetPacksInBundle~~ |2.0.3 |Export settings for non App Store. If the application is using on demand resources and this item is on, the asset pack is included in the application bundle, so you can test the app without the server hosting the asset pack. If assetPacksBaseURL is not specified, the default is YES (check is on).
+|On demand resources asset URL |~~assetPacksBaseURL~~ |2.0.3 |Export settings for non-App Store. If the application is using an on demand resource and assetPacksInBundle is not YES, this must be the base URL that specifies the host of the asset pack. This will set up the app to download the asset pack from the specified URL.
|Application URL |appURL |2.0.3 |Specify the URL for installing the application when creating the manifest.plist that is necessary when OTA installing the application from Web pages or email.
|Display image URL |displayImageURL |2.0.3 |Export settings for non App Store. Specify the URL of the image (57 x 57 pixels) of the icon to be displayed when installing the application using manifest.plist.
|Full size image URL |fullSizeImageURL |2.0.3 |Export settings for non App Store. Specify the URL of the image (512 x 512 pixels) of the icon to be displayed when installing the application using manifest.plist.
|Asset pack URL |assetPackManifestURL |2.0.3 |Export settings for non-App Store App. If the application is using on-demand resources and the application will installing OTA with manifest.plist, this must be the base URL that specifies the host of the asset pack. This will set up the app to download the asset pack from the specified URL.
|trip Swift Symbols? |stripSwiftSymbols |2.0.5 |If checked, symbols be stripped from Swift libraries when exporting the application to IPA.
|Manual signing? |manualSigning This has been deprecated and has now been replaced by "signingMethod".|2.0.1|For this option you need to manually specify the combination of Provisioning profile UUID and BundleID. This will be useful if you want to change the combination of Provisioning Profile and Certificate used for CodeSign when you build the application.
-|Code signing settings |signingMethod |2.0.7 |This attribute can take one of the following three values. - "automatic" (Check "Automatic Signing") Checking this option will automatically generate Provisioning Profile and certificates for signing application. However, please be aware that using this function will automatically create Provisioning profile and certificates as necessary, so that old Provisioning profile and certificates will be invalid at that time. - "manual" (Check "Manual signing") For this option you need to manually specify the combination of Provisioning profile UUID and BundleID. This will be useful if you want to change the combination of Provisioning Profile and Certificate used for CodeSign when you build the application. - "readFromProject" (Check "Read from Xcode Project") With this option, it automatically retrieve and sets the combination of BundleID and Provisioning profile UUID from the Xcode project file. This is useful when you want to take over the combination of BundleID and Provisioning profile UUID that you used in the Xcode project (GUI).
-|Provisioning Profiles Bundle ID|provisioningProfiles: [provisioningProfileAppId]|2.0.1|Specify the Bundle ID of the application for which code sign to be performed. If the location of the Info.plist file contained in the compiled archive is set instead of the Bundle ID, read the Bundle ID from the Info.plist file and use that value.
+|Code signing settings |signingMethod |2.0.7 |This attribute can take one of the following three values. "automatic" (Check "Automatic Signing") Checking this option will automatically generate Provisioning Profile and certificates for signing application. However, please be aware that using this function will automatically create Provisioning profile and certificates as necessary, so that old Provisioning profile and certificates will be invalid at that time. "manual" (Check "Manual signing") For this option you need to manually specify the combination of Provisioning profile UUID and BundleID. This will be useful if you want to change the combination of Provisioning Profile and Certificate used for CodeSign when you build the application. "readFromProject" (Check "Read from Xcode Project") With this option,it automatically retrieve and sets the combination of BundleID and Provisioning profile UUID from the Xcode project file. This is useful when you want to take over the combination of BundleID and Provisioning profile UUID that you used in the Xcode project (GUI).|
+|Bundle ID |provisioningProfiles: [provisioningProfileAppId]|2.0.1|Specify the Bundle ID of the application for which code sign to be performed. If the location of the Info.plist file contained in the compiled archive is set instead of the Bundle ID, read the Bundle ID from the Info.plist file and use that value.
|Provisioning profiles UUID |provisioningProfiles: [provisioningProfileUUID]|2.0.1|Specify the UUID or Specifire of the provisioning profile to use to sign the application. If the location of the provisioning profile is set instead of the UUID or Specifire, read the UUID from the provisioning profile and use that value.
|Unlock Keychain? |unlockKeychain |2.0.1 |Automatically unlock the keychain before signing the archive?
|Copy provisioning profile |copyProvisioningProfile |2.0.7 |If Checked, and the filename of provisioning profile is specified in "Provisioning profile UUID", the specified file is copied to a predetermined place. ("/Users/${HOME}/Library/MobileDevice/Provisioning Profiles/") This can be used to overwrite the contents of the developer profile or system settings in the provisioning profile in the project deployed from SCM etc. If the provisioning profile UUID or Specifire is set in "provisioning profile UUID", it does not do anything. The default is "Yes" (check is on)
-|Keychain name |keychainName |2.0.1 |The name of the configured keychain to use to retrieve certificates to sign the package.
-|Keychain name |keychainName |2.0.1 |The name of the configured keychain to use to retrieve certificates to sign the package.
+|Keychain |keychainId |2.0.13 |The ID of the configured keychain info to use to retrieve certificates to sign the package. Register the keychain information in "credentials" before using it.|
+|Keychain name |keychainName This has been deprecated and has now been replaced by "keychainId".|2.0.1 |The name of the configured keychain to use to retrieve certificates to sign the package.|
|Keychain path |keychainPath |2.0.1 |The path of the keychain to use to retrieve certificates to sign the package (default : ${HOME}/Library/Keychains/login.keychain).
|Keychain password |keychainPwd |2.0.1 |The password of the keychain to use to retrieve certificates to sign the package.
#### Compiling Xcode projects and exporting IPApackages using Jenkins's Pipeline function
-1. Import developer profile.
+1. Import developer profile.
``` syntaxhighlighter-pre
importDeveloperProfile(importIntoExistingKeychain: false,
profileId: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX')
```
-2. Build the project and output the archive.
+2. Build the project and output the archive.
``` syntaxhighlighter-pre
xcodeBuild(
@@ -332,7 +406,7 @@ archive output in the Xcode Build step.
)
```
-3. Export the IPA file from the archive.
+3. Export the IPA file from the archive.
``` syntaxhighlighter-pre
exportIpa(
@@ -353,7 +427,7 @@ archive output in the Xcode Build step.
)
```
-4. Upload the exported IPA file.
+4. Upload the exported IPA file.
> When using "XCode's" Automatically manage signing ", various ways are required, so please note the points to be noted separately.
@@ -365,13 +439,13 @@ Here's one strategy:
###### install multiple versions of xcode
-0\. Note current config.
-
-xcode-select -p
-
-1\. download xcode DMGs from
+1. Note current config.
+```
+ xcode-select -p
+```
+2. download xcode DMGs from
-2\. enable install from everywhere (under System preferences / Security)
+3. enable install from everywhere (under System preferences / Security)
Without that I had problems installing xcode, without graphical
feedback, tested on 10.9.5, freshly booted.
@@ -387,21 +461,21 @@ pid:57656 refs=6 @ 0x7fa5d9f6df40 but it still has
stopped. : LASApplication.cp \#2468 SetApplicationInStoppedState()
q=LSSession 100027/0x186bb queue
-3\. open DMG file, copy app to /Applications. This might take a while.
+3. open DMG file, copy app to /Applications. This might take a while.
-4\. close /Volumes/Xcode (otherwise installation won't start)
+4. close /Volumes/Xcode (otherwise installation won't start)
-5\. start Xcode, accept agreement, install missing packages if necessary.
+5. start Xcode, accept agreement, install missing packages if necessary.
This might take a while. Close xcode after GUI opens.
-6\. move freshly installed Xcode to new path, e.g.
+6. move freshly installed Xcode to new path, e.g.
sudo mv /Applications/Xcode.app /Applications/Xcode6.1.app
(I use this so that the xcode app appears with version number under
spotlight)
-7\. reset default xcode-select if necessary (installation might have
+7. reset default xcode-select if necessary (installation might have
changed it / reset to /Applications/Xcode.app)
sudo xcode-select -s /Applications/Xcode6.1.app
@@ -410,7 +484,7 @@ sudo xcode-select -s /Applications/Xcode6.1.app
###### Select the xcode version at runtime
-1\. Use EnvInject plugin
+1. Use EnvInject plugin
2. for jobs that require the non default do something like
DEVELOPER\_DIR=/Applications/Xcode6.0.1.app/Contents/Developer
@@ -436,7 +510,7 @@ This will block the build with a message like
`"User interaction is not allowed"` until it is dismissed.
Just select 'Always Allow' the first time and it shouldn't need to ask
again.
-![](docs/images/308d472628999c9f1961068c9af34e49a31c76c7.png)
+![](docs/images/Screenshot_2021-05-26_17.31.50.png)
If this prompt is not showing on the build machine, you can force it to
appear by running the codesign command that failed from a terminal on
@@ -445,16 +519,16 @@ Distribution: .....
##### No Xcode folder is set
-\[sources\] $ /usr/bin/xcodebuild -version xcode-select: Error: No Xcode
-folder is set. Run xcode-select -switch \ to set
+[sources] $ /usr/bin/xcodebuild -version xcode-select: Error: No Xcode
+folder is set. Run xcode-select -switch to set
the path to the Xcode folder. Error: /usr/bin/xcode-select returned
unexpected error. FATAL: Check your XCode installation. Jenkins cannot
retrieve its version.
-You probably just installed XCode (by default it is in `/Developer`) but
+You probably just installed Xcode (by default it is in `/Applications/Xcode.app/Contents/Developer`) but
its path isn't configured. You can fix it with
-xcode-select -switch /Developer/
+xcode-select -switch /Applications/Xcode.app/Contents/Developer
You should now be able to execute `xcodebuild`. Ex :
diff --git a/README_JA.md b/README_JA.md
new file mode 100644
index 00000000..86f03fc0
--- /dev/null
+++ b/README_JA.md
@@ -0,0 +1,449 @@
+Xcode plugin
+------------
+
+このプラグインは、Xcodeコマンドラインツールを呼び出して、iOSアプリケーション(iPhone、iPadなど)のビルドとパッケージ化を自動化する機能を追加します。
+* Jiraですべての問題または機能のリクエストを報告する: https://issues.jenkins-ci.org/issues/?jql=component%20%3D%20xcode-plugin
+
+[メールで](http://jenkins-ci.org/content/mailing-lists) または [ircで](http://jenkins-ci.org/content/chat) Jenkinsコミュニティに連絡してサポートを受けてください。
+
+*あなたの助けが必要です!!
+メンテナは共同メンテナを探しています。*
+
+プラグインの保守を支援するために、特に今後のリリースをテストできる場合は、「kazuhide.t アットマーク linux-powered.com」に連絡してください。
+
+ありがとうございました!
+
+問題、アイデア?
+
+*バグ、改善、または新機能を報告するには、タスクと問題トラッカーを使用してください。*
+
+- [Report a bug](https://issues.jenkins-ci.org/secure/CreateIssueDetails!init.jspa?Create=Create&components=16124&pid=10172&issuetype=1)
+- [Ask for a new feature](https://issues.jenkins-ci.org/secure/CreateIssueDetails!init.jspa?Create=Create&components=16124&pid=10172&issuetype=2)
+- [Ask for an improvement of an existing feature](https://issues.jenkins-ci.org/secure/CreateIssueDetails!init.jspa?Create=Create&components=16124&pid=10172&issuetype=4)
+
+また、Githubのプルリクエストを使用してコードの変更を提案する場合にはJiraのIssueもオープンしてください。
+開発者が問題を追跡するのが簡単になります。
+
+*重要!*
+
+最新バージョンは、2.0.12より前のバージョンとの互換性が維持されています。
+ただし、macOSキーチェーンの処理に大きな変更が加えられました。
+
+キーチェーンにアクセスするための情報は、「設定」から「認証情報」に移動されています。
+今後はキーチェーンにアクセスするための情報は「認証情報」に登録する必要があります。
+
+#### 機能
+
+このプラグインは、Xcodeコマンドラインツールを呼び出して、iOSアプリケーション(iPhone、iPadなど)のビルドとパッケージ化を自動化する機能を追加します。
+
+##### バージョン付け
+
+ビルドではagvtoolを呼び出して
+`CFBundleVersion` (別名テクニカルバージョン)や `CFBundleShortVersionString` (別名マーケティングバージョン)を動的に更新できます。
+'$'で始まるすべてのマクロをサポートします。
+たとえば、値 `${BUILD_NUMBER}` は現在のビルド番号に置き換えられます。
+たとえばアプリをプライベートストアにデプロイする場合には `CFBundleVersion` にビルドごとに一意の値を生成することが推奨されますが、
+このような場合、たとえば次のように使用できます: `${JOB_NAME}-${BUILD_NUMBER}`
+
+##### ビルド
+
+ビルドフェーズの前にクリーンアップを実行するかどうか、ターゲット(オプション)、構成(`Debug`や`Release`など)、SDK(オプション)などをプロジェクトごとに構成で指定できます。
+
+##### パッケージ化
+
+Xcodeビルドを使用して.appを.ipaにパッケージ化できます。
+.appは実際にはディレクトリであるため、取扱い、特に配布などが面倒な場合があります。
+.appを単一の.ipaファイルにパッケージ化することでこれを単純化できます。
+これは、よく知られた内部構造を持つ単なるzipファイルです。
+
+##### アプリへの署名
+
+このプラグインにはコード署名プロセスを簡素化するのに役立つ2つの機能があります。
+
+###### Jenkinsが開発者プロファイルをステージングできるようにする
+
+このプラグインは、Apple Developer Profile (*.developerprofile)ファイルを保存できるように構成されています。
+[このファイルには、コード署名秘密鍵、対応する開発者/配布証明書、およびモバイルプロビジョニングプロファイルが含まれています。](http://stackoverflow.com/questions/15154211/what-data-are-stored-in-developer-profile-file-exported-from-xcode)
+あなたは[XCodeからこのファイルを作成できます](http://stackoverflow.com/questions/10404931/copying-keys-and-certificates-to-another-one-mac-for-iphone-development).
+
+開発者プロファイルをJenkinsにアップロードするには、「Jenkinsの設定」ページの「Manage Credential(認証情報の管理)」に移動し、「認証情報の追加」ボタンから「Apple Developer Profile」を選択します。
+詳細については、「ヘルプ」を参照してください。
+
+このプロファイルを署名に使用するにはXcodeを実行する前にビルドステップとして「開発者プロファイルのインポート」を追加し、ビルドマシンにインポートする開発者プロファイルを選択します。
+このビルド手順では開発者プロファイルをスレーブのキーチェーンにインストールします。
+
+###### 既存の設定済みキーチェーンを操作する
+
+すべてのビルドスレーブにコード署名秘密鍵と証明書を格納する専用のキーチェーンを作成する場合、このキーチェーンのロックを解除するようにプラグインを構成できます(xcodeが署名に使用できるようにするため)
+
+ロックの解除
+
+キーを(おそらくは)ユーザーキーチェーンに保存し、jenkinsをデーモンとして実行する場合にはmacOS用jenkinsの最新バージョンをインストールしたか?、
+そしてセッションを作成するようにデーモンを構成したことを確認してください。(org.jenkins-ci.plistデーモン構成ファイルの`CreationSession = true` パラメーターを使用)
+[参考](http://stackoverflow.com/questions/9626447/unable-to-sign-ios-builds-with-jenkins)
+
+タイムアウト
+
+キーチェーンのデフォルトのタイムアウトは300秒です。 現在プラグインでサポートされていないsecurityset-keychain-settingsコマンドを使用してオーバーライドできます。 プラグインのサポートは、ビルドプロセスの一部としてタイムアウトを変更するオプションを追加することで改善できます。
+[JENKINS-17184を参照](https://issues.jenkins-ci.org/browse/JENKINS-17184)
+
+##### ユニットテスト
+
+このプラグインは、OCUnitまたはXCtestsを実行するときにxcodebuildの出力をリッスンし、Jenkinsが理解できるJUnit形式のテストレポートを書き出します。
+その後、ジェンキンスはこれらを使用して、テストの失敗レポートとグラフを公開します。
+
+##### 構成パネルのサンプル
+
+![](docs/images/ScreenShot_2021-04-29_16.05.56.png)
+
+#### Documentation
+
+##### インストールガイド
+
+もちろんビルドマシンはXcode開発ツールがインストールされたmacOS Xマシンである必要があります。
+証明書、ID、およびプロビジョニングはそれぞれのビルドマシンにインストールする必要があります。
+
+(これについては最新版のプラグインでは改善されていています。
+ビルドステップに先立ちマスターノードで「デベロッパープロファイルのインポート」を行うことでマスターノードからスレーブのノードへと「デベロッパープロファイル」を配布することができます。)
+
+アップデートセンターからプラグインの最新バージョンをインストールし、フリースタイルジョブ(#使い方のガイドを参照)でmacOS Xノードを使用するように構成するだけです(セントラルインスタンスがmacOSで実行されていない場合)。
+Xcode関連のバイナリがデフォルトの場所に保存されていない場合は、プラグインのグローバル構成を更新します(Jenkinsの管理->システムの設定)
+
+![](docs/images/ScreenShot_2021-04-19_14.29.25.png)
+
+複数のバージョンのXcodeを使用してアプリケーションを構築する場合は、「Global Tool Configuration」を使用して、インストールされているXcodeの名前とパス(場所)を登録します。
+
+![](docs/images/ScreenShot_2021-04-19_14.42.24.png)
+
+##### 使い方のガイド
+
+###### 開発者プロファイルのインポート手順
+
+「開発者プロファイルのインポート」ステップを「ビルド」に追加することでXcodeからエクスポートされた開発者プロファイルを一時キーチェーンまたは既存のキーチェーンにインポートします。
+開発者プロファイルにはアプリケーションのコンパイルと署名に必要な一連の証明書、秘密鍵、およびプロビジョニングプロファイルが含まれています。
+これは複数のJenkinsノードで配布パッケージをビルドする場合に便利です。
+
+###### 開発者プロファイルのインポート構成パラメーター
+
+| パラメータ | Pipelineのパラメータ | サポートバージョン | 概要 |
+|-------------------------------|----------------------------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| 開発者プロファイル | profileId | 2.0.1 | XcodeのPreferenceからエクスポートした開発者プロファイルを選択してキーチェーンにインポートします。 開発者プロファイルは「認証情報」によって事前にJenkinsに登録する必要があります。|
+| 既存のキーチェーンにインポート | importIntoExistingKeychain | 2.0.6 | チェックすると開発者プロファイルが既存のキーチェーンにインポートされます。 チェックされていない場合は、ファイル名「jenkins-」+「ジョブ名」で新しいキーチェーンを新たに作成し、開発者プロファイルをこれにインポートします。(この場合、ランダムな文字列が自動的に生成され、パスワードに使用されます)|
+| 対象のキーチェーン | keychainId | 2.0.13 | パッケージに署名するために開発者プロファイルから証明書をインポートするために使用する、構成済みのキーチェーンのID。|
+| ~~対象のキーチェーン~~ | ~~keychainName~~ これは非推奨になり「keychainId」に置き換えられました。| 2.0.6 | パッケージに署名するために開発者プロファイルから証明書をインポートするために使用する、設定済みのキーチェーンの名前。|
+| キーチェーンのパス | keychainPath | 2.0.6 | 開発者プロファイルをインポートするキーチェーンパス。 |
+| キーチェーンのパスワード | keychainPwd | 2.0.6 | 開発者プロファイルをインポートするキーチェーンのロックを解除するためのパスワード。 |
+| AppleWWDRCA | appleWWDRCACertId | 2.0.15 | macOSキーチェーンからエクスポートしたAppleWWDRCA(中間証明書)を選択してJenkinsノードのキーチェーンにインポートします。 AppleWWDRCAは「認証情報」によって予めJenkinsに登録する必要があります。 |
+
+###### macOSキーチェーンからAppleWWDRCA(中間証明書)をエクスポートする方法
+
+Xcodeを日常的に使用する環境にあり、Xcodeを使用してアプリにコード署名できる場合はmacOSキーチェーンの中に必要なAppleWWDRCA中間証明書があります。
+「キーチェーンアクセス」ユーティリティを使ってこれをエクスポートできます。
+
+macOSキーチェーンからAppleWWDRCA(中間証明書)をエクスポートする場合は、次のようにすべての「Apple Worldwide Developer Relations Certification Authority」(2023年に有効期限切れのものと2030年に有効期限切れのもの)と「AppleDeveloper ID Certification Authority」を選択してエクスポートします。
+
+![Select certificates](docs/images/ScreenShot_2021-04-19_16.52.10.png)
+
+コンテキストメニューから「3項目を書き出す…」を選択します。
+
+![Select export items](docs/images/ScreenShot_2021-04-19_16.55.38.png)
+
+エクスポートするときは、「フォーマット:」に「証明書(.cer)」を選択してください。
+
+![export certificates](docs/images/ScreenShot_2021-04-20_9.53.59.png)
+
+Jenkinsノードがクラウドサービスなどのリモートロケーションにある場合など、WWDRCA中間証明書がmacOSにインストールされていない環境では「認証局」ページ(https://www.apple.com)から証明書をダウンロードできます。 Apple DeveloperPortalの/ certificateauthority /)を使用してください。
+
+![Select certificates](docs/images/ScreenShot_2021-04-13_22.39.25.png)
+
+Apple Developer Portalからダウンロードしたファイル(拡張子.cer)はバイナリ形式のDER形式であるため、opensslコマンドを使用してBASE64でエンコードされたテキストに変換し、ダウンロードした3つのファイルを1つのファイルに結合します。
+
+```shell
+% (openssl x509 -in ~/Downloads/DeveloperIDCA.cer -inform der -out - && \
+openssl x509 -in ~/Downloads/AppleWWDRCA.cer -inform der -out - && \
+openssl x509 -in ~/Downloads/AppleWWDRCAG3.cer -inform der -out -) > AppleWWDRCA.cer
+```
+
+キーチェーンアクセスを使用して証明書をエクスポートする場合でも、Apple Developer Portalからダウンロードしたファイルを変換して結合する場合でも、結果のAppleWWDRCA.cerファイルの内容は同じになります。
+
+###### AppleWWDRCA(中間証明書)をJenkinsの認証情報にインポートする方法
+
+ダッシュボードで「Jenkinsの管理」を選択します。
+
+![Select Manage Jenkins](docs/images/ScreenShot_2021-04-20_10.41.22.png)
+
+「Manage Credentials」を選択します。
+
+![Select Manage Credentials](docs/images/ScreenShot_2021-04-13_21.58.31.png)
+
+「Stores scoped to Jenkins」から「(grobal)」をクリックし、表示されたページの左上から「クレデンシャルを追加」を選択すると、「グローバル」ドメインに新しいクレデンシャルを追加できます。
+
+![Select (grobal)](docs/images/ScreenShot_2021-04-13_21.59.20.png)
+
+そして「認証情報の追加」をクリックします。
+
+![Select Add Credentials](docs/images/ScreenShot_2021-04-20_10.42.03.png)
+
+「種類」には、「Apple Worldwide Developer Relations Certification Authority」を選択します。
+次に、「ファイルを選択」をクリックします。
+
+![Select Choose file](docs/images/ScreenShot_2021-04-20_10.45.25.png)
+
+事前にキーチェーンからエクスポートしたか、Apple Developer Portalからダウンロードした証明書ファイル(.cer)を選択してアップロードします。
+
+![Select .cer file from chooser](docs/images/ScreenShot_2021-04-20_10.49.56.png)
+
+
+###### 制約
+
+Xcode統合プラグインは開発者アカウントの秘密鍵と証明書を一時キーチェーンにインポートする機能を備えていますが、macOSの制約でセッションごとに異なるキーチェーンを処理することができないため、並行してキーチェーンを処理するジョブを実行するとこれは正しく機能しません。
+
+この回避策の1つとして、Jenkinsのノードでのジョブの最大数を1に制限し、異なるmacOSアカウントで複数のノードを実行することは可能です。
+
+###### ビルド手順の追加
+
+「Xcodeビルド手順」をフリースタイルプロジェクトに追加し、「ターゲット」(`MyApp`など)、「Configuration」(`Release`など)を設定し、「アプリケーションを署名、パックして.ipaを作成」をチェックしてバージョン番号オプションを更新します。
+これによりバージョン管理された単一の.ipaファイルが提供されます。
+ビルド前にプロジェクトをクリーンアップすることを選択することもできます。
+これによりプロジェクトがクリーンな状態から開始されるようになりますが、大規模なプロジェクトでビルドにかなり時間がかか流ようになります。
+
+###### ユニットテスト手順の追加
+
+「Xcodeビルド手順」を追加し、今回は単体テストの「ターゲット」(例えば、`MyAppTests`)、「Configuration」(例えば、`Debug`)、SDK(例えば、`Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.4.sdk/`などを指定します)。
+SDKのパスはXcodeのディレクトリ(環境変数`DEVELOPER_DIR`で指定でき、`xcode-select -p`コマンドで確認可能)からの相対位置で指定します。
+すべてのチェックボックスをオフのままにします。
+
+単体テストはシミュレーターのSDKでビルドする場合にのみ実行されるため、SDKをここで指定する必要があります。
+以下の項目は現在のバージョンには存在せず、代わりに「ResultBundlePath」が指定されているかどうかでテストレポート出力の有無を判断します。(ResultBundlePathが空ならレポートは出力されない)
+~~プロジェクト構成の「JUnitテスト結果レポートの公開」オプションをチェックし、「テストレポートXML」の下に値 `" * `` / test-reports / `` * .xml "`を設定します。 これにより、JenkinsはJUnit形式のテストレポートを取得するようになります。~~
+
+###### XCodeビルドの設定パラメーター
+
+| パラメータ | Pipelineのパラメータ | ポートバージョン | 概要 |
+|-------------------------------|---------------------------|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+|開発者チーム |developmentTeamName |1.4 |パッケージへの署名に使用する登録済みの開発チームの名前。 Xcode 8.3以降、これはipaに署名する(現在はxcodebuilderを使用)ために必要です。 チームを設定するには、ここでJenkinsグローバル構成で登録したチームの名前を選択するか次で開発チームIDを指定できます。|
+|開発者チームのID |developmentTeamID |1.4 |「開発者チーム」が選択されていない場合にIPAに署名するために使用するApple開発者チームのIDを指定します。|
+|Xcode toolsのバージョン |xcodeName |2.0.3 |「Jenkinsの設定」の「Global Tool Configuration」で設定したXcodeのバージョンを選択できます。 Xcodeのバージョンで「システムの設定」を選択した場合、プラグインは何もしないので環境変数「DEVELOPER_DIR」を使用してXcodeを切り替えることができます。|
+|旧来のビルドシステムを使用する |useLegacyBuildSystem |2.0.9 |Xcode 9以降の「New Build System」の代わりに、旧来の「Regacy Build System」を使用します。|
+|ターゲット |target |1.0 |ビルドするターゲット。 空のままにするとプロジェクト内のすべてのターゲットがビルドされます。 バイナリと単体テスト用のモジュールを構築する場合には、それぞれを独自のターゲットを持つ2つの別々のビルド手順として設定するとよいでしょう。そうすることでiPhone Simulator SDKを単体テストで指定できます。|
+|ターゲットを正規表現で評価 |interpretTargetAsRegEx |1.4 |xcodebuild -listの出力で「Targets:」部分ににリストされる中から正規表現に一致するすべてのエントリをビルドします。|
+|ビルド前に消去 |cleanBeforeBuild |1.0 |チェックするとビルドを開始する前にビルドディレクトリが削除されます。 これによりすべての依存関係の再ビルドが強制され、大規模なプロジェクトのビルドにかかる時間が大幅に長くなる可能性があります。|
+|処理に失敗しても続行 |allowFailingBuildResults |1.4 |このオプションをチェックするとxcodebuildがゼロ以外の終了コードで終了した場合でもこのビルドステップが失敗するのを防ぐことができます。|
+|コンソールログを出力しない |noConsoleLog |2.0.1 |このオプションをチェックするとxcodeビルドの出力はコンソールログに記録されません。|
+|ログファイルの出力先 |logfileOutputDirectory |2.0.1 |xcodebuildのログを出力するディレクトリを指定します。 空白のままにすると他のログとともに「プロジェクトディレクトリ/builds/${BUILD_NUMBER}/log」に出力されます。 出力パスを指定した場合、「ビルド出力ディレクトリ」以下の相対ディレクトリにxcodebuild.logファイルとして出力されます。|
+|ResultBundlePath |resultBundlePath |2.0.11 |テスト結果の出力リディレクトリを設定します。 空のままにするとテスト結果は出力されず、テスト結果の分析も行われません。プロジェクトディレクトリ以下の相対位置で指定します。|
+|ResultBundlePathを消去 |cleanResultBundlePath |2.0.11 |これによりビルドを呼び出す前にResultBundlePathが削除されます。|
+|Configuration |configuration |1.0 |Xcodeプロジェクトで定義されている「Configuration」の名前を指定します。 デフォルトでは「Debug」と「Release」Configurationがあります。|
+|Xcode Schemaファイル |xcodeSchema |1.2 |ターゲットではなく特定のスキーマ用にコンパイルする場合、またはアーカイブやIPAを生成する場合に必要です。|
+|アーカイブを作成 |generateArchive |2.0 |このオプションをチェックすると指定したスキームのxcarchiveが生成されます。アーカイブにはワークスペースとスキームも必要です。|
+|アプリケーションに署名、パックして.ipaを作成|buildIpa |1.0 |ここがチェックされていたならxcarchiveからパックされた単一の.ipaファイルを生成します。 .ipaファイルはアプリをテストサイトで配布したりApp Storeへとアップロードするのに使います。|
+|エクスポートの方法 |ipaExportMethod |1.4 |.ipaファイルを生成するための.appのエクスポート方法。「development」、「ad-doc」、「enterprise」、または「app-store」のいずれかである必要があります。|
+|.ipaファイル名のパターン |ipaName |1.4 |生成する.ipaファイル名のパターン。 この文字列ではマクロ ${VERSION} と ${BUILD_DATE} (yyyy.MM.dd)を使用できます。|
+|出力ディレクトリ |ipaOutputDirectory |1.4 |ビルドディレクトリからの相対位置で指定した.ipaファイルの出力ディレクトリ。|
+|Bitcodeをアップロード |uploadBitcode |2.0.3 |チェックされている場合にはApp StoreのIPAエクスポートにBitcodeを含めます。 デフォルトは「はい」(チェックはオンです)です。|
+|シンボルをアップロード |uploadSymbols |2.0.3 |チェックされている場合にはApp StoreのIPAエクスポートにシンボルを含めます。 デフォルトは「はい」(チェックはオンです)です。|
+|Bitcodeをコンパイル |compileBitcode |2.0.3 |チェックされているなら、アプリケーションをIPAにエクスポートする際にBitcodeから再コンパイルします。 デフォルトは「はい」(チェックはオン)です。|
+|最適化 |thinning |2.0.3 |App Storeでの配布用以外のIPAをエクスポートするときにアプリ内の複数のデバイス向けパッケージを最適化するように設定します。
使用可能なオプションは次のとおりです。 - \ (Xcodeは最適化されない汎用アプリケーションをエクスポートします。) - \ (Xcodeはユニバーサルアプリと最適化可能なすべての対象向けのアプリをエクスポートします。) - モデル識別子の場合は特定のデバイス(「iPhone7,1」など向けのアプリをエクスポートします。) デフォルトは\です。|
+|オンデマンドリソースを含める |~~assetPacksInBundle~~ assetPacksInBundle| 2.0.3 |App Storeでの配布用以外のIPAをエクスポートするときの設定です。 アプリケーションがオンデマンドリソースを使用していて、この項目がオンの場合、アセットパックはアプリケーションバンドルに含まれるため、アセットパックをホストしているサーバーなしでアプリをテストできます。 AssetPacksBaseURLが指定されていない場合、デフォルトでオンになります(チェックがオンになっています)。|
+|オンデマンドリソースのURL |~~assetPacksBaseURL~~ assetPacksBaseURL |2.0.3 |App Storeでの配布用以外のIPAをエクスポートするときの設定です。 アプリケーションがオンデマンドリソースを使用していて、assetPacksInBundleがオンでない場合、これはアセットパックのホストを指定するベースURLである必要があります。 これにより指定したURLからアセットパックをダウンロードするようにアプリが設定されます。|
+|アプリケーションのURL |appURL |2.0.3 |App Storeでの配布用以外のIPAをエクスポートするときの設定です。 OTAでWebページや電子メールからアプリケーションをインストールするときに必要なmanifest.plistを作成するときに、アプリケーションをインストールするためのURLを指定します。|
+|表示するイメージのURL |displayImageURL |2.0.3 |App Storeでの配布用以外のIPAをエクスポートするときの設定です。 manifest.plistを使用してアプリケーションをインストールするときに表示されるアイコンの画像(57x57ピクセル)のURLを指定します。|
+|フルサイズイメージのURL |fullSizeImageURL |2.0.3 |App Storeでの配布用以外のIPAをエクスポートするときの設定です。 manifest.plistを使用してアプリケーションをインストールするときに表示されるアイコンの画像(512x512ピクセル)のURLを指定します。|
+|アセットパックのURL |assetPackManifestURL |2.0.3 |App Storeでの配布用以外のIPAをエクスポートするときの設定です。 アプリケーションがオンデマンドリソースを使用していて、アプリケーションがmanifest.plistを使用してOTAインストールする場合、これはアセットパックのホストを指定するベースURLである必要があります。 これにより指定したURLからアセットパックをダウンロードするようにアプリが設定されます。|
+|Swiftのシンボルを削除 |stripSwiftSymbols |2.0.5 |チェックするとアプリケーションをIPAにエクスポートするときにシンボルがSwiftライブラリから削除されます。|
+|~~手動でコード署名を行なう~~ |~~manualSigning~~ これは非推奨となり「signingMethod」に置き換えられました。|2.0.1 |このオプションでは、プロビジョニングプロファイルUUIDとBundleIDの組み合わせを手動で指定する必要があります。 これは、組み合わせを変更する場合に役立ちます。 アプリケーションのビルド時にCodeSignに使用されるプロビジョニングプロファイルと証明書の一覧。|
+|コード署名とキーチェーンのオプション |signingMethod |2.0.7 |ここでは次の3つの値のいずれかを指定できます。 自動で署名 (「自動署名」をオンにする) このオプションをオンにすると、アプリケーションに署名するためのプロビジョニングプロファイルと証明書が自動的に生成されます。 この機能を使用すると、必要に応じてプロビジョニングプロファイルと証明書が自動的に作成されるため、その時点で古いプロビジョニングプロファイルと証明書は無効になるので注意してください。 手動で設定 (「手動で設定」をチェック) このオプションでは、プロビジョニングプロファイルUUIDとBundleIDの組み合わせを手動で指定します。 これは、アプリケーションのビルド時にCodeSignに使用されるプロビジョニングプロファイルと証明書の組み合わせを変更する場合に役立ちます。 プロジェクトから読み取る (「プロジェクトに従う」をオンにします。) このオプションを使用すると、XcodeプロジェクトファイルからBundleIDとプロビジョニングプロファイルUUIDの組み合わせを自動的に取得して設定します。 これはXcodeプロジェクト(GUI)で使用したプロビジョニングプロファイルのUUIDやBundle IDの組み合わせをそのまま引き継ぐ場合に便利です。|
+|Bundle ID |provisioningProfiles: [provisioningProfileAppId] |2.0.1 |コードサインを実行するアプリケーションのバンドルIDを指定します。 バンドルIDの代わりにコンパイル済みアーカイブに含まれるInfo.plistファイルの場所が設定されている場合は、Info.plistファイルからバンドルIDを読み取り、その値を使用します。|
+|プロビジョニングプロファイル |provisioningProfiles: [provisioningProfileUUID] |2.0.1 |アプリケーションの署名に使用するプロビジョニングプロファイルのUUIDまたはSpecifireを指定します。 UUIDまたはSpecifireの代わりにプロビジョニングプロファイルの場所が設定されている場合は、プロビジョニングプロファイルからUUIDを読み取り、その値を使用します。|
+|プロビジョニングプロファイルをコピーする|copyProvisioningProfile |2.0.7 |チェックすると、プロビジョニングプロファイルのファイル名が「プロビジョニングプロファイルUUID」で指定されている場合、指定されたファイルが所定の場所にコピーされます。 ("/Users/${HOME}/Library/MobileDevice/Provisioning Profiles/") これを使用して、SCMなどからデプロイされたプロジェクトのプロビジョニングプロファイルの開発者プロファイルまたはシステム設定の内容を上書きできます。 プロビジョニングプロファイルUUIDまたはSpecifireが「プロビジョニングプロファイルUUID」に設定されている場合、何も実行されません。 デフォルトは「はい」(チェックがオン)です。|
+|Bundle IDの変更 |changeBundleID |2.0.1 |このオプションをチェックするとバンドル識別子が置き換えられます。 使用するバンドルID(CFBundleIdentifier)と、Info.plistファイルの場所を指定する必要があります。 これは開発プロジェクトのコード署名IDに別のバンドルIDを使用する場合などに便利です。|
+|新しいBundle ID |bundleID |2.0.1 |新しいバンドルID。 通常、com.companyname.projectnameのような形式です。|
+|Info.plistのパス |bundleIDInfoPlistPath |2.0.1 |プロジェクトのCFBundleIdentifierを含むinfo.plistファイルへのパス。 通常は次のようになります。 ${WORKSPACE}/ProjectName/Project-Info.plist|
+|キーチェーンをアンロック |unlockKeychain |2.0.1 |チェックするとアーカイブに署名する前に、キーチェーンのロックを自動的に解除します。|
+|キーチェーン |keychainId |2.0.13 |パッケージに署名するための証明書を取得するために使用する、登録済みのキーチェーン情報のID。 キーチェーンの情報は事前に「認証情報」へと登録しておきます。|
+|~~キーチェーンの名前~~ |~~keychainName~~ これは非推奨となり「keychainId」に置き換えられました。|2.0.1 |パッケージに署名するための証明書を取得するために使用する、登録済みのキーチェーンの名前。|
+|キーチェーンのパス |keychainPath |2.0.1 |パッケージに署名するための証明書を取得するために使用するキーチェーンのパス。 (デフォルトは:${HOME}/Library/Keychains/login.keychain-db)|
+|キーチェーンのパスワード |keychainPwd |2.0.1 |パッケージに署名するための証明書を取得するために使用するキーチェーンのパスワード。|
+
+#### Jenkinsのパイプライン関数を使用したXcodeプロジェクトのコンパイルとIPAパッケージのエクスポート
+
+1. 開発者プロファイルをインポートします。
+
+ ``` syntaxhighlighter-pre
+ importDeveloperProfile(importIntoExistingKeychain: false,
+ profileId: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX')
+ ```
+
+2. プロジェクトをビルドし、アーカイブを出力します。
+
+ ``` syntaxhighlighter-pre
+ xcodeBuild(
+ xcodeSchema: "${PROJECT_SCHEMA}",
+ ipaOutputDirectory: 'Release',
+ ipaExportMethod: 'app-store',
+ generateArchive: true,
+ buildIpa: true,
+ ipaName: "${BUILD_TARGET}",
+ bundleID: 'com.example.TargetApp',
+ developmentTeamName: "${DEVELOPMENT_TEAM_NAME}",
+ cleanBeforeBuild: true,
+ configuration: 'Release',
+ cfBundleShortVersionStringValue: '1.0.0',
+ cfBundleVersionValue: '1'
+ )
+ ```
+
+3. アーカイブからIPAファイルをエクスポートします。
+
+ ``` syntaxhighlighter-pre
+ exportIpa(
+ archiveDir: "${WORKSPACE}/${repositoryName}/build/Release-iphoneos",
+ xcodeSchema: "${PROJECT_SCHEMA}",
+ developmentTeamName: "${DEVELOPMENT_TEAM}",
+ configuration: "AdHoc",
+ infoPlistPath: "${INFO_PLIST}",
+ manualSigning: true,
+ provisioningProfiles: [
+ [provisioningProfileAppId: "${BUNDLE_ID}", provisioningProfileUUID: 'TestApp_AdHoc_Profile.mobileprovision']
+ [provisioningProfileAppId: "${BUNDLE_ID}.watchkitapp", provisioningProfileUUID: 'TestApp_AdHoc_Profile.mobileprovision'],
+ [provisioningProfileAppId: "${BUNDLE_ID}.watchkitapp.watchkitextension", provisioningProfileUUID: 'TestApp_AdHoc_Profile.mobileprovision']
+ ],
+ ipaExportMethod: "ad-hoc",
+ ipaName: "${BUILD_TARGET}",
+ ipaOutputDirectory: "AdHoc"
+ )
+ ```
+
+4. エクスポートされたIPAファイルをアップロードします。
+
+> XCodeの「署名の自動管理」を利用する場合、さまざまな方法が必要になりますので、別途ご注意ください。
+
+##### 複数のバージョンのXcodeを使用する。
+
+環境変数を使用することで、複数のバージョンを簡単にサポートできます。
+ただし、最初にビルドサーバーに複数のバージョンをインストールする必要があります。
+これが1つの戦略です:
+
+###### xcodeの複数のバージョンをインストールする
+
+1. 現在の設定を覚えておきましょう
+
+
+ xcode-select -p
+
+2. Xcodeの.xipファイルを からダウンロードします
+
+3. ダウンロードした.xipファイルを任意の場所に展開します
+
+###### 実行するXcodeのバージョンを選択します
+
+1. EnvInjectプラグインを使用する
+2. デフォルト以外のXcodeを必要とするジョブの場合では次のように環境変数を設定します
+
+
+ DEVELOPER_DIR=/Applications/Xcode6.0.1.app/Contents/Developer
+
+ビルドプロセスへの環境変数の挿入
+
+###### 実行時にXcodeバージョンを選択します (バージョン2.0.3以降)
+
+1. 「Global Tool Configuration(グローバルツールの設定)」を使用してインストールされているXcodeの識別名と場所を登録します。
+2. ジョブの「Xcodeツールバージョン」で「グローバルツール構成」に登録されているXcodeを選択します。
+
+それだけです!
+
+#### FAQ
+
+##### User interaction is not allowed(ユーザーの操作は許可されていません)
+
+コード署名が実行される時にキーチェーンアクセスを許可するかどうかを尋ねるダイアログがビルドマシンに表示される場合があります。
+「User interaction is not allowed(ユーザーの操作は許可されていません)」などのメッセージが表示され、これが解除されるまでビルドがブロックされます。
+これは最初に「常に許可」を選択すれば再度質問されることはありません。
+
+![](docs/images/ScreenShot_2021-05-25_22.31.15.png)
+
+このダイアログがビルドマシンに表示されない場合は、強制的に
+ビルドマシンのターミナルから失敗したcodesignコマンドを実行すると表示されます:/usr/bin/codesign --force --sign "iPhone Distribution:...."
+
+##### No Xcode folder is set(Xcodeフォルダが設定されていません)
+
+[ソース] $ /usr/bin/xcodebuild -version
+xcode-select:エラー:Xcodeフォルダーが設定されていません。
+xcode-select -switch を実行して、Xcodeフォルダーへのパスを設定します。
+エラー:/usr/bin/xcode-selectが予期しないエラーを返しました。
+致命的:Xcodeのインストールを確認してください。
+Jenkinsはそのバージョンを取得できません。
+
+おそらくXCodeをインストールしたばかりでそのパス(デフォルトでは `/Applications/Xcode.app/Contents/Developer`にあります)が構成されていません。 あなたはそれを修正することができます
+
+ xcode-select -switch /Applications/Xcode.app/Contents/Developer/
+
+これで、 `xcodebuild`を実行できるようになります。 例:
+
+ % xcodebuild -version
+ Xcode 12.5
+ Build version 12E262
+
+##### Xcode 4.3
+
+Xcode 4.3 で変更された [2つのこと](https://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles/xcode_4_3.html)
+スレーブまたはマスターでの使用に重要なもの :
+
+- **コマンドラインツールはオプションです** : コマンドラインツールは、デフォルトではXcodeにバンドルされていません。 代わりに、[ダウンロード]設定パネルの[コンポーネント]タブを使用してインストールする必要があります
+ ![](docs/images/8f2803dc1d2d272296cfa2ba044a3286e29a374c.jpg)
+- **Developer No Longer Existsなどエラーになったら** : 次のようにパスを再構成する必要がある場合があります。
+
+
+ % sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer/
diff --git a/docs/images/ScreenShot_2021-04-13_21.04.34.png b/docs/images/ScreenShot_2021-04-13_21.04.34.png
new file mode 100644
index 00000000..abc128c7
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-13_21.04.34.png differ
diff --git a/docs/images/ScreenShot_2021-04-13_21.05.45.png b/docs/images/ScreenShot_2021-04-13_21.05.45.png
new file mode 100644
index 00000000..0e01ee36
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-13_21.05.45.png differ
diff --git a/docs/images/ScreenShot_2021-04-13_21.06.34.png b/docs/images/ScreenShot_2021-04-13_21.06.34.png
new file mode 100644
index 00000000..b32de6f8
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-13_21.06.34.png differ
diff --git a/docs/images/ScreenShot_2021-04-13_21.58.10.png b/docs/images/ScreenShot_2021-04-13_21.58.10.png
new file mode 100644
index 00000000..5e6a19fe
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-13_21.58.10.png differ
diff --git a/docs/images/ScreenShot_2021-04-13_21.58.31.png b/docs/images/ScreenShot_2021-04-13_21.58.31.png
new file mode 100644
index 00000000..ac935fa4
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-13_21.58.31.png differ
diff --git a/docs/images/ScreenShot_2021-04-13_21.59.20.png b/docs/images/ScreenShot_2021-04-13_21.59.20.png
new file mode 100644
index 00000000..e3d17f11
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-13_21.59.20.png differ
diff --git a/docs/images/ScreenShot_2021-04-13_22.00.05.png b/docs/images/ScreenShot_2021-04-13_22.00.05.png
new file mode 100644
index 00000000..6024c629
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-13_22.00.05.png differ
diff --git a/docs/images/ScreenShot_2021-04-13_22.03.04.png b/docs/images/ScreenShot_2021-04-13_22.03.04.png
new file mode 100644
index 00000000..0284e2a6
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-13_22.03.04.png differ
diff --git a/docs/images/ScreenShot_2021-04-13_22.03.30.png b/docs/images/ScreenShot_2021-04-13_22.03.30.png
new file mode 100644
index 00000000..bb998631
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-13_22.03.30.png differ
diff --git a/docs/images/ScreenShot_2021-04-13_22.04.04.png b/docs/images/ScreenShot_2021-04-13_22.04.04.png
new file mode 100644
index 00000000..a82a019a
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-13_22.04.04.png differ
diff --git a/docs/images/ScreenShot_2021-04-13_22.39.25.png b/docs/images/ScreenShot_2021-04-13_22.39.25.png
new file mode 100644
index 00000000..a836f458
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-13_22.39.25.png differ
diff --git a/docs/images/ScreenShot_2021-04-19_13.25.38.png b/docs/images/ScreenShot_2021-04-19_13.25.38.png
new file mode 100644
index 00000000..1f171a55
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-19_13.25.38.png differ
diff --git a/docs/images/ScreenShot_2021-04-19_14.17.49.png b/docs/images/ScreenShot_2021-04-19_14.17.49.png
new file mode 100644
index 00000000..8f475748
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-19_14.17.49.png differ
diff --git a/docs/images/ScreenShot_2021-04-19_14.29.25.png b/docs/images/ScreenShot_2021-04-19_14.29.25.png
new file mode 100644
index 00000000..2ce66842
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-19_14.29.25.png differ
diff --git a/docs/images/ScreenShot_2021-04-19_14.42.24.png b/docs/images/ScreenShot_2021-04-19_14.42.24.png
new file mode 100644
index 00000000..2888579d
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-19_14.42.24.png differ
diff --git a/docs/images/ScreenShot_2021-04-19_16.52.10.png b/docs/images/ScreenShot_2021-04-19_16.52.10.png
new file mode 100644
index 00000000..492da991
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-19_16.52.10.png differ
diff --git a/docs/images/ScreenShot_2021-04-19_16.55.38.png b/docs/images/ScreenShot_2021-04-19_16.55.38.png
new file mode 100644
index 00000000..98a57d5a
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-19_16.55.38.png differ
diff --git a/docs/images/ScreenShot_2021-04-20_10.41.22.png b/docs/images/ScreenShot_2021-04-20_10.41.22.png
new file mode 100644
index 00000000..1fd85a4e
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-20_10.41.22.png differ
diff --git a/docs/images/ScreenShot_2021-04-20_10.42.03.png b/docs/images/ScreenShot_2021-04-20_10.42.03.png
new file mode 100644
index 00000000..9e29a388
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-20_10.42.03.png differ
diff --git a/docs/images/ScreenShot_2021-04-20_10.45.25.png b/docs/images/ScreenShot_2021-04-20_10.45.25.png
new file mode 100644
index 00000000..be09e3be
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-20_10.45.25.png differ
diff --git a/docs/images/ScreenShot_2021-04-20_10.49.56.png b/docs/images/ScreenShot_2021-04-20_10.49.56.png
new file mode 100644
index 00000000..23c8f44c
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-20_10.49.56.png differ
diff --git a/docs/images/ScreenShot_2021-04-20_9.53.59.png b/docs/images/ScreenShot_2021-04-20_9.53.59.png
new file mode 100644
index 00000000..c5f485c7
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-20_9.53.59.png differ
diff --git a/docs/images/ScreenShot_2021-04-29_16.05.56.png b/docs/images/ScreenShot_2021-04-29_16.05.56.png
new file mode 100644
index 00000000..22b727cc
Binary files /dev/null and b/docs/images/ScreenShot_2021-04-29_16.05.56.png differ
diff --git a/docs/images/ScreenShot_2021-05-25_22.31.15.png b/docs/images/ScreenShot_2021-05-25_22.31.15.png
new file mode 100644
index 00000000..1dfb85ef
Binary files /dev/null and b/docs/images/ScreenShot_2021-05-25_22.31.15.png differ
diff --git a/docs/images/Screenshot_2021-05-26_17.31.50.png b/docs/images/Screenshot_2021-05-26_17.31.50.png
new file mode 100644
index 00000000..2c325ad0
Binary files /dev/null and b/docs/images/Screenshot_2021-05-26_17.31.50.png differ
diff --git a/pom.xml b/pom.xml
index aedfd73d..06e2e3e1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -70,7 +70,7 @@
scm:git:git@github.com:jenkinsci/xcode-plugin.gitscm:git:git@github.com:jenkinsci/xcode-plugin.githttps://github.com/jenkinsci/xcode-plugin
- xcode-plugin-2.0.11
+ xcode-plugin-2.0.15
diff --git a/src/main/java/au/com/rayh/AppleWWDRCA.java b/src/main/java/au/com/rayh/AppleWWDRCA.java
new file mode 100644
index 00000000..e91e8bf9
--- /dev/null
+++ b/src/main/java/au/com/rayh/AppleWWDRCA.java
@@ -0,0 +1,118 @@
+package au.com.rayh;
+
+import com.cloudbees.plugins.credentials.CredentialsProvider;
+import com.cloudbees.plugins.credentials.domains.DomainRequirement;
+import hudson.Extension;
+import hudson.security.ACL;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.GeneralSecurityException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.*;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+
+import jenkins.security.ConfidentialKey;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.io.IOUtils;
+import org.kohsuke.stapler.DataBoundConstructor;
+
+import com.cloudbees.plugins.credentials.CredentialsScope;
+import com.cloudbees.plugins.credentials.impl.BaseStandardCredentials;
+
+/**
+ * Apple Worldwide Developer Relations Certification Authority, which consists of any number of
+ * certificate for prepare certificate for code signing, and mobile provisioning profiles.
+ *
+ * @author Kazuhide Takahashi
+ */
+public class AppleWWDRCA extends BaseStandardCredentials {
+ @DataBoundConstructor
+ public AppleWWDRCA(@CheckForNull CredentialsScope scope, @CheckForNull String id, @CheckForNull String description,
+ FileItem image) throws IOException {
+ super(scope, id, description);
+
+ if ( image != null ) {
+ // for added secrecy, store this in the confidential store
+ new ConfidentialKeyImpl(id).store(image);
+ }
+ }
+
+ /**
+ * Retrieves the AppleWWDRCA.cer file image.
+ * @return AppleWWDRCA.cer file image
+ * @throws IOException file I/O
+ */
+ public byte[] getImage() throws IOException {
+ return new ConfidentialKeyImpl(getId()).load();
+ }
+
+ /**
+ * Obtains the certificates in this AppleWWDRCA.cer file.
+ * @return X509Certificates
+ * @throws IOException file I/O
+ * @throws GeneralSecurityException Certificate error
+ */
+ public @Nonnull List getCertificates() throws IOException, GeneralSecurityException {
+ List r = new ArrayList<>();
+ try ( InputStream inputStream = new ByteArrayInputStream(getImage()) ) {
+ CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
+ Collection c = certificateFactory.generateCertificates(inputStream);
+ Iterator i = c.iterator();
+ while ( i.hasNext() ) {
+ X509Certificate cert = (X509Certificate) i.next();
+ r.add((X509Certificate)cert);
+ }
+ }
+ return r;
+ }
+
+ public String getDisplayNameOf(X509Certificate p) {
+ String name = p.getSubjectDN().getName();
+ try {
+ LdapName n = new LdapName(name);
+ for ( Rdn rdn : n.getRdns() ) {
+ if ( rdn.getType().equalsIgnoreCase("CN") )
+ return rdn.getValue().toString();
+ }
+ }
+ catch ( InvalidNameException e ) {
+ // fall through
+ }
+ return name; // fallback
+ }
+
+ @Extension
+ public static class DescriptorImpl extends BaseStandardCredentialsDescriptor {
+ @Override
+ public String getDisplayName() {
+ return "Apple Worldwide Developer Relations Certification Authority";
+ }
+ }
+
+ static class ConfidentialKeyImpl extends ConfidentialKey {
+ ConfidentialKeyImpl(String id) {
+ super(AppleWWDRCA.class.getName()+"."+id);
+ }
+
+ public void store(FileItem submitted) throws IOException {
+ super.store(IOUtils.toByteArray(submitted.getInputStream()));
+ }
+
+ public @CheckForNull byte[] load() throws IOException {
+ return super.load();
+ }
+ }
+
+ public static List getAllCertificates() {
+ return CredentialsProvider.lookupCredentials(AppleWWDRCA.class, (hudson.model.Item)null, ACL.SYSTEM, Collections.emptyList());
+ }
+}
diff --git a/src/main/java/au/com/rayh/DeveloperProfile.java b/src/main/java/au/com/rayh/DeveloperProfile.java
index 5c187c23..178060e4 100644
--- a/src/main/java/au/com/rayh/DeveloperProfile.java
+++ b/src/main/java/au/com/rayh/DeveloperProfile.java
@@ -4,7 +4,6 @@
import com.cloudbees.plugins.credentials.domains.DomainRequirement;
import hudson.Extension;
import hudson.security.ACL;
-import hudson.util.IOUtils;
import hudson.util.Secret;
import java.io.ByteArrayInputStream;
@@ -29,6 +28,7 @@
import jenkins.security.ConfidentialKey;
import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.io.IOUtils;
import org.kohsuke.stapler.DataBoundConstructor;
import com.cloudbees.plugins.credentials.CredentialsScope;
@@ -52,7 +52,7 @@ public DeveloperProfile(@CheckForNull CredentialsScope scope, @CheckForNull Stri
super(scope, id, description);
this.password = password;
- if (image!=null) {
+ if ( image != null ) {
// for added secrecy, store this in the confidential store
new ConfidentialKeyImpl(id).store(image);
}
@@ -60,7 +60,7 @@ public DeveloperProfile(@CheckForNull CredentialsScope scope, @CheckForNull Stri
@Deprecated
public DeveloperProfile(String id, String description, Secret password, FileItem image) throws IOException {
- this(CredentialsScope.GLOBAL,id,description,password,image);
+ this(CredentialsScope.GLOBAL, id, description, password, image);
}
public Secret getPassword() {
@@ -87,21 +87,20 @@ public byte[] getImage() throws IOException {
List r = new ArrayList<>();
ZipEntry ze;
- while ((ze = zip.getNextEntry()) != null) {
- if (ze.getName().endsWith(".p12")) {
+ while ( (ze = zip.getNextEntry()) != null ) {
+ if ( ze.getName().endsWith(".p12") ) {
KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(zip, password.getPlainText().toCharArray());
Enumeration en = ks.aliases();
- while (en.hasMoreElements()) {
+ while ( en.hasMoreElements() ) {
String s = en.nextElement();
Certificate c = ks.getCertificate(s);
- if (c instanceof X509Certificate) {
+ if ( c instanceof X509Certificate ) {
r.add((X509Certificate) c);
}
}
}
}
-
return r;
}
}
@@ -110,11 +109,12 @@ public String getDisplayNameOf(X509Certificate p) {
String name = p.getSubjectDN().getName();
try {
LdapName n = new LdapName(name);
- for (Rdn rdn : n.getRdns()) {
- if (rdn.getType().equalsIgnoreCase("CN"))
+ for ( Rdn rdn : n.getRdns() ) {
+ if ( rdn.getType().equalsIgnoreCase("CN") )
return rdn.getValue().toString();
}
- } catch (InvalidNameException e) {
+ }
+ catch ( InvalidNameException e ) {
// fall through
}
return name; // fallback
@@ -143,6 +143,6 @@ public void store(FileItem submitted) throws IOException {
}
public static List getAllProfiles() {
- return CredentialsProvider.lookupCredentials(DeveloperProfile.class, (hudson.model.Item)null, ACL.SYSTEM, Collections.emptyList());
+ return CredentialsProvider.lookupCredentials(DeveloperProfile.class, (hudson.model.Item)null, ACL.SYSTEM, Collections.emptyList());
}
}
diff --git a/src/main/java/au/com/rayh/DeveloperProfileLoader.java b/src/main/java/au/com/rayh/DeveloperProfileLoader.java
index d14bed30..be67474f 100644
--- a/src/main/java/au/com/rayh/DeveloperProfileLoader.java
+++ b/src/main/java/au/com/rayh/DeveloperProfileLoader.java
@@ -71,14 +71,17 @@ public class DeveloperProfileLoader extends Builder implements SimpleBuildStep {
private String keychainPath;
@CheckForNull
private Secret keychainPwd;
+ @CheckForNull
+ private String appleWWDRCACertId;
+
@CheckForNull
public String getProfileId() {
return profileId;
}
@DataBoundSetter
- public void setProfileId(String developerProfileId) {
- this.profileId = developerProfileId;
+ public void setProfileId(String profileId) {
+ this.profileId = profileId;
}
public Boolean getImportIntoExistingKeychain() {
@@ -132,6 +135,17 @@ public void setKeychainPwd(Secret keychainPwd) {
this.keychainPwd = keychainPwd;
}
+ /**
+ * @since 2.0.15
+ */
+ @CheckForNull
+ public String getAppleWWDRCACertId() { return appleWWDRCACertId; }
+
+ @DataBoundSetter
+ public void setAppleWWDRCACertId(String appleWWDRCACertId) {
+ this.appleWWDRCACertId = appleWWDRCACertId;
+ }
+
@DataBoundConstructor
public DeveloperProfileLoader() {
}
@@ -139,28 +153,29 @@ public DeveloperProfileLoader() {
@Deprecated
public DeveloperProfileLoader(String profileId) {
this();
- this.profileId = profileId;
+ this.profileId = profileId;
}
@Override
public void perform(@Nonnull Run, ?> run, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException {
- EnvVars envs = run.getEnvironment(listener);
- String _profileId = envs.expand(this.profileId);
+ EnvVars envs = run.getEnvironment(listener);
+ String _profileId = envs.expand(this.profileId);
String _keychainId = envs.expand(this.keychainId);
- String _keychainName = envs.expand(this.keychainName);
- Boolean _importIntoExistingKeychain = this.importIntoExistingKeychain;
+ String _keychainName = envs.expand(this.keychainName);
+ Boolean _importIntoExistingKeychain = this.importIntoExistingKeychain;
+ String _appleWWDRCACertId = envs.expand(this.appleWWDRCACertId);
DeveloperProfile dp = getProfile(run.getParent(), _profileId);
if ( dp == null )
throw new AbortException(Messages.DeveloperProfile_NoDeveloperProfileConfigured());
String _keychainPath;
String _keychainPwd;
- if ( BooleanUtils.isTrue(_importIntoExistingKeychain)) {
+ if ( BooleanUtils.isTrue(_importIntoExistingKeychain) ) {
if ( StringUtils.isNotEmpty(_keychainName) ) {
// for backward compatibility
listener.getLogger().println(Messages.XCodeBuilder_UseDeprecatedKeychainInfo());
Keychain keychain = getKeychain(_keychainName);
- if (keychain == null) {
+ if ( keychain == null ) {
throw new AbortException(Messages.DeveloperProfileLoader_NoKeychainInfoConfigured());
}
else {
@@ -193,16 +208,16 @@ else if ( StringUtils.isNotEmpty(_keychainId) ) {
else {
// Use temporary keychain with random UUID nasme.
_keychainPath = "jenkins-" + run.getParent().getFullName().replace('/', '-');
- _keychainPwd = UUID.randomUUID().toString();
- _importIntoExistingKeychain = Boolean.valueOf(false);
+ _keychainPwd = UUID.randomUUID().toString();
+ _importIntoExistingKeychain = Boolean.valueOf(false);
}
- // Note: keychain are usualy suffixed with .keychain. If we change we should probably clean up the ones we created
+ // Note: keychain are usually suffixed with .keychain. If we change we should probably clean up the ones we created
ArgumentListBuilder args;
if ( BooleanUtils.isNotTrue(_importIntoExistingKeychain) ) {
- // if the key chain is already present, delete it and start fresh
+ // if the key chain is already present, delete it and start fresh
ByteArrayOutputStream out = new ByteArrayOutputStream();
args = new ArgumentListBuilder("security", "delete-keychain", _keychainPath);
launcher.launch().cmds(args).stdout(out).join();
@@ -211,25 +226,25 @@ else if ( StringUtils.isNotEmpty(_keychainId) ) {
args.add("-p").addMasked(_keychainPwd);
args.add(_keychainPath);
invoke(launcher, listener, args, "Failed to create a keychain");
- }
+ }
args = new ArgumentListBuilder("security", "unlock-keychain");
args.add("-p").addMasked(_keychainPwd);
args.add(_keychainPath);
invoke(launcher, listener, args, "Failed to unlock keychain");
- if ( BooleanUtils.isNotTrue(_importIntoExistingKeychain) ) {
+ if ( BooleanUtils.isNotTrue(_importIntoExistingKeychain) ) {
args = new ArgumentListBuilder("security", "list-keychains");
- args.add("-d").add("user");
- args.add("-s").add("login.keychain");
+ args.add("-d").add("user");
+ args.add("-s").add("login.keychain");
args.add(_keychainPath);
invoke(launcher, listener, args, "Failed to set keychain search path");
- }
+ }
final FilePath secret = getSecretDir(workspace, _keychainPwd);
- final byte[] dpImage = dp.getImage();
- if ( dpImage == null )
- throw new AbortException(Messages.DeveloperProfile_NoDeveloperProfileConfigured());
+ final byte[] dpImage = dp.getImage();
+ if ( dpImage == null )
+ throw new AbortException(Messages.DeveloperProfile_NoDeveloperProfileConfigured());
secret.unzipFrom(new ByteArrayInputStream(dpImage));
// import identities
@@ -240,44 +255,44 @@ else if ( StringUtils.isNotEmpty(_keychainId) ) {
args.add("-T", "/usr/bin/codesign");
args.add("-T", "/usr/bin/productsign");
args.add(_keychainPath);
- invoke(launcher, listener, args, "Failed to import identity " + id);
+ invoke(launcher, listener, args, Messages.DeveloperProfileLoader_FailedToImportIdentity(id));
}
{
// display keychain info for potential troubleshooting
args = new ArgumentListBuilder("security", "show-keychain-info");
args.add(_keychainPath);
- ByteArrayOutputStream output = invoke(launcher, listener, args, "Failed to show keychain info");
+ ByteArrayOutputStream output = invoke(launcher, listener, args, Messages.DeveloperProfileLoader_FailedToShowKeychainInfo());
listener.getLogger().write(output.toByteArray());
}
- if ( BooleanUtils.isNotTrue(_importIntoExistingKeychain) ) {
+ if ( BooleanUtils.isNotTrue(_importIntoExistingKeychain) ) {
args = new ArgumentListBuilder("security", "set-key-partition-list");
args.add("-S").add("apple-tool:,apple:");
args.add("-s").add("-k").addMasked(_keychainPwd);
args.add(_keychainPath);
- invoke(launcher, listener, args, "Failed to set key partition list to keychain");
+ invoke(launcher, listener, args, Messages.DeveloperProfileLoader_FailedToSetKeyPartitionListToKeychain());
}
- {
- // If default keychain is not set, set the specified keychain to default keychain.
- args = new ArgumentListBuilder("security", "default-keychain");
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- if ( launcher.launch().cmds(args).stdout(output).join() != 0 ) {
- listener.getLogger().write(output.toByteArray());
- String strResult = new String(output.toByteArray(), "UTF-8");
- if ( strResult.contains("A default keychain could not be found.") ) {
- args = new ArgumentListBuilder("security", "default-keychain");
- args.add("-d").add("user");
- args.add("-s").add(_keychainPath);
- invoke(launcher, listener, args, "Failed to set default keychain");
- }
+ {
+ // If default keychain is not set, set the specified keychain to default keychain.
+ args = new ArgumentListBuilder("security", "default-keychain");
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ if ( launcher.launch().cmds(args).stdout(output).join() != 0 ) {
+ listener.getLogger().write(output.toByteArray());
+ String strResult = new String(output.toByteArray(), "UTF-8");
+ if ( strResult.contains("A default keychain could not be found.") ) {
+ args = new ArgumentListBuilder("security", "default-keychain");
+ args.add("-d").add("user");
+ args.add("-s").add(_keychainPath);
+ invoke(launcher, listener, args, Messages.DeveloperProfileLoader_FailedToSetDefaultKeychain());
+ }
+ }
}
- }
- if ( BooleanUtils.isNotTrue(_importIntoExistingKeychain) ) {
- importAppleCert(launcher, listener, workspace, _keychainPath);
- }
+ if ( BooleanUtils.isNotTrue(_importIntoExistingKeychain) ) {
+ importAppleCert(run.getParent(), launcher, listener, workspace, _keychainPath, secret, _appleWWDRCACertId);
+ }
// copy provisioning profiles
VirtualChannel ch = launcher.getChannel();
@@ -294,7 +309,6 @@ else if ( StringUtils.isNotEmpty(_keychainId) ) {
@Override
public boolean perform(AbstractBuild, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
perform(build, build.getWorkspace(), launcher, listener);
-
return true;
}
@@ -332,22 +346,41 @@ public KeychainPasswordAndPath getKeychainPasswordAndPath(Item context, String k
CredentialsMatchers.withId(keychainId));
}
- public void importAppleCert(Launcher launcher, TaskListener listener, FilePath workspace, String keychainPath) throws IOException, InterruptedException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- FilePath homeFolder = workspace.getHomeDirectory(workspace.getChannel());
- String homePath = homeFolder.getRemote();
- String cert = homePath + "/AppleWWDRCA.cer";
- launcher
- .launch()
- .cmds("security", "import", cert, "-k", keychainPath)
- .stdout(out)
- .join();
- listener.getLogger().write(out.toByteArray());
+ public void importAppleCert(Item context, Launcher launcher, TaskListener listener, FilePath workspace,
+ String keychainPath, FilePath secret, String appleWWDRCACertId) throws IOException, InterruptedException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ FilePath homeFolder = workspace.getHomeDirectory(workspace.getChannel());
+ String cert = null;
+ if ( !appleWWDRCACertId.isEmpty() ) {
+ AppleWWDRCA cr_cert = getAppleWWDRCA(context, appleWWDRCACertId);
+ if ( cr_cert == null ) {
+ listener.getLogger().println(Messages.DeveloperProfileLoader_AppleWWDRCAWasNotFoundInCredentials());
+ }
+ else {
+ listener.getLogger().println(Messages.DeveloperProfileLoader_ImportAppleWWDRCAFromCredentials());
+ secret.child("AppleWWDRCA.cer").write().write(cr_cert.getImage());
+ cert = secret.child("AppleWWDRCA.cer").getRemote();
+ }
+ }
+ else if ( homeFolder.child("AppleWWDRCA.cer").exists() ) {
+ listener.getLogger().println(Messages.DeveloperProfileLoader_ImportAppleWWDRCAFromLocalFilesystem());
+ cert = homeFolder.child("AppleWWDRCA.cer").getRemote();
+ }
+ else {
+ listener.getLogger().println(Messages.DeveloperProfileLoader_AppleWWDRCAWasNotFoundAnywhere());
+ return;
+ }
+ launcher
+ .launch()
+ .cmds("security", "import", cert, "-k", keychainPath)
+ .stdout(out)
+ .join();
+ listener.getLogger().write(out.toByteArray());
}
private ByteArrayOutputStream invoke(Launcher launcher, TaskListener listener, ArgumentListBuilder args, String errorMessage) throws IOException, InterruptedException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
- if (launcher.launch().cmds(args).stdout(output).join()!=0) {
+ if ( launcher.launch().cmds(args).stdout(output).join() != 0 ) {
listener.getLogger().write(output.toByteArray());
throw new AbortException(errorMessage);
}
@@ -368,16 +401,23 @@ public DeveloperProfile getProfile(Item context, String profileId) {
CredentialsMatchers.withId(profileId));
}
+ public AppleWWDRCA getAppleWWDRCA(Item context, String appleWWDRCACertId) {
+ return (AppleWWDRCA)CredentialsMatchers.firstOrNull(
+ CredentialsProvider.lookupCredentials(AppleWWDRCA.class, context,
+ ACL.SYSTEM, Collections.EMPTY_LIST),
+ CredentialsMatchers.withId(appleWWDRCACertId));
+ }
+
@Extension
@Symbol("importDeveloperProfile")
public static class DescriptorImpl extends BuildStepDescriptor {
- GlobalConfigurationImpl globalConfiguration;
+ GlobalConfigurationImpl globalConfiguration;
@SuppressFBWarnings("UWF_UNWRITTEN_FIELD")
@Inject
void setGlobalConfiguration(GlobalConfigurationImpl c) {
this.globalConfiguration = c;
- }
+ }
@Override
public boolean isApplicable(Class extends AbstractProject> jobType) {
@@ -393,7 +433,7 @@ public ListBoxModel doFillProfileIdItems(@AncestorInPath Item context) {
List profiles = CredentialsProvider
.lookupCredentials(DeveloperProfile.class, context, null);
ListBoxModel r = new ListBoxModel();
- for (DeveloperProfile p : profiles) {
+ for ( DeveloperProfile p : profiles ) {
r.add(p.getDescription(), p.getId());
}
return r;
@@ -414,18 +454,18 @@ public FormValidation doCheckDeveloperProfileId(@QueryParameter String value) {
return FormValidation.ok();
}
- public FormValidation doCheckKeychainPath(@QueryParameter String value, @QueryParameter String keychainName, @QueryParameter Boolean importIntoExistingKeychain) {
+ public FormValidation doCheckKeychainPath(@QueryParameter String value, @QueryParameter String keychainId, @QueryParameter Boolean importIntoExistingKeychain) {
if ( BooleanUtils.isTrue(importIntoExistingKeychain) ) {
- if ( StringUtils.isEmpty(keychainName) && StringUtils.isEmpty(value) ) {
+ if ( StringUtils.isEmpty(keychainId) && StringUtils.isEmpty(value) ) {
return FormValidation.error(Messages.DeveloperProfileLoader_MustSpecifyKeychainPath());
}
}
return FormValidation.ok();
}
- public FormValidation doCheckKeychainPwd(@QueryParameter Secret value, @QueryParameter String keychainName, @QueryParameter Boolean importIntoExistingKeychain) {
+ public FormValidation doCheckKeychainPwd(@QueryParameter Secret value, @QueryParameter String keychainId, @QueryParameter Boolean importIntoExistingKeychain) {
if ( BooleanUtils.isTrue(importIntoExistingKeychain) ) {
- if ( StringUtils.isEmpty(keychainName) && StringUtils.isEmpty(Secret.toString(value)) ) {
+ if ( StringUtils.isEmpty(keychainId) && StringUtils.isEmpty(Secret.toString(value)) ) {
return FormValidation.error(Messages.DeveloperProfileLoader_MustSpecifyKeychainPwd());
}
}
diff --git a/src/main/resources/au/com/rayh/AppleWWDRCA/config.groovy b/src/main/resources/au/com/rayh/AppleWWDRCA/config.groovy
new file mode 100644
index 00000000..d9940789
--- /dev/null
+++ b/src/main/resources/au/com/rayh/AppleWWDRCA/config.groovy
@@ -0,0 +1,53 @@
+package au.com.rayh.AppleWWDRCA
+
+import java.security.GeneralSecurityException
+import java.security.cert.CertificateException
+
+f = namespace(lib.FormTagLib)
+st = namespace("jelly:stapler")
+
+def fileForm() {
+ f.entry(title:_("*.cer File"), field:"image") {
+ raw("")
+ }
+}
+
+def img = instance?.image
+if ( img == null ) {
+ fileForm()
+}
+else {
+ f.entry(title:_("Contents")) { // show the certificates in the .cer file
+ try {
+ def certs = instance.certificates
+ certs.each { c ->
+ boolean valid = true;
+ try {
+ c.checkValidity();
+ }
+ catch ( CertificateException e ) {
+ valid = false;
+ }
+
+ div(class:valid ? null : 'error') {
+ text(instance.getDisplayNameOf(c))
+ if ( !valid )
+ text(_("expired"));
+ }
+ }
+ if ( certs.isEmpty() )
+ div(class:'error', _("There's no certificate in this .cer file"));
+ }
+ catch ( IOException e ) {
+ div(class:'error', _("Not a valid certificates file:") + "${e.message}")
+ }
+ catch ( GeneralSecurityException e ) {
+ div(class:'error', _("Not a valid certificates file:") + "${e.message}")
+ }
+ }
+ f.optionalBlock( title:_("Re-upload *.cer File"), inline:true ) {
+ fileForm()
+ }
+}
+
+st.include(page:"id-and-description", class:descriptor.clazz)
diff --git a/src/main/resources/au/com/rayh/AppleWWDRCA/config_ja.properties b/src/main/resources/au/com/rayh/AppleWWDRCA/config_ja.properties
new file mode 100644
index 00000000..aacc752a
--- /dev/null
+++ b/src/main/resources/au/com/rayh/AppleWWDRCA/config_ja.properties
@@ -0,0 +1,6 @@
+*.cer\ File=*.cer \u30D5\u30A1\u30A4\u30EB
+Contents=\u5185\u5BB9
+Re-upload\ *.cer\ File=*.cer \u30D5\u30A1\u30A4\u30EB\u3092\u518D\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9
+There's\ no\ certificate\ in\ this\ .cer\ file=\u8A3C\u660E\u66F8\u30D5\u30A1\u30A4\u30EB(.crt)\u306B\u306F\u8A3C\u660E\u66F8\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u305B\u3093
+Not\ a\ valid\ certificates\ file:=\u6B63\u3057\u3044\u8A3C\u660E\u66F8\u30D5\u30A1\u30A4\u30EB\u3067\u306F\u3042\u308A\u307E\u305B\u3093:
+expired=\u671F\u9650\u5207\u308C
diff --git a/src/main/resources/au/com/rayh/AppleWWDRCA/help-description.html b/src/main/resources/au/com/rayh/AppleWWDRCA/help-description.html
new file mode 100644
index 00000000..e34037b2
--- /dev/null
+++ b/src/main/resources/au/com/rayh/AppleWWDRCA/help-description.html
@@ -0,0 +1,5 @@
+
+ Any one-liner text to help you remember what this certificate is
+ among other certificates. Jenkins will use this text when it wants
+ you to select a certificate.
+
\ No newline at end of file
diff --git a/src/main/resources/au/com/rayh/AppleWWDRCA/help-description_ja.html b/src/main/resources/au/com/rayh/AppleWWDRCA/help-description_ja.html
new file mode 100644
index 00000000..3b60cb18
--- /dev/null
+++ b/src/main/resources/au/com/rayh/AppleWWDRCA/help-description_ja.html
@@ -0,0 +1,4 @@
+
diff --git a/src/main/resources/au/com/rayh/AppleWWDRCA/help-id.html b/src/main/resources/au/com/rayh/AppleWWDRCA/help-id.html
new file mode 100644
index 00000000..6974dc6b
--- /dev/null
+++ b/src/main/resources/au/com/rayh/AppleWWDRCA/help-id.html
@@ -0,0 +1,5 @@
+
+ An internal unique ID by which these credentials are identified from jobs and other configuration.
+ Normally left blank, in which case an ID will be generated, which is fine for jobs created using visual forms.
+ Useful to specify explicitly when using credentials from scripted configuration.
+
diff --git a/src/main/resources/au/com/rayh/AppleWWDRCA/help-id_ja.html b/src/main/resources/au/com/rayh/AppleWWDRCA/help-id_ja.html
new file mode 100644
index 00000000..5cb7aa81
--- /dev/null
+++ b/src/main/resources/au/com/rayh/AppleWWDRCA/help-id_ja.html
@@ -0,0 +1,6 @@
+
diff --git a/src/main/resources/au/com/rayh/AppleWWDRCA/help.html b/src/main/resources/au/com/rayh/AppleWWDRCA/help.html
new file mode 100644
index 00000000..b3b12abc
--- /dev/null
+++ b/src/main/resources/au/com/rayh/AppleWWDRCA/help.html
@@ -0,0 +1,5 @@
+
+ Register your Apple Worldwide Devceloper Relations intermediate certificate with your Jenkins credentials,
+ which is required to sign your app with the certificate included in your developer profile.
+ Generally, if you're importing a developer profile into a standard macOS keychain, this step isn't necessary.
+
diff --git a/src/main/resources/au/com/rayh/AppleWWDRCA/help_ja.html b/src/main/resources/au/com/rayh/AppleWWDRCA/help_ja.html
new file mode 100644
index 00000000..a4c00de3
--- /dev/null
+++ b/src/main/resources/au/com/rayh/AppleWWDRCA/help_ja.html
@@ -0,0 +1,4 @@
+