fastlane-plugin-ciutils 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +62 -0
- data/lib/fastlane/plugin/ciutils/actions/en_build_number.rb +30 -0
- data/lib/fastlane/plugin/ciutils/actions/en_ci_utils_init_action.rb +65 -0
- data/lib/fastlane/plugin/ciutils/actions/en_close_simulator.rb +25 -0
- data/lib/fastlane/plugin/ciutils/actions/en_git_changelog.rb +64 -0
- data/lib/fastlane/plugin/ciutils/actions/en_install_provisioning_profiles.rb +27 -0
- data/lib/fastlane/plugin/ciutils/actions/en_profile_name.rb +59 -0
- data/lib/fastlane/plugin/ciutils/actions/en_remove_keychain.rb +32 -0
- data/lib/fastlane/plugin/ciutils/actions/en_setup_keychain.rb +99 -0
- data/lib/fastlane/plugin/ciutils/actions/en_setup_project.rb +136 -0
- data/lib/fastlane/plugin/ciutils/helper/ciutils_helper.rb +31 -0
- data/lib/fastlane/plugin/ciutils/version.rb +5 -0
- data/lib/fastlane/plugin/ciutils.rb +16 -0
- metadata +197 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 129a95d51b3aad1d32a14f1a19c8d113a7d399c5
|
4
|
+
data.tar.gz: 0c31216415d0084b7423982c088cdc5509d9a70d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9133b114e21bc602d6b3494674701161440a0591f4b080472e67f2d8dd86e640e6b2e4eb379d4bf87cb44f0e120c6a412cc31f1f4b2ff082368f39935042cab8
|
7
|
+
data.tar.gz: b9f4e9c1519de1b2b984c8e29dd448154873e516c23e1271483dd24bb5e9fb6b4c8dcb5478b2c3ae5a6175fd07f92d2b121703abb8c8f21271233608cca0898f
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Nicolae Ghimbovschi <xfreebird@gmail.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# ciutils plugin
|
2
|
+
|
3
|
+
[](https://rubygems.org/gems/fastlane-plugin-ciutils)
|
4
|
+
|
5
|
+
## Getting Started
|
6
|
+
|
7
|
+
This project is a [fastlane](https://github.com/fastlane/fastlane) plugin. To get started with `fastlane-plugin-ciutils`, add it to your project by running:
|
8
|
+
|
9
|
+
```bash
|
10
|
+
bundle exec fastlane add_plugin ciutils
|
11
|
+
```
|
12
|
+
|
13
|
+
## About ciutils
|
14
|
+
|
15
|
+
Various utilities for CI and Xcode project configuration.
|
16
|
+
|
17
|
+
action |description
|
18
|
+
-------------------------|-------
|
19
|
+
`en_ci_utils_init` | Initializes several environment variables: <br>**gym**<br>`GYM_OUTPUT_DIRECTORY`=**`build`**<br> `GYM_BUILDLOG_PATH`=**`build/logs/gym`** <br><br>**scan**<br>`SCAN_OUTPUT_DIRECTORY`=**`build/reports/unittests`**<br>`SCAN_BUILDLOG_PATH`=**`build/logs/scan/`**<br>`SCAN_DERIVED_DATA_PATH`=**`build/deriveddata`** <br>`SCAN_OUTPUT_TYPES`=**`html,junit,json-compilation-database`**<br><br>**slather**<br>`FL_SLATHER_BUILD_DIRECTORY`=**`build/deriveddata`**<br>`FL_SLATHER_USE_BUNDLE_EXEC`=**`true`**<br>`FL_SLATHER_OUTPUT_DIRECTORY`=**`build/reports/`**<br> `FL_SLATHER_COBERTURA_XML_ENABLED`=**`true`**<br><br>**build number**<br>`BUILD_NUMBER` and `FL_BUILD_NUMBER_BUILD_NUMBER` are initialized with the current build number regardless of CI environment. When run on desktop, it us always `1`<br><br>
|
20
|
+
`en_profile_name` | Returns the provisioning profile name by path or uuid
|
21
|
+
`en_build_number` | Returns the value of current build number regardless of CI environment. If run on desktop, then is always `1`
|
22
|
+
`en_setup_keychain` | Creates a keychain and imports the provided certificate
|
23
|
+
`en_remove_keychain` | Removes the keychain created by ```en_setup_keychain``` and restores the default keychain
|
24
|
+
`en_git_changelog` | Creates the changelog based on git commits by filtering commit messages by a keyword
|
25
|
+
`en_close_simulator` | Quits the simulator
|
26
|
+
`en_install_provisioning_profiles` | Copies all provisioning profiles from project folder to `~/Library/MobileDevice/Provisioning Profiles`
|
27
|
+
`en_setup_project` | Updates Xcode projects, Info.plist, Entitlements file and any other plist file using values from the provided yaml file.
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
## Example
|
32
|
+
|
33
|
+
Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin. Try it by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane test`.
|
34
|
+
|
35
|
+
## Run tests for this plugin
|
36
|
+
|
37
|
+
To run both the tests, and code style validation, run
|
38
|
+
|
39
|
+
```
|
40
|
+
rake
|
41
|
+
```
|
42
|
+
|
43
|
+
To automatically fix many of the styling issues, use
|
44
|
+
```
|
45
|
+
rubocop -a
|
46
|
+
```
|
47
|
+
|
48
|
+
## Issues and Feedback
|
49
|
+
|
50
|
+
For any other issues and feedback about this plugin, please submit it to this repository.
|
51
|
+
|
52
|
+
## Troubleshooting
|
53
|
+
|
54
|
+
If you have trouble using plugins, check out the [Plugins Troubleshooting](https://github.com/fastlane/fastlane/blob/master/fastlane/docs/PluginsTroubleshooting.md) doc in the main `fastlane` repo.
|
55
|
+
|
56
|
+
## Using `fastlane` Plugins
|
57
|
+
|
58
|
+
For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Plugins.md).
|
59
|
+
|
60
|
+
## About `fastlane`
|
61
|
+
|
62
|
+
`fastlane` is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class EnBuildNumberAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
return Helper::CiutilsHelper.en_ci_build_number()
|
6
|
+
end
|
7
|
+
|
8
|
+
#####################################################
|
9
|
+
# @!group Documentation
|
10
|
+
#####################################################
|
11
|
+
|
12
|
+
def self.description
|
13
|
+
"Get the value for build number from environment"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.return_value
|
17
|
+
"Returns the value of env BUILD_NUMBER, else returns 1. Value is string"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.authors
|
21
|
+
# So no one will ever forget your contribution to fastlane :) You are awesome btw!
|
22
|
+
["Nicolae Ghimbovschi"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.is_supported?(platform)
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class EnCiUtilsInitAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
# gym evn variables
|
6
|
+
ENV['GYM_OUTPUT_DIRECTORY'] = "build"
|
7
|
+
ENV['GYM_BUILDLOG_PATH'] = "build/logs/gym"
|
8
|
+
|
9
|
+
# scan env variables
|
10
|
+
ENV['SCAN_OUTPUT_DIRECTORY'] = "build/reports/unittests"
|
11
|
+
ENV['SCAN_BUILDLOG_PATH'] = "build/logs/scan/"
|
12
|
+
ENV['SCAN_DERIVED_DATA_PATH'] = "build/deriveddata"
|
13
|
+
ENV['SCAN_OUTPUT_TYPES'] = "html,junit,json-compilation-database"
|
14
|
+
|
15
|
+
ENV['FL_SLATHER_BUILD_DIRECTORY'] = "build/deriveddata"
|
16
|
+
ENV['FL_SLATHER_OUTPUT_DIRECTORY'] = "build/reports"
|
17
|
+
ENV['FL_SLATHER_COBERTURA_XML_ENABLED'] = "true"
|
18
|
+
ENV['FL_SLATHER_USE_BUNDLE_EXEC'] = "true"
|
19
|
+
ENV['FL_SLATHER_HTML_ENABLED'] = "false"
|
20
|
+
|
21
|
+
# swiftlint
|
22
|
+
ENV['FL_SWIFTLINT_OUTPUT'] = "./build/reports/swiftlint.txt"
|
23
|
+
|
24
|
+
# lizard
|
25
|
+
ENV['FL_LIZARD_OUTPUT'] = "../build/reports/lizard-report.xml"
|
26
|
+
|
27
|
+
ENV['BUILD_NUMBER'] = Helper::CiutilsHelper.en_ci_build_number()
|
28
|
+
ENV['FL_BUILD_NUMBER_BUILD_NUMBER'] = ENV['BUILD_NUMBER']
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.description
|
32
|
+
"Sets env variables for gym, scan, swiftlint and lizard actions"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.authors
|
36
|
+
["Nicolae Ghimbovschi"]
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.details
|
40
|
+
"Call this action to pre-set gym, scan, swiftlint and lizard to use the build folder for intermediate files and reports"
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.is_supported?(platform)
|
44
|
+
true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
class CiutilsAction < EnCiUtilsInitAction
|
48
|
+
def self.description
|
49
|
+
"Sets env variables for gym, scan, swiftlint and lizard actions"
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.authors
|
53
|
+
["Nicolae Ghimbovschi"]
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.details
|
57
|
+
"Call this action to pre-set gym, scan, swiftlint and lizard to use the build folder for intermediate files and reports"
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.is_supported?(platform)
|
61
|
+
true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class EnCloseSimulatorAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
Fastlane::Actions.sh("osascript -e 'tell app \"Simulator\" to quit'", log: false)
|
6
|
+
end
|
7
|
+
|
8
|
+
#####################################################
|
9
|
+
# @!group Documentation
|
10
|
+
#####################################################
|
11
|
+
|
12
|
+
def self.description
|
13
|
+
"Closes all simulator instances"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.authors
|
17
|
+
["Nicolae Ghimbovschi"]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.is_supported?(platform)
|
21
|
+
platform == :ios
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class EnGitChangelogAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
from_commit = params[:from_commit]
|
6
|
+
to_commit = params[:to_commit]
|
7
|
+
filter = params[:filter]
|
8
|
+
|
9
|
+
change_log = self.git_log_between(from_commit, to_commit, filter)
|
10
|
+
self.inject_env_with_changelog(change_log)
|
11
|
+
change_log
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.git_log_between(from_commit, to_commit, filter)
|
15
|
+
change_log = `git log #{from_commit}...#{to_commit} --no-merges | grep #{filter} | sed -e 's/^[[:space:]]*//' | sed 's/\\[//'| sed 's/\\]//' | sort -r -u`
|
16
|
+
change_log
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.inject_env_with_changelog(change_log)
|
20
|
+
ENV['EN_CHANGELOG'] = change_log
|
21
|
+
ENV['FL_HOCKEY_NOTES'] = change_log
|
22
|
+
ENV['PILOT_CHANGELOG'] = change_log
|
23
|
+
ENV['CRASHLYTICS_NOTES'] = change_log
|
24
|
+
end
|
25
|
+
|
26
|
+
#####################################################
|
27
|
+
# @!group Documentation
|
28
|
+
#####################################################
|
29
|
+
|
30
|
+
def self.description
|
31
|
+
"Creates a change log from git commits by filtering commits by a pattern (e.g. JIRA task prefix)"
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.details
|
35
|
+
"You can use this action to do create a git changelog with tasks id.
|
36
|
+
It also sets the result to EN_CHANGELOG, FL_HOCKEY_NOTES, PILOT_CHANGELOG and CRASHLYTICS_NOTES"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.available_options
|
40
|
+
[
|
41
|
+
FastlaneCore::ConfigItem.new(key: :from_commit,
|
42
|
+
env_name: "FL_EN_GIT_FROM_COMMIT",
|
43
|
+
description: "Commit from where to start the log. Default value is ENV['GIT_PREVIOUS_SUCCESSFUL_COMMIT']",
|
44
|
+
default_value: ENV['GIT_PREVIOUS_SUCCESSFUL_COMMIT']),
|
45
|
+
FastlaneCore::ConfigItem.new(key: :to_commit,
|
46
|
+
env_name: "FL_EN_GIT_TO_COMMIT",
|
47
|
+
description: "The last commit included in the log. Default value is ENV['GIT_COMMIT']",
|
48
|
+
default_value: ENV['GIT_COMMIT']),
|
49
|
+
FastlaneCore::ConfigItem.new(key: :filter,
|
50
|
+
env_name: "FL_EN_TASK_PREFIX_FILTER",
|
51
|
+
description: "The prefix/string to look in the commit message (e.g. JIRA task prefix)")
|
52
|
+
]
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.authors
|
56
|
+
["Nicolae Ghimbovschi"]
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.is_supported?(platform)
|
60
|
+
true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class EnInstallProvisioningProfilesAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
profiles_dir = "#{Dir.home}/Library/MobileDevice/Provisioning Profiles"
|
6
|
+
source = Dir.glob("**/*.mobileprovision")
|
7
|
+
|
8
|
+
# Remove all profiles
|
9
|
+
FileUtils.rm_rf Dir.glob("#{profiles_dir}/*")
|
10
|
+
# Copy new profiles
|
11
|
+
FileUtils.cp_r source, "#{profiles_dir}", remove_destination: true
|
12
|
+
end
|
13
|
+
|
14
|
+
#####################################################
|
15
|
+
# @!group Documentation
|
16
|
+
#####################################################
|
17
|
+
|
18
|
+
def self.description
|
19
|
+
"Copies recursively all provisioning profiles from current folder to system Provisioning Profiles"
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.is_supported?(platform)
|
23
|
+
platform == :ios
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class EnProfileNameAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
file_path = params[:path]
|
6
|
+
profile_name = ""
|
7
|
+
|
8
|
+
unless file_path
|
9
|
+
file_uuid = params[:uuid]
|
10
|
+
file_path = "~/Library/MobileDevice/Provisioning Profiles/#{file_uuid}.mobileprovision"
|
11
|
+
file_path = File.expand_path(file_path)
|
12
|
+
end
|
13
|
+
|
14
|
+
if File.exist?(file_path)
|
15
|
+
profile_xml_data = Fastlane::Actions.sh "security cms -D -i '#{file_path}'", log: false
|
16
|
+
profile_data = Plist.parse_xml(profile_xml_data)
|
17
|
+
profile_name = profile_data['Name']
|
18
|
+
else
|
19
|
+
UI.user_error! "Could not find the specified profile at path '#{file_path}'"
|
20
|
+
end
|
21
|
+
|
22
|
+
profile_name
|
23
|
+
end
|
24
|
+
|
25
|
+
#####################################################
|
26
|
+
# @!group Documentation
|
27
|
+
#####################################################
|
28
|
+
|
29
|
+
def self.description
|
30
|
+
"A short description with <= 80 characters of what this action does"
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.available_options
|
34
|
+
[
|
35
|
+
FastlaneCore::ConfigItem.new(key: :path,
|
36
|
+
env_name: "FL_EN_PROFILE_PATH",
|
37
|
+
description: "Path to the provisioning profile",
|
38
|
+
optional: true),
|
39
|
+
FastlaneCore::ConfigItem.new(key: :uuid,
|
40
|
+
env_name: "FL_EN_PROFILE_UUID",
|
41
|
+
description: "The UUID of the provisioning profile from 'Provisioning Profiles' folder",
|
42
|
+
optional: true)
|
43
|
+
]
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.return_value
|
47
|
+
"Provisioning profile name"
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.authors
|
51
|
+
["Nicolae Ghimbovschi"]
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.is_supported?(platform)
|
55
|
+
platform == :ios
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
module SharedValues
|
4
|
+
end
|
5
|
+
|
6
|
+
class EnRemoveKeychainAction < Action
|
7
|
+
def self.run(params)
|
8
|
+
begin
|
9
|
+
keychain_name = Actions.lane_context[SharedValues::EN_KEYCHAIN_NAME]
|
10
|
+
other_action.delete_keychain(name: keychain_name)
|
11
|
+
rescue
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
#####################################################
|
16
|
+
# @!group Documentation
|
17
|
+
#####################################################
|
18
|
+
|
19
|
+
def self.description
|
20
|
+
"Removes the keychain setup by en_setup_keychain"
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.authors
|
24
|
+
["Nicolae Ghimbovschi"]
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.is_supported?(platform)
|
28
|
+
true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
module SharedValues
|
4
|
+
EN_KEYCHAIN_NAME = :EN_KEYCHAIN_NAME
|
5
|
+
end
|
6
|
+
|
7
|
+
class EnSetupKeychainAction < Action
|
8
|
+
def self.run(params)
|
9
|
+
keychain_name = params[:name]
|
10
|
+
keychain_password = "password"
|
11
|
+
|
12
|
+
self.remove_keychain_if_exists(keychain_name)
|
13
|
+
|
14
|
+
other_action.create_keychain(
|
15
|
+
name: keychain_name,
|
16
|
+
default_keychain: false,
|
17
|
+
unlock: true,
|
18
|
+
timeout: 9600,
|
19
|
+
lock_when_sleeps: false,
|
20
|
+
password: keychain_password
|
21
|
+
)
|
22
|
+
|
23
|
+
# set shared var
|
24
|
+
current_keychain_name = Helper::CiutilsHelper.en_keychain_name(keychain_name)
|
25
|
+
Actions.lane_context[SharedValues::EN_KEYCHAIN_NAME] = current_keychain_name
|
26
|
+
ENV['MATCH_KEYCHAIN_NAME'] = keychain_name
|
27
|
+
ENV['MATCH_KEYCHAIN_PASSWORD'] = keychain_password
|
28
|
+
|
29
|
+
cert_path = params[:certp12_path]
|
30
|
+
unless File.exist?(cert_path)
|
31
|
+
UI.message("Skipping keychain certificate import. File doesn't exist.")
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
35
|
+
other_action.import_certificate(
|
36
|
+
keychain_name: current_keychain_name,
|
37
|
+
keychain_password: keychain_password,
|
38
|
+
certificate_path: cert_path,
|
39
|
+
certificate_password: params[:certp12_password]
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.remove_keychain_if_exists(keychain_name)
|
44
|
+
begin
|
45
|
+
other_action.delete_keychain(name: keychain_name)
|
46
|
+
rescue
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
#####################################################
|
51
|
+
# @!group Documentation
|
52
|
+
#####################################################
|
53
|
+
|
54
|
+
def self.description
|
55
|
+
"Creates the keychain, and imports the provided certificate"
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.details
|
59
|
+
"The default value for the keychain name is 'fastlane'.
|
60
|
+
It removes the keychain if exists.
|
61
|
+
The certificate path should be relative to fastlane folder or full path"
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.available_options
|
65
|
+
[
|
66
|
+
FastlaneCore::ConfigItem.new(key: :name,
|
67
|
+
env_name: "EN_KEYCHAIN_NAME",
|
68
|
+
description: "Keychain name",
|
69
|
+
is_string: true, # true: verifies the input is a string, false: every kind of value
|
70
|
+
default_value: "fastlane"), # the default value if the user didn't provide one
|
71
|
+
FastlaneCore::ConfigItem.new(key: :certp12_path,
|
72
|
+
env_name: "EN_CERTP12_PATH",
|
73
|
+
description: "Certificate to import",
|
74
|
+
is_string: true, # true: verifies the input is a string, false: every kind of value
|
75
|
+
default_value: "cert.p12"), # the default value if the user didn't provide one
|
76
|
+
FastlaneCore::ConfigItem.new(key: :certp12_password,
|
77
|
+
env_name: "EN_CERTP12_PASSWORD",
|
78
|
+
description: "Password of the Certificate to import. Should be relative to the fastlane folder, or full path",
|
79
|
+
is_string: true, # true: verifies the input is a string, false: every kind of value
|
80
|
+
default_value: "password") # the default value if the user didn't provide one
|
81
|
+
]
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.output
|
85
|
+
[
|
86
|
+
['EN_KEYCHAIN_NAME', 'The name of the created keychain']
|
87
|
+
]
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.authors
|
91
|
+
["Nicolae Ghimbovschi"]
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.is_supported?(platform)
|
95
|
+
true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
module ResourceType
|
4
|
+
XcodeProject = 1
|
5
|
+
InfoPlist = 2
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'yaml'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'xcodeproj'
|
11
|
+
require 'plist'
|
12
|
+
|
13
|
+
class EnSetupProjectAction < Action
|
14
|
+
def self.run(params)
|
15
|
+
config_file = params[:config]
|
16
|
+
|
17
|
+
unless File.exist?(config_file)
|
18
|
+
UI.user_error!("Could not find #{config_file}! Aborting!")
|
19
|
+
return
|
20
|
+
end
|
21
|
+
|
22
|
+
configurations = YAML.load_file(config_file)
|
23
|
+
configurations.each do |file_path, settings|
|
24
|
+
file_type = self.file_type(file_path)
|
25
|
+
|
26
|
+
if file_type == ResourceType::XcodeProject
|
27
|
+
self.updateXcodeProject(file_path, settings)
|
28
|
+
elsif file_type == ResourceType::InfoPlist
|
29
|
+
self.updatePlistFile(file_path, settings)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.updateXcodeProject(project_path, settings)
|
35
|
+
project = Xcodeproj::Project.open(project_path)
|
36
|
+
|
37
|
+
common_configurations = settings['common']
|
38
|
+
|
39
|
+
project.targets.each do |target|
|
40
|
+
target_configurations = settings['targets'][target.name]
|
41
|
+
target_configurations = {} if target_configurations == nil
|
42
|
+
target_configurations.merge!(common_configurations) unless common_configurations == nil
|
43
|
+
|
44
|
+
target.build_configurations.each do |config|
|
45
|
+
|
46
|
+
target_configurations.each do |key, value|
|
47
|
+
value = "iPhone Distribution" if value == "iOS Distribution"
|
48
|
+
config.build_settings[key] = value
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
project.save
|
53
|
+
|
54
|
+
UI.message("#{project_path} has been updated")
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.updatePlistFile(file_path, settings)
|
58
|
+
plist = {}
|
59
|
+
plist = Plist.parse_xml(file_path) if File.exist?(file_path)
|
60
|
+
plist.merge!(settings)
|
61
|
+
|
62
|
+
settings.each do |key, value|
|
63
|
+
plist.delete(key) if value == nil
|
64
|
+
end
|
65
|
+
|
66
|
+
File.open(file_path, 'w') do |file|
|
67
|
+
file.write(plist.to_plist)
|
68
|
+
end
|
69
|
+
|
70
|
+
UI.message("#{file_path} has been updated")
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.file_type(file_path)
|
74
|
+
return ResourceType::XcodeProject if file_path.end_with? ".xcodeproj"
|
75
|
+
return ResourceType::InfoPlist if file_path.end_with? ".plist"
|
76
|
+
return ResourceType::InfoPlist if file_path.end_with? ".entitlements"
|
77
|
+
end
|
78
|
+
|
79
|
+
#####################################################
|
80
|
+
# @!group Documentation
|
81
|
+
#####################################################
|
82
|
+
|
83
|
+
def self.description
|
84
|
+
"Updates Xcode project, plist and entitlements file if config file is provided"
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.details
|
88
|
+
"Updates Xcode project, plist and entitlements file if config file is provided.
|
89
|
+
|
90
|
+
Example a project with two targets info.plist and entitlements.
|
91
|
+
|
92
|
+
TestMatch.xcodeproj:
|
93
|
+
options:
|
94
|
+
CODE_SIGN_IDENTITY: iOS Distribution
|
95
|
+
DEVELOPMENT_TEAM: H86U5Z8HYB
|
96
|
+
CODE_SIGN_STYLE: Manual
|
97
|
+
BUNDLE_ID: com.ghimbovschi.FastlaneDemo
|
98
|
+
targets:
|
99
|
+
TestMatch:
|
100
|
+
PRODUCT_BUNDLE_IDENTIFIER: ${BUNDLE_ID}
|
101
|
+
PROVISIONING_PROFILE_SPECIFIER: match AppStore $(PRODUCT_BUNDLE_IDENTIFIER)
|
102
|
+
|
103
|
+
keyboard:
|
104
|
+
PRODUCT_BUNDLE_IDENTIFIER: ${BUNDLE_ID}.keyboard
|
105
|
+
PROVISIONING_PROFILE_SPECIFIER: match AppStore $(PRODUCT_BUNDLE_IDENTIFIER)
|
106
|
+
|
107
|
+
TestMatch/Info.plist:
|
108
|
+
CFBundleDisplayName: My App
|
109
|
+
|
110
|
+
TestMatch/TestMatch.entitlements:
|
111
|
+
com.apple.security.application-groups:
|
112
|
+
|
113
|
+
|
114
|
+
The config file path should be relative to fastlane folder or full path"
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.available_options
|
118
|
+
[
|
119
|
+
FastlaneCore::ConfigItem.new(key: :config,
|
120
|
+
env_name: "EN_SETUP_PROJECT_CONFIG",
|
121
|
+
description: "Config file path, default it tries to load config.yaml",
|
122
|
+
is_string: true,
|
123
|
+
default_value: "config.yaml")
|
124
|
+
]
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.authors
|
128
|
+
["Nicolae Ghimbovschi"]
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.is_supported?(platform)
|
132
|
+
true
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Helper
|
3
|
+
class CiutilsHelper
|
4
|
+
# class methods that you define here become available in your action
|
5
|
+
# as `Helper::CiutilsHelper.en_keychain_name`
|
6
|
+
#
|
7
|
+
def self.en_keychain_name(keychain_name)
|
8
|
+
keychain_new_name = File.expand_path("~/Library/Keychains/#{keychain_name}")
|
9
|
+
|
10
|
+
["", ".keychain", ".keychain-db", "-db"].each do |ext|
|
11
|
+
file_path = "#{keychain_new_name}#{ext}"
|
12
|
+
if File.exist?(file_path)
|
13
|
+
return "#{keychain_name}#{ext}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
""
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.en_ci_build_number()
|
21
|
+
['BUILD_NUMBER', 'CIRCLE_BUILD_NUM', 'APPCENTER_BUILD_ID', 'TEAMCITY_VERSION',
|
22
|
+
'GO_PIPELINE_NAME', 'bamboo_buildNumber', 'CI_BUILD_ID', 'CI_JOB_ID',
|
23
|
+
'XCS_INTEGRATION_NUMBER', 'BITBUCKET_BUILD_NUMBER', 'BUDDYBUILD_BUILD_NUMBER',
|
24
|
+
'TRAVIS_BUILD_NUMBER'].each do |current|
|
25
|
+
return ENV[current] if ENV.key?(current)
|
26
|
+
end
|
27
|
+
return "1"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'fastlane/plugin/ciutils/version'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module Ciutils
|
5
|
+
# Return all .rb files inside the "actions" and "helper" directory
|
6
|
+
def self.all_classes
|
7
|
+
Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# By default we want to import all available actions and helpers
|
13
|
+
# A plugin can contain any number of actions and plugins
|
14
|
+
Fastlane::Ciutils.all_classes.each do |current|
|
15
|
+
require current
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fastlane-plugin-ciutils
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nicolae Ghimbovschi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-08-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: slather
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ocunit2junit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: xcodeproj
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: plist
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rake
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: fastlane
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 1.110.0
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 1.110.0
|
153
|
+
description:
|
154
|
+
email: xfreebird@gmail.com
|
155
|
+
executables: []
|
156
|
+
extensions: []
|
157
|
+
extra_rdoc_files: []
|
158
|
+
files:
|
159
|
+
- LICENSE
|
160
|
+
- README.md
|
161
|
+
- lib/fastlane/plugin/ciutils.rb
|
162
|
+
- lib/fastlane/plugin/ciutils/actions/en_build_number.rb
|
163
|
+
- lib/fastlane/plugin/ciutils/actions/en_ci_utils_init_action.rb
|
164
|
+
- lib/fastlane/plugin/ciutils/actions/en_close_simulator.rb
|
165
|
+
- lib/fastlane/plugin/ciutils/actions/en_git_changelog.rb
|
166
|
+
- lib/fastlane/plugin/ciutils/actions/en_install_provisioning_profiles.rb
|
167
|
+
- lib/fastlane/plugin/ciutils/actions/en_profile_name.rb
|
168
|
+
- lib/fastlane/plugin/ciutils/actions/en_remove_keychain.rb
|
169
|
+
- lib/fastlane/plugin/ciutils/actions/en_setup_keychain.rb
|
170
|
+
- lib/fastlane/plugin/ciutils/actions/en_setup_project.rb
|
171
|
+
- lib/fastlane/plugin/ciutils/helper/ciutils_helper.rb
|
172
|
+
- lib/fastlane/plugin/ciutils/version.rb
|
173
|
+
homepage: https://github.com/xfreebird/fastlane-plugin-ciutils
|
174
|
+
licenses:
|
175
|
+
- MIT
|
176
|
+
metadata: {}
|
177
|
+
post_install_message:
|
178
|
+
rdoc_options: []
|
179
|
+
require_paths:
|
180
|
+
- lib
|
181
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
182
|
+
requirements:
|
183
|
+
- - ">="
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0'
|
186
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
187
|
+
requirements:
|
188
|
+
- - ">="
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: '0'
|
191
|
+
requirements: []
|
192
|
+
rubyforge_project:
|
193
|
+
rubygems_version: 2.6.8
|
194
|
+
signing_key:
|
195
|
+
specification_version: 4
|
196
|
+
summary: Various utilities for iOS CI
|
197
|
+
test_files: []
|