├── .gitignore ├── versions ├── 1.0 │ ├── Pluginfile │ ├── Gemfile │ ├── Gemfile.lock │ └── parse_project_settings.rb ├── 1.2 │ ├── Pluginfile │ ├── Gemfile │ ├── Gemfile.lock │ └── parse_project_settings.rb ├── 1.3 │ ├── Pluginfile │ ├── Gemfile │ ├── Gemfile.lock │ └── parse_project_settings.rb ├── 1.4 │ ├── Pluginfile │ ├── Gemfile │ ├── Gemfile.lock │ └── parse_project_settings.rb ├── 1.5 │ ├── Pluginfile │ ├── Gemfile │ ├── Gemfile.lock │ └── parse_project_settings.rb ├── 2.0 │ ├── Pluginfile │ ├── Gemfile │ ├── Gemfile.lock │ └── parse_project_settings.rb ├── 2.1 │ ├── Pluginfile │ ├── Gemfile │ └── Gemfile.lock ├── 2.2 │ ├── Pluginfile │ ├── Gemfile │ └── Gemfile.lock ├── 1.0-beta │ ├── Pluginfile │ ├── Gemfile │ ├── Gemfile.lock │ └── parse_project_settings.rb ├── 1.1-beta │ ├── Pluginfile │ ├── Gemfile │ ├── Gemfile.lock │ └── parse_project_settings.rb ├── development │ ├── Pluginfile │ ├── Gemfile │ ├── Gemfile.lock │ └── parse_project_settings.rb ├── 0.1 │ └── parse_project_settings.rb └── 0.2 │ └── parse_project_settings.rb ├── LICENSE ├── step.sh ├── step.yml ├── bitrise.yml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .bitrise* 2 | .gows.user.yml 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /versions/1.0/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-badge' 6 | -------------------------------------------------------------------------------- /versions/1.2/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-badge' 6 | -------------------------------------------------------------------------------- /versions/1.3/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-badge' 6 | -------------------------------------------------------------------------------- /versions/1.4/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-badge' 6 | -------------------------------------------------------------------------------- /versions/1.5/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-badge' 6 | -------------------------------------------------------------------------------- /versions/2.0/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-badge' 6 | -------------------------------------------------------------------------------- /versions/2.1/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-badge' 6 | -------------------------------------------------------------------------------- /versions/2.2/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-badge' 6 | -------------------------------------------------------------------------------- /versions/1.0-beta/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-badge' 6 | -------------------------------------------------------------------------------- /versions/1.1-beta/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-badge' 6 | -------------------------------------------------------------------------------- /versions/development/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | gem 'fastlane-plugin-badge' 6 | -------------------------------------------------------------------------------- /versions/1.0/Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'fastlane' 8 | gem 'cocoapods' 9 | 10 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 11 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 12 | -------------------------------------------------------------------------------- /versions/1.0-beta/Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'fastlane' 8 | gem 'cocoapods', '~> 1.6.0.beta.2' 9 | 10 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 11 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 12 | -------------------------------------------------------------------------------- /versions/1.1-beta/Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'fastlane' 8 | gem 'cocoapods', '~> 1.6.0.beta.2' 9 | 10 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 11 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 12 | -------------------------------------------------------------------------------- /versions/1.2/Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'fastlane' 8 | gem 'cocoapods' 9 | gem 'httparty' 10 | gem 'json' 11 | gem 'rubyzip' 12 | 13 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 14 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 15 | -------------------------------------------------------------------------------- /versions/1.3/Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'fastlane' 8 | gem 'cocoapods' 9 | gem 'httparty' 10 | gem 'json' 11 | gem 'rubyzip' 12 | 13 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 14 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 15 | -------------------------------------------------------------------------------- /versions/1.4/Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'fastlane' 8 | gem 'cocoapods' 9 | gem 'httparty' 10 | gem 'json' 11 | gem 'rubyzip' 12 | 13 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 14 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 15 | -------------------------------------------------------------------------------- /versions/1.5/Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'fastlane' 8 | gem 'cocoapods' 9 | gem 'httparty' 10 | gem 'json' 11 | gem 'rubyzip' 12 | 13 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 14 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 15 | -------------------------------------------------------------------------------- /versions/2.0/Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'fastlane' 8 | gem 'cocoapods' 9 | gem 'httparty' 10 | gem 'json' 11 | gem 'rubyzip' 12 | 13 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 14 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 15 | -------------------------------------------------------------------------------- /versions/2.1/Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'fastlane' 8 | gem 'cocoapods' 9 | gem 'httparty' 10 | gem 'json' 11 | gem 'rubyzip' 12 | 13 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 14 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 15 | -------------------------------------------------------------------------------- /versions/2.2/Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'fastlane' 8 | gem 'cocoapods' 9 | gem 'httparty' 10 | gem 'json' 11 | gem 'rubyzip' 12 | 13 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 14 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 15 | -------------------------------------------------------------------------------- /versions/development/Gemfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | # 3 | # Ensure this file is checked in to source control! 4 | 5 | source "https://rubygems.org" 6 | 7 | gem 'fastlane' 8 | gem 'cocoapods' 9 | gem 'httparty' 10 | gem 'json' 11 | gem 'rubyzip' 12 | 13 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 14 | eval_gemfile(plugins_path) if File.exist?(plugins_path) 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Nodes iOS 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. 22 | -------------------------------------------------------------------------------- /step.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | THIS_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | 6 | # Handle CI Version 7 | DEFAULT_CI_VERSION='1.2' 8 | CI_PROJECT_FILE="project.yml" 9 | CI_VERSION_REGEX="ci-version: \"([0-9.]+)\"" 10 | 11 | if [[ ( -z "${CI_VERSION}" ) && ( `cat project.yml` =~ $CI_VERSION_REGEX ) ]]; then 12 | # Parse the CI version from the project.yml, unless set by environment 13 | CI_VERSION=${BASH_REMATCH[1]} 14 | elif [[ -z "${CI_VERSION}" ]]; then 15 | # Fallback to a default version if not set by environment variable or in project.yml 16 | CI_VERSION=$DEFAULT_CI_VERSION 17 | fi 18 | 19 | echo "Using Nodes CI version: ${CI_VERSION}" 20 | 21 | copyFastfile() 22 | { 23 | # if directory doesn't exist, create it 24 | if [ ! -d "$PWD/fastlane" ]; then 25 | mkdir $PWD/fastlane 26 | fi 27 | 28 | # Try to load fastile for the correct CI version 29 | if [ -e "${THIS_SCRIPT_DIR}/versions/${CI_VERSION}/Fastfile" ]; then 30 | cp "${THIS_SCRIPT_DIR}/versions/${CI_VERSION}/Fastfile" $PWD/fastlane 31 | else 32 | # Otherwise fail 33 | echo "No fastfile found in ci tools version folder ${CI_VERSION}." 34 | exit 1 35 | fi 36 | } 37 | 38 | if [ "${script_input}" == 'Fastlane copy' ]; then 39 | 40 | copyFastfile 41 | 42 | # Check for plugin capabilities 43 | if [[ -e "${THIS_SCRIPT_DIR}/versions/${CI_VERSION}/Pluginfile" && 44 | "${THIS_SCRIPT_DIR}/versions/${CI_VERSION}/Gemfile" && 45 | "${THIS_SCRIPT_DIR}/versions/${CI_VERSION}/Gemfile.lock" ]]; then 46 | cp "${THIS_SCRIPT_DIR}/versions/${CI_VERSION}/Pluginfile" $PWD/fastlane 47 | cp "${THIS_SCRIPT_DIR}/versions/${CI_VERSION}/Gemfile" $PWD 48 | cp "${THIS_SCRIPT_DIR}/versions/${CI_VERSION}/Gemfile.lock" $PWD 49 | 50 | gem install bundler "--force" "--no-document" "-v" "2.0.2" 51 | bundle install 52 | bundle exec fastlane -- install_plugins 53 | fi 54 | 55 | elif [ "${script_input}" == 'Prep Slack message' ]; then 56 | copyFastfile 57 | else 58 | # Try to load fastile for the correct CI version 59 | if [ -e "${THIS_SCRIPT_DIR}/versions/${CI_VERSION}/parse_project_settings.rb" ]; then 60 | gem install hockeyver 61 | ruby "${THIS_SCRIPT_DIR}/versions/${CI_VERSION}/parse_project_settings.rb" 62 | else 63 | # Otherwise fail 64 | echo "No fastfile found in ci tools version folder ${CI_VERSION}." 65 | exit 1 66 | fi 67 | fi 68 | -------------------------------------------------------------------------------- /step.yml: -------------------------------------------------------------------------------- 1 | # 2 | # A couple of useful guides & docs: 3 | # 4 | # - Main Bitrise CLI docs: https://github.com/bitrise-io/bitrise/tree/master/_docs 5 | # - Step Development Guideline: https://github.com/bitrise-io/bitrise/blob/master/_docs/step-development-guideline.md 6 | # - Bitrise.yml format spec: https://github.com/bitrise-io/bitrise/blob/master/_docs/bitrise-yml-format-spec.md 7 | # - Bitrise docs: http://devcenter.bitrise.io/ 8 | # - Bitrise CLI guides: http://devcenter.bitrise.io/bitrise-cli/ 9 | 10 | title: |- 11 | Nodes Custom Script 12 | summary: | 13 | Runs a custom script hosted at our private github 14 | description: | 15 | Runs a custom script hosted at our private github 16 | website: https://github.com/nodes-ios/bitrise-step-nodes-custom-script 17 | source_code_url: https://github.com/nodes-ios/bitrise-step-nodes-custom-script 18 | support_url: https://github.com/nodes-ios/bitrise-step-nodes-custom-script/issues 19 | host_os_tags: 20 | - osx-10.10 21 | - ubuntu-16.04 22 | 23 | # If this step should be available only for certain project types 24 | # just uncomment this `project_type_tags` section and include all the 25 | # project types supported by the step. If the step can be used for all 26 | # project types then you can just remove this section. 27 | # If no `project_type_tags` specified (or specified as an empty array) 28 | # that means the step can be used for any project type. 29 | # You can find more information about project type tags in the Step Development Guideline: 30 | # https://github.com/bitrise-io/bitrise/blob/master/_docs/step-development-guideline.md 31 | # 32 | # project_type_tags: 33 | # - ios 34 | # - macos 35 | # - android 36 | # - xamarin 37 | # - react-native 38 | # - cordova 39 | # - ionic 40 | 41 | # Type tags are used for categorizing steps, for easier step discovery in Step Libraries. 42 | # You can find more information about type tags in the Step Development Guideline: 43 | # https://github.com/bitrise-io/bitrise/blob/master/_docs/step-development-guideline.md 44 | type_tags: 45 | - utility 46 | 47 | is_requires_admin_user: true 48 | is_always_run: false 49 | is_skippable: false 50 | run_if: "" 51 | 52 | deps: 53 | brew: 54 | - name: git 55 | - name: wget 56 | apt_get: 57 | - name: git 58 | - name: wget 59 | 60 | 61 | toolkit: 62 | bash: 63 | entry_file: step.sh 64 | 65 | 66 | inputs: 67 | - script_input: "Parse project settings" 68 | opts: 69 | title: "Choose script" 70 | summary: Select a script to run 71 | is_expand: true 72 | is_required: true 73 | value_options: ["Parse project settings", "Fastlane copy", "Prep Slack message"] 74 | 75 | -------------------------------------------------------------------------------- /bitrise.yml: -------------------------------------------------------------------------------- 1 | format_version: 3 2 | default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git 3 | 4 | app: 5 | envs: 6 | # An example secret param, define it (A_SECRET_PARAM) in .bitrise.secrets.yml 7 | - A_SECRET_PARAM: $A_SECRET_PARAM 8 | # If you want to share this step into a StepLib 9 | - BITRISE_STEP_ID: nodes-custom-script 10 | - BITRISE_STEP_VERSION: "0.0.1" 11 | - BITRISE_STEP_GIT_CLONE_URL: https://github.com/nodes-ios/bitrise-step-nodes-custom-script 12 | - MY_STEPLIB_REPO_FORK_GIT_URL: $MY_STEPLIB_REPO_FORK_GIT_URL 13 | 14 | workflows: 15 | test: 16 | steps: 17 | - script: 18 | inputs: 19 | - content: | 20 | #!/bin/bash 21 | echo "Just an example 'secrets' print." 22 | echo "The value of 'A_SECRET_PARAM' is: $A_SECRET_PARAM" 23 | - change-workdir: 24 | title: Switch working dir to test / _tmp dir 25 | description: |- 26 | To prevent step testing issues, like referencing relative 27 | files with just './some-file' in the step's code, which would 28 | work for testing the step from this directory directly 29 | but would break if the step is included in another `bitrise.yml`. 30 | run_if: true 31 | inputs: 32 | - path: ./_tmp 33 | - is_create_path: true 34 | - path::./: 35 | title: Step Test 36 | description: |- 37 | The example input has a default value, 38 | you can overwrite it if you want to, just like we did below, 39 | but the step would use the default value specified in the `step.yml` 40 | file if you would not specify another value. 41 | run_if: true 42 | inputs: 43 | - example_step_input: Example Step Input's value 44 | - script: 45 | inputs: 46 | - content: | 47 | #!/bin/bash 48 | echo "This output was generated by the Step (EXAMPLE_STEP_OUTPUT): $EXAMPLE_STEP_OUTPUT" 49 | 50 | 51 | # ---------------------------------------------------------------- 52 | # --- workflows to Share this step into a Step Library 53 | audit-this-step: 54 | steps: 55 | - script: 56 | inputs: 57 | - content: |- 58 | #!/bin/bash 59 | set -ex 60 | stepman audit --step-yml ./step.yml 61 | 62 | share-this-step: 63 | envs: 64 | # if you want to share this step into a StepLib 65 | - MY_STEPLIB_REPO_FORK_GIT_URL: $MY_STEPLIB_REPO_FORK_GIT_URL 66 | - BITRISE_STEP_ID: $BITRISE_STEP_ID 67 | - BITRISE_STEP_VERSION: $BITRISE_STEP_VERSION 68 | - BITRISE_STEP_GIT_CLONE_URL: $BITRISE_STEP_GIT_CLONE_URL 69 | description: |- 70 | If this is the first time you try to share a Step you should 71 | first call: $ bitrise share 72 | 73 | This will print you a guide, and information about how Step sharing 74 | works. Please read it at least once! 75 | 76 | As noted in the Step sharing guide you'll have to fork the 77 | StepLib you want to share this step into. Once you're done with forking 78 | the repository you should set your own fork's git clone URL 79 | in the `.bitrise.secrets.yml` file, or here in the `envs` section, 80 | as the value of the `MY_STEPLIB_REPO_FORK_GIT_URL` environment. 81 | 82 | You're now ready to share this Step, just make sure that 83 | the `BITRISE_STEP_ID` and `BITRISE_STEP_VERSION` 84 | environments are set to the desired values! 85 | 86 | To share this Step into a StepLib you can just run: $ bitrise run share-this-step 87 | 88 | Once it finishes the only thing left is to actually create a Pull Request, 89 | the way described in the guide printed at the end of the process. 90 | before_run: 91 | - audit-this-step 92 | steps: 93 | - script: 94 | inputs: 95 | - content: |- 96 | #!/bin/bash 97 | set -ex 98 | bitrise share start -c "${MY_STEPLIB_REPO_FORK_GIT_URL}" 99 | bitrise share create --stepid "${BITRISE_STEP_ID}" --tag "${BITRISE_STEP_VERSION}" --git "${BITRISE_STEP_GIT_CLONE_URL}" 100 | bitrise share finish 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nodes Custom Script 2 | 3 | Runs a custom script hosted at our private github 4 | 5 | To add this step to your workflow, add this as a step in bitrise.yml: 6 | 7 | `- git::https://github.com/nodes-ios/bitrise-step-nodes-custom-script.git@master:` 8 | 9 | Be sure to select the correct input value for the script you want to run: 10 | 11 | - `Parse project settings` Runs the `parse_project_settings.rb` script 12 | - `Fastlane copy` Copies the Fastfile into the `/fastlane` directory 13 | - `Prep Slack message` Runs the `prepare_slack.rb` script 14 | 15 | This script will create all the necessary steps on Bitrise (detailed bellow) to make the build. 16 | 17 | 18 | ## Workflow 19 | 20 | There are 6 workflows, each with its own set of steps. The process works like this: 21 | 22 | 1. Checkout the project and verify that all of the settings and configurations are correct. 23 | 2. Build carthage 24 | 3. Build, archive, and sign the targets. 25 | 4. Upload to Hockey 26 | 5. Upload to Testflight 27 | 6. Notify Slack 28 | 29 | Most of these steps require custom scripts. These steps are written in Ruby and stored at [nodes-ios/bitrise-step-nodes-custom-script](https://github.com/nodes-ios/bitrise-step-nodes-custom-script). The Bitrise workflow will read from these scripts (currently at branch `master`) so that your project will always build with the latest versions of the scripts. 30 | 31 | 32 | ### Nodes custom script: 33 | 34 | #### 1) Prepare-repo 35 | 36 | Activating the SSH key for our private nodes-projects repo and cloning the project are handled automatically by bitrise. A changelog of the commit history between now and the previous tag is generated by a script maintained by [nodes-android](https://github.com/nodes-android/ci-bitrise-changelog-step). 37 | 38 | The first Nodes custom script happens next, which is the `parse_project_settings.rb` script. The script is fairly well documented, but at a high level this is what happens: The project.yml file is loaded and parsed, as is the xcodeproj file, and the two are compared and validated to make sure information matches and all required settings exist. The values needed for building and uploading are saved as environment variables. The most likely step to fail here is hockey version number comparing. If the current project build number is the same as the version on hockey, validation will fail and your build will fail. Make sure to increment your build number before releasing a new tag! 39 | 40 | #### 2) Prepare-dependencies 41 | 42 | This is mostly handeled by Bitrise. Cached build folder is loaded, carthage is built (using cached builds if possible), and then the cache is updated. If running locally using the Bitrise CLI, this step is skipped. 43 | 44 | #### 3) Build 45 | 46 | Building is handled by Fastlane. The Fastfile used here is loaded from the custom script step. The script copies the `Fastfile` to the project directory for use in this step, as well as the two deploy steps. 47 | For each target, the certificate and provisioning profile are retrieved from `match` and installed, then the target is built, archived, and exported as a .ipa file. The target is then re-exported with bitcode turned off, because bitcode and enterprise profiles don't play nice together. `match` grabs the enterprise cert and profile, and then that copy is resigned with the enterprise profile and certificate for uploading to Hockey. Then the upload info is saved as an environment variable. 48 | 49 | #### 4) Deploy-hockey 50 | 51 | Also handled by Fastlane, and it uses the same Fastfile as in the build step. This step is fairly straightforward: The deploy configuration from the build step is loaded, and used to upload directly to Hockey. Note that this step will be skipped if `hockey-upload` is disabled in the project.yml file. 52 | 53 | #### 5) Deploy-testflight 54 | 55 | Also handled by Fastlane, using the same Fastfile. Again, this step is straightforward and is basically indentical to the Hockey upload step. It will be skipped if `testflight-upload` is disabled in the project.yml file. 56 | 57 | Note that your build may fail here if you have not incremented your build number since the last Testflight upload. 58 | 59 | #### 6) Notify 60 | 61 | The first thing that is notified is github, this is what confirms that the build passed, if something was waiting on the status before proceeding. 62 | 63 | The final custom script is next, which aggregates all of the build information into one message for slack to display, including the scheme (target name, basically), configuration (Adhoc/Release), version number, and Hockey link. There will also be a note that a Testflight build will be available after processing. 64 | -------------------------------------------------------------------------------- /versions/1.0/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.0) 5 | activesupport (4.2.11.1) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.6.0) 11 | public_suffix (>= 2.0.2, < 4.0) 12 | atomos (0.1.3) 13 | babosa (1.0.2) 14 | claide (1.0.2) 15 | cocoapods (1.7.0) 16 | activesupport (>= 4.0.2, < 5) 17 | claide (>= 1.0.2, < 2.0) 18 | cocoapods-core (= 1.7.0) 19 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 20 | cocoapods-downloader (>= 1.2.2, < 2.0) 21 | cocoapods-plugins (>= 1.0.0, < 2.0) 22 | cocoapods-search (>= 1.0.0, < 2.0) 23 | cocoapods-stats (>= 1.0.0, < 2.0) 24 | cocoapods-trunk (>= 1.3.1, < 2.0) 25 | cocoapods-try (>= 1.1.0, < 2.0) 26 | colored2 (~> 3.1) 27 | escape (~> 0.0.4) 28 | fourflusher (>= 2.2.0, < 3.0) 29 | gh_inspector (~> 1.0) 30 | molinillo (~> 0.6.6) 31 | nap (~> 1.0) 32 | ruby-macho (~> 1.4) 33 | xcodeproj (>= 1.8.2, < 2.0) 34 | cocoapods-core (1.7.0) 35 | activesupport (>= 4.0.2, < 6) 36 | fuzzy_match (~> 2.0.4) 37 | nap (~> 1.0) 38 | cocoapods-deintegrate (1.0.4) 39 | cocoapods-downloader (1.2.2) 40 | cocoapods-plugins (1.0.0) 41 | nap 42 | cocoapods-search (1.0.0) 43 | cocoapods-stats (1.1.0) 44 | cocoapods-trunk (1.3.1) 45 | nap (>= 0.8, < 2.0) 46 | netrc (~> 0.11) 47 | cocoapods-try (1.1.0) 48 | colored (1.2) 49 | colored2 (3.1.2) 50 | commander-fastlane (4.4.6) 51 | highline (~> 1.7.2) 52 | concurrent-ruby (1.1.5) 53 | declarative (0.0.10) 54 | declarative-option (0.1.0) 55 | digest-crc (0.4.1) 56 | domain_name (0.5.20180417) 57 | unf (>= 0.0.5, < 1.0.0) 58 | dotenv (2.7.2) 59 | emoji_regex (1.0.1) 60 | escape (0.0.4) 61 | excon (0.64.0) 62 | faraday (0.15.4) 63 | multipart-post (>= 1.2, < 3) 64 | faraday-cookie_jar (0.0.6) 65 | faraday (>= 0.7.4) 66 | http-cookie (~> 1.0.0) 67 | faraday_middleware (0.13.1) 68 | faraday (>= 0.7.4, < 1.0) 69 | fastimage (2.1.5) 70 | fastlane (2.123.0) 71 | CFPropertyList (>= 2.3, < 4.0.0) 72 | addressable (>= 2.3, < 3.0.0) 73 | babosa (>= 1.0.2, < 2.0.0) 74 | bundler (>= 1.12.0, < 3.0.0) 75 | colored 76 | commander-fastlane (>= 4.4.6, < 5.0.0) 77 | dotenv (>= 2.1.1, < 3.0.0) 78 | emoji_regex (>= 0.1, < 2.0) 79 | excon (>= 0.45.0, < 1.0.0) 80 | faraday (~> 0.9) 81 | faraday-cookie_jar (~> 0.0.6) 82 | faraday_middleware (~> 0.9) 83 | fastimage (>= 2.1.0, < 3.0.0) 84 | gh_inspector (>= 1.1.2, < 2.0.0) 85 | google-api-client (>= 0.21.2, < 0.24.0) 86 | google-cloud-storage (>= 1.15.0, < 2.0.0) 87 | highline (>= 1.7.2, < 2.0.0) 88 | json (< 3.0.0) 89 | mini_magick (~> 4.5.1) 90 | multi_json 91 | multi_xml (~> 0.5) 92 | multipart-post (~> 2.0.0) 93 | plist (>= 3.1.0, < 4.0.0) 94 | public_suffix (~> 2.0.0) 95 | rubyzip (>= 1.2.2, < 2.0.0) 96 | security (= 0.1.3) 97 | simctl (~> 1.6.3) 98 | slack-notifier (>= 2.0.0, < 3.0.0) 99 | terminal-notifier (>= 2.0.0, < 3.0.0) 100 | terminal-table (>= 1.4.5, < 2.0.0) 101 | tty-screen (>= 0.6.3, < 1.0.0) 102 | tty-spinner (>= 0.8.0, < 1.0.0) 103 | word_wrap (~> 1.0.0) 104 | xcodeproj (>= 1.8.1, < 2.0.0) 105 | xcpretty (~> 0.3.0) 106 | xcpretty-travis-formatter (>= 0.0.3) 107 | fourflusher (2.2.0) 108 | fuzzy_match (2.0.4) 109 | gh_inspector (1.1.3) 110 | google-api-client (0.23.9) 111 | addressable (~> 2.5, >= 2.5.1) 112 | googleauth (>= 0.5, < 0.7.0) 113 | httpclient (>= 2.8.1, < 3.0) 114 | mime-types (~> 3.0) 115 | representable (~> 3.0) 116 | retriable (>= 2.0, < 4.0) 117 | signet (~> 0.9) 118 | google-cloud-core (1.3.0) 119 | google-cloud-env (~> 1.0) 120 | google-cloud-env (1.0.5) 121 | faraday (~> 0.11) 122 | google-cloud-storage (1.16.0) 123 | digest-crc (~> 0.4) 124 | google-api-client (~> 0.23) 125 | google-cloud-core (~> 1.2) 126 | googleauth (>= 0.6.2, < 0.10.0) 127 | googleauth (0.6.7) 128 | faraday (~> 0.12) 129 | jwt (>= 1.4, < 3.0) 130 | memoist (~> 0.16) 131 | multi_json (~> 1.11) 132 | os (>= 0.9, < 2.0) 133 | signet (~> 0.7) 134 | highline (1.7.10) 135 | http-cookie (1.0.3) 136 | domain_name (~> 0.5) 137 | httpclient (2.8.3) 138 | i18n (0.9.5) 139 | concurrent-ruby (~> 1.0) 140 | json (2.2.0) 141 | jwt (2.2.1) 142 | memoist (0.16.0) 143 | mime-types (3.2.2) 144 | mime-types-data (~> 3.2015) 145 | mime-types-data (3.2019.0331) 146 | mini_magick (4.5.1) 147 | minitest (5.11.3) 148 | molinillo (0.6.6) 149 | multi_json (1.13.1) 150 | multi_xml (0.6.0) 151 | multipart-post (2.0.0) 152 | nanaimo (0.2.6) 153 | nap (1.1.0) 154 | naturally (2.2.0) 155 | netrc (0.11.0) 156 | os (1.0.1) 157 | plist (3.5.0) 158 | public_suffix (2.0.5) 159 | representable (3.0.4) 160 | declarative (< 0.1.0) 161 | declarative-option (< 0.2.0) 162 | uber (< 0.2.0) 163 | retriable (3.1.2) 164 | rouge (2.0.7) 165 | ruby-macho (1.4.0) 166 | rubyzip (1.2.3) 167 | security (0.1.3) 168 | signet (0.11.0) 169 | addressable (~> 2.3) 170 | faraday (~> 0.9) 171 | jwt (>= 1.5, < 3.0) 172 | multi_json (~> 1.10) 173 | simctl (1.6.5) 174 | CFPropertyList 175 | naturally 176 | slack-notifier (2.3.2) 177 | terminal-notifier (2.0.0) 178 | terminal-table (1.8.0) 179 | unicode-display_width (~> 1.1, >= 1.1.1) 180 | thread_safe (0.3.6) 181 | tty-cursor (0.6.1) 182 | tty-screen (0.7.0) 183 | tty-spinner (0.9.0) 184 | tty-cursor (~> 0.6.0) 185 | tzinfo (1.2.5) 186 | thread_safe (~> 0.1) 187 | uber (0.1.0) 188 | unf (0.1.4) 189 | unf_ext 190 | unf_ext (0.0.7.6) 191 | unicode-display_width (1.6.0) 192 | word_wrap (1.0.0) 193 | xcodeproj (1.9.0) 194 | CFPropertyList (>= 2.3.3, < 4.0) 195 | atomos (~> 0.1.3) 196 | claide (>= 1.0.2, < 2.0) 197 | colored2 (~> 3.1) 198 | nanaimo (~> 0.2.6) 199 | xcpretty (0.3.0) 200 | rouge (~> 2.0.7) 201 | xcpretty-travis-formatter (1.0.0) 202 | xcpretty (~> 0.2, >= 0.0.7) 203 | 204 | PLATFORMS 205 | ruby 206 | 207 | DEPENDENCIES 208 | cocoapods 209 | fastlane 210 | 211 | BUNDLED WITH 212 | 1.16.6 213 | -------------------------------------------------------------------------------- /versions/1.0-beta/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.0) 5 | activesupport (4.2.11) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.5.2) 11 | public_suffix (>= 2.0.2, < 4.0) 12 | atomos (0.1.3) 13 | babosa (1.0.2) 14 | claide (1.0.2) 15 | cocoapods (1.6.0.beta.2) 16 | activesupport (>= 4.0.2, < 5) 17 | claide (>= 1.0.2, < 2.0) 18 | cocoapods-core (= 1.6.0.beta.2) 19 | cocoapods-deintegrate (>= 1.0.2, < 2.0) 20 | cocoapods-downloader (>= 1.2.2, < 2.0) 21 | cocoapods-plugins (>= 1.0.0, < 2.0) 22 | cocoapods-search (>= 1.0.0, < 2.0) 23 | cocoapods-stats (>= 1.0.0, < 2.0) 24 | cocoapods-trunk (>= 1.3.1, < 2.0) 25 | cocoapods-try (>= 1.1.0, < 2.0) 26 | colored2 (~> 3.1) 27 | escape (~> 0.0.4) 28 | fourflusher (~> 2.0.1) 29 | gh_inspector (~> 1.0) 30 | molinillo (~> 0.6.6) 31 | nap (~> 1.0) 32 | ruby-macho (~> 1.3, >= 1.3.1) 33 | xcodeproj (>= 1.7.0, < 2.0) 34 | cocoapods-core (1.6.0.beta.2) 35 | activesupport (>= 4.0.2, < 6) 36 | fuzzy_match (~> 2.0.4) 37 | nap (~> 1.0) 38 | cocoapods-deintegrate (1.0.2) 39 | cocoapods-downloader (1.2.2) 40 | cocoapods-plugins (1.0.0) 41 | nap 42 | cocoapods-search (1.0.0) 43 | cocoapods-stats (1.0.0) 44 | cocoapods-trunk (1.3.1) 45 | nap (>= 0.8, < 2.0) 46 | netrc (~> 0.11) 47 | cocoapods-try (1.1.0) 48 | colored (1.2) 49 | colored2 (3.1.2) 50 | commander-fastlane (4.4.6) 51 | highline (~> 1.7.2) 52 | concurrent-ruby (1.1.4) 53 | declarative (0.0.10) 54 | declarative-option (0.1.0) 55 | digest-crc (0.4.1) 56 | domain_name (0.5.20180417) 57 | unf (>= 0.0.5, < 1.0.0) 58 | dotenv (2.5.0) 59 | emoji_regex (0.1.1) 60 | escape (0.0.4) 61 | excon (0.62.0) 62 | faraday (0.15.4) 63 | multipart-post (>= 1.2, < 3) 64 | faraday-cookie_jar (0.0.6) 65 | faraday (>= 0.7.4) 66 | http-cookie (~> 1.0.0) 67 | faraday_middleware (0.12.2) 68 | faraday (>= 0.7.4, < 1.0) 69 | fastimage (2.1.5) 70 | fastlane (2.112.0) 71 | CFPropertyList (>= 2.3, < 4.0.0) 72 | addressable (>= 2.3, < 3.0.0) 73 | babosa (>= 1.0.2, < 2.0.0) 74 | bundler (>= 1.12.0, < 2.0.0) 75 | colored 76 | commander-fastlane (>= 4.4.6, < 5.0.0) 77 | dotenv (>= 2.1.1, < 3.0.0) 78 | emoji_regex (~> 0.1) 79 | excon (>= 0.45.0, < 1.0.0) 80 | faraday (~> 0.9) 81 | faraday-cookie_jar (~> 0.0.6) 82 | faraday_middleware (~> 0.9) 83 | fastimage (>= 2.1.0, < 3.0.0) 84 | gh_inspector (>= 1.1.2, < 2.0.0) 85 | google-api-client (>= 0.21.2, < 0.24.0) 86 | google-cloud-storage (>= 1.15.0, < 2.0.0) 87 | highline (>= 1.7.2, < 2.0.0) 88 | json (< 3.0.0) 89 | mini_magick (~> 4.5.1) 90 | multi_json 91 | multi_xml (~> 0.5) 92 | multipart-post (~> 2.0.0) 93 | plist (>= 3.1.0, < 4.0.0) 94 | public_suffix (~> 2.0.0) 95 | rubyzip (>= 1.2.2, < 2.0.0) 96 | security (= 0.1.3) 97 | simctl (~> 1.6.3) 98 | slack-notifier (>= 2.0.0, < 3.0.0) 99 | terminal-notifier (>= 1.6.2, < 2.0.0) 100 | terminal-table (>= 1.4.5, < 2.0.0) 101 | tty-screen (>= 0.6.3, < 1.0.0) 102 | tty-spinner (>= 0.8.0, < 1.0.0) 103 | word_wrap (~> 1.0.0) 104 | xcodeproj (>= 1.6.0, < 2.0.0) 105 | xcpretty (~> 0.3.0) 106 | xcpretty-travis-formatter (>= 0.0.3) 107 | fourflusher (2.0.1) 108 | fuzzy_match (2.0.4) 109 | gh_inspector (1.1.3) 110 | google-api-client (0.23.9) 111 | addressable (~> 2.5, >= 2.5.1) 112 | googleauth (>= 0.5, < 0.7.0) 113 | httpclient (>= 2.8.1, < 3.0) 114 | mime-types (~> 3.0) 115 | representable (~> 3.0) 116 | retriable (>= 2.0, < 4.0) 117 | signet (~> 0.9) 118 | google-cloud-core (1.2.7) 119 | google-cloud-env (~> 1.0) 120 | google-cloud-env (1.0.5) 121 | faraday (~> 0.11) 122 | google-cloud-storage (1.15.0) 123 | digest-crc (~> 0.4) 124 | google-api-client (~> 0.23) 125 | google-cloud-core (~> 1.2) 126 | googleauth (~> 0.6.2) 127 | googleauth (0.6.7) 128 | faraday (~> 0.12) 129 | jwt (>= 1.4, < 3.0) 130 | memoist (~> 0.16) 131 | multi_json (~> 1.11) 132 | os (>= 0.9, < 2.0) 133 | signet (~> 0.7) 134 | highline (1.7.10) 135 | http-cookie (1.0.3) 136 | domain_name (~> 0.5) 137 | httpclient (2.8.3) 138 | i18n (0.9.5) 139 | concurrent-ruby (~> 1.0) 140 | json (2.1.0) 141 | jwt (2.1.0) 142 | memoist (0.16.0) 143 | mime-types (3.2.2) 144 | mime-types-data (~> 3.2015) 145 | mime-types-data (3.2018.0812) 146 | mini_magick (4.5.1) 147 | minitest (5.11.3) 148 | molinillo (0.6.6) 149 | multi_json (1.13.1) 150 | multi_xml (0.6.0) 151 | multipart-post (2.0.0) 152 | nanaimo (0.2.6) 153 | nap (1.1.0) 154 | naturally (2.2.0) 155 | netrc (0.11.0) 156 | os (1.0.0) 157 | plist (3.5.0) 158 | public_suffix (2.0.5) 159 | representable (3.0.4) 160 | declarative (< 0.1.0) 161 | declarative-option (< 0.2.0) 162 | uber (< 0.2.0) 163 | retriable (3.1.2) 164 | rouge (2.0.7) 165 | ruby-macho (1.3.1) 166 | rubyzip (1.2.2) 167 | security (0.1.3) 168 | signet (0.11.0) 169 | addressable (~> 2.3) 170 | faraday (~> 0.9) 171 | jwt (>= 1.5, < 3.0) 172 | multi_json (~> 1.10) 173 | simctl (1.6.5) 174 | CFPropertyList 175 | naturally 176 | slack-notifier (2.3.2) 177 | terminal-notifier (1.8.0) 178 | terminal-table (1.8.0) 179 | unicode-display_width (~> 1.1, >= 1.1.1) 180 | thread_safe (0.3.6) 181 | tty-cursor (0.6.0) 182 | tty-screen (0.6.5) 183 | tty-spinner (0.9.0) 184 | tty-cursor (~> 0.6.0) 185 | tzinfo (1.2.5) 186 | thread_safe (~> 0.1) 187 | uber (0.1.0) 188 | unf (0.1.4) 189 | unf_ext 190 | unf_ext (0.0.7.5) 191 | unicode-display_width (1.4.1) 192 | word_wrap (1.0.0) 193 | xcodeproj (1.7.0) 194 | CFPropertyList (>= 2.3.3, < 4.0) 195 | atomos (~> 0.1.3) 196 | claide (>= 1.0.2, < 2.0) 197 | colored2 (~> 3.1) 198 | nanaimo (~> 0.2.6) 199 | xcpretty (0.3.0) 200 | rouge (~> 2.0.7) 201 | xcpretty-travis-formatter (1.0.0) 202 | xcpretty (~> 0.2, >= 0.0.7) 203 | 204 | PLATFORMS 205 | ruby 206 | 207 | DEPENDENCIES 208 | cocoapods (~> 1.6.0.beta.2) 209 | fastlane 210 | 211 | BUNDLED WITH 212 | 1.16.6 213 | -------------------------------------------------------------------------------- /versions/1.1-beta/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.0) 5 | activesupport (4.2.11) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.5.2) 11 | public_suffix (>= 2.0.2, < 4.0) 12 | atomos (0.1.3) 13 | babosa (1.0.2) 14 | claide (1.0.2) 15 | cocoapods (1.6.0.beta.2) 16 | activesupport (>= 4.0.2, < 5) 17 | claide (>= 1.0.2, < 2.0) 18 | cocoapods-core (= 1.6.0.beta.2) 19 | cocoapods-deintegrate (>= 1.0.2, < 2.0) 20 | cocoapods-downloader (>= 1.2.2, < 2.0) 21 | cocoapods-plugins (>= 1.0.0, < 2.0) 22 | cocoapods-search (>= 1.0.0, < 2.0) 23 | cocoapods-stats (>= 1.0.0, < 2.0) 24 | cocoapods-trunk (>= 1.3.1, < 2.0) 25 | cocoapods-try (>= 1.1.0, < 2.0) 26 | colored2 (~> 3.1) 27 | escape (~> 0.0.4) 28 | fourflusher (~> 2.0.1) 29 | gh_inspector (~> 1.0) 30 | molinillo (~> 0.6.6) 31 | nap (~> 1.0) 32 | ruby-macho (~> 1.3, >= 1.3.1) 33 | xcodeproj (>= 1.7.0, < 2.0) 34 | cocoapods-core (1.6.0.beta.2) 35 | activesupport (>= 4.0.2, < 6) 36 | fuzzy_match (~> 2.0.4) 37 | nap (~> 1.0) 38 | cocoapods-deintegrate (1.0.2) 39 | cocoapods-downloader (1.2.2) 40 | cocoapods-plugins (1.0.0) 41 | nap 42 | cocoapods-search (1.0.0) 43 | cocoapods-stats (1.0.0) 44 | cocoapods-trunk (1.3.1) 45 | nap (>= 0.8, < 2.0) 46 | netrc (~> 0.11) 47 | cocoapods-try (1.1.0) 48 | colored (1.2) 49 | colored2 (3.1.2) 50 | commander-fastlane (4.4.6) 51 | highline (~> 1.7.2) 52 | concurrent-ruby (1.1.4) 53 | declarative (0.0.10) 54 | declarative-option (0.1.0) 55 | digest-crc (0.4.1) 56 | domain_name (0.5.20180417) 57 | unf (>= 0.0.5, < 1.0.0) 58 | dotenv (2.5.0) 59 | emoji_regex (0.1.1) 60 | escape (0.0.4) 61 | excon (0.62.0) 62 | faraday (0.15.4) 63 | multipart-post (>= 1.2, < 3) 64 | faraday-cookie_jar (0.0.6) 65 | faraday (>= 0.7.4) 66 | http-cookie (~> 1.0.0) 67 | faraday_middleware (0.12.2) 68 | faraday (>= 0.7.4, < 1.0) 69 | fastimage (2.1.5) 70 | fastlane (2.112.0) 71 | CFPropertyList (>= 2.3, < 4.0.0) 72 | addressable (>= 2.3, < 3.0.0) 73 | babosa (>= 1.0.2, < 2.0.0) 74 | bundler (>= 1.12.0, < 2.0.0) 75 | colored 76 | commander-fastlane (>= 4.4.6, < 5.0.0) 77 | dotenv (>= 2.1.1, < 3.0.0) 78 | emoji_regex (~> 0.1) 79 | excon (>= 0.45.0, < 1.0.0) 80 | faraday (~> 0.9) 81 | faraday-cookie_jar (~> 0.0.6) 82 | faraday_middleware (~> 0.9) 83 | fastimage (>= 2.1.0, < 3.0.0) 84 | gh_inspector (>= 1.1.2, < 2.0.0) 85 | google-api-client (>= 0.21.2, < 0.24.0) 86 | google-cloud-storage (>= 1.15.0, < 2.0.0) 87 | highline (>= 1.7.2, < 2.0.0) 88 | json (< 3.0.0) 89 | mini_magick (~> 4.5.1) 90 | multi_json 91 | multi_xml (~> 0.5) 92 | multipart-post (~> 2.0.0) 93 | plist (>= 3.1.0, < 4.0.0) 94 | public_suffix (~> 2.0.0) 95 | rubyzip (>= 1.2.2, < 2.0.0) 96 | security (= 0.1.3) 97 | simctl (~> 1.6.3) 98 | slack-notifier (>= 2.0.0, < 3.0.0) 99 | terminal-notifier (>= 1.6.2, < 2.0.0) 100 | terminal-table (>= 1.4.5, < 2.0.0) 101 | tty-screen (>= 0.6.3, < 1.0.0) 102 | tty-spinner (>= 0.8.0, < 1.0.0) 103 | word_wrap (~> 1.0.0) 104 | xcodeproj (>= 1.6.0, < 2.0.0) 105 | xcpretty (~> 0.3.0) 106 | xcpretty-travis-formatter (>= 0.0.3) 107 | fourflusher (2.0.1) 108 | fuzzy_match (2.0.4) 109 | gh_inspector (1.1.3) 110 | google-api-client (0.23.9) 111 | addressable (~> 2.5, >= 2.5.1) 112 | googleauth (>= 0.5, < 0.7.0) 113 | httpclient (>= 2.8.1, < 3.0) 114 | mime-types (~> 3.0) 115 | representable (~> 3.0) 116 | retriable (>= 2.0, < 4.0) 117 | signet (~> 0.9) 118 | google-cloud-core (1.2.7) 119 | google-cloud-env (~> 1.0) 120 | google-cloud-env (1.0.5) 121 | faraday (~> 0.11) 122 | google-cloud-storage (1.15.0) 123 | digest-crc (~> 0.4) 124 | google-api-client (~> 0.23) 125 | google-cloud-core (~> 1.2) 126 | googleauth (~> 0.6.2) 127 | googleauth (0.6.7) 128 | faraday (~> 0.12) 129 | jwt (>= 1.4, < 3.0) 130 | memoist (~> 0.16) 131 | multi_json (~> 1.11) 132 | os (>= 0.9, < 2.0) 133 | signet (~> 0.7) 134 | highline (1.7.10) 135 | http-cookie (1.0.3) 136 | domain_name (~> 0.5) 137 | httpclient (2.8.3) 138 | i18n (0.9.5) 139 | concurrent-ruby (~> 1.0) 140 | json (2.1.0) 141 | jwt (2.1.0) 142 | memoist (0.16.0) 143 | mime-types (3.2.2) 144 | mime-types-data (~> 3.2015) 145 | mime-types-data (3.2018.0812) 146 | mini_magick (4.5.1) 147 | minitest (5.11.3) 148 | molinillo (0.6.6) 149 | multi_json (1.13.1) 150 | multi_xml (0.6.0) 151 | multipart-post (2.0.0) 152 | nanaimo (0.2.6) 153 | nap (1.1.0) 154 | naturally (2.2.0) 155 | netrc (0.11.0) 156 | os (1.0.0) 157 | plist (3.5.0) 158 | public_suffix (2.0.5) 159 | representable (3.0.4) 160 | declarative (< 0.1.0) 161 | declarative-option (< 0.2.0) 162 | uber (< 0.2.0) 163 | retriable (3.1.2) 164 | rouge (2.0.7) 165 | ruby-macho (1.3.1) 166 | rubyzip (1.2.2) 167 | security (0.1.3) 168 | signet (0.11.0) 169 | addressable (~> 2.3) 170 | faraday (~> 0.9) 171 | jwt (>= 1.5, < 3.0) 172 | multi_json (~> 1.10) 173 | simctl (1.6.5) 174 | CFPropertyList 175 | naturally 176 | slack-notifier (2.3.2) 177 | terminal-notifier (1.8.0) 178 | terminal-table (1.8.0) 179 | unicode-display_width (~> 1.1, >= 1.1.1) 180 | thread_safe (0.3.6) 181 | tty-cursor (0.6.0) 182 | tty-screen (0.6.5) 183 | tty-spinner (0.9.0) 184 | tty-cursor (~> 0.6.0) 185 | tzinfo (1.2.5) 186 | thread_safe (~> 0.1) 187 | uber (0.1.0) 188 | unf (0.1.4) 189 | unf_ext 190 | unf_ext (0.0.7.5) 191 | unicode-display_width (1.4.1) 192 | word_wrap (1.0.0) 193 | xcodeproj (1.7.0) 194 | CFPropertyList (>= 2.3.3, < 4.0) 195 | atomos (~> 0.1.3) 196 | claide (>= 1.0.2, < 2.0) 197 | colored2 (~> 3.1) 198 | nanaimo (~> 0.2.6) 199 | xcpretty (0.3.0) 200 | rouge (~> 2.0.7) 201 | xcpretty-travis-formatter (1.0.0) 202 | xcpretty (~> 0.2, >= 0.0.7) 203 | 204 | PLATFORMS 205 | ruby 206 | 207 | DEPENDENCIES 208 | cocoapods (~> 1.6.0.beta.2) 209 | fastlane 210 | 211 | BUNDLED WITH 212 | 1.16.6 213 | -------------------------------------------------------------------------------- /versions/1.2/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.1) 5 | activesupport (4.2.11.1) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.7.0) 11 | public_suffix (>= 2.0.2, < 5.0) 12 | atomos (0.1.3) 13 | babosa (1.0.2) 14 | claide (1.0.3) 15 | cocoapods (1.7.5) 16 | activesupport (>= 4.0.2, < 5) 17 | claide (>= 1.0.2, < 2.0) 18 | cocoapods-core (= 1.7.5) 19 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 20 | cocoapods-downloader (>= 1.2.2, < 2.0) 21 | cocoapods-plugins (>= 1.0.0, < 2.0) 22 | cocoapods-search (>= 1.0.0, < 2.0) 23 | cocoapods-stats (>= 1.0.0, < 2.0) 24 | cocoapods-trunk (>= 1.3.1, < 2.0) 25 | cocoapods-try (>= 1.1.0, < 2.0) 26 | colored2 (~> 3.1) 27 | escape (~> 0.0.4) 28 | fourflusher (>= 2.3.0, < 3.0) 29 | gh_inspector (~> 1.0) 30 | molinillo (~> 0.6.6) 31 | nap (~> 1.0) 32 | ruby-macho (~> 1.4) 33 | xcodeproj (>= 1.10.0, < 2.0) 34 | cocoapods-core (1.7.5) 35 | activesupport (>= 4.0.2, < 6) 36 | fuzzy_match (~> 2.0.4) 37 | nap (~> 1.0) 38 | cocoapods-deintegrate (1.0.4) 39 | cocoapods-downloader (1.2.2) 40 | cocoapods-plugins (1.0.0) 41 | nap 42 | cocoapods-search (1.0.0) 43 | cocoapods-stats (1.1.0) 44 | cocoapods-trunk (1.4.0) 45 | nap (>= 0.8, < 2.0) 46 | netrc (~> 0.11) 47 | cocoapods-try (1.1.0) 48 | colored (1.2) 49 | colored2 (3.1.2) 50 | commander-fastlane (4.4.6) 51 | highline (~> 1.7.2) 52 | concurrent-ruby (1.1.5) 53 | declarative (0.0.10) 54 | declarative-option (0.1.0) 55 | digest-crc (0.4.1) 56 | domain_name (0.5.20190701) 57 | unf (>= 0.0.5, < 1.0.0) 58 | dotenv (2.7.5) 59 | emoji_regex (1.0.1) 60 | escape (0.0.4) 61 | excon (0.66.0) 62 | faraday (0.15.4) 63 | multipart-post (>= 1.2, < 3) 64 | faraday-cookie_jar (0.0.6) 65 | faraday (>= 0.7.4) 66 | http-cookie (~> 1.0.0) 67 | faraday_middleware (0.13.1) 68 | faraday (>= 0.7.4, < 1.0) 69 | fastimage (2.1.7) 70 | fastlane (2.130.0) 71 | CFPropertyList (>= 2.3, < 4.0.0) 72 | addressable (>= 2.3, < 3.0.0) 73 | babosa (>= 1.0.2, < 2.0.0) 74 | bundler (>= 1.12.0, < 3.0.0) 75 | colored 76 | commander-fastlane (>= 4.4.6, < 5.0.0) 77 | dotenv (>= 2.1.1, < 3.0.0) 78 | emoji_regex (>= 0.1, < 2.0) 79 | excon (>= 0.45.0, < 1.0.0) 80 | faraday (~> 0.9) 81 | faraday-cookie_jar (~> 0.0.6) 82 | faraday_middleware (~> 0.9) 83 | fastimage (>= 2.1.0, < 3.0.0) 84 | gh_inspector (>= 1.1.2, < 2.0.0) 85 | google-api-client (>= 0.21.2, < 0.24.0) 86 | google-cloud-storage (>= 1.15.0, < 2.0.0) 87 | highline (>= 1.7.2, < 2.0.0) 88 | json (< 3.0.0) 89 | jwt (~> 2.1.0) 90 | mini_magick (>= 4.9.4, < 5.0.0) 91 | multi_xml (~> 0.5) 92 | multipart-post (~> 2.0.0) 93 | plist (>= 3.1.0, < 4.0.0) 94 | public_suffix (~> 2.0.0) 95 | rubyzip (>= 1.2.2, < 2.0.0) 96 | security (= 0.1.3) 97 | simctl (~> 1.6.3) 98 | slack-notifier (>= 2.0.0, < 3.0.0) 99 | terminal-notifier (>= 2.0.0, < 3.0.0) 100 | terminal-table (>= 1.4.5, < 2.0.0) 101 | tty-screen (>= 0.6.3, < 1.0.0) 102 | tty-spinner (>= 0.8.0, < 1.0.0) 103 | word_wrap (~> 1.0.0) 104 | xcodeproj (>= 1.8.1, < 2.0.0) 105 | xcpretty (~> 0.3.0) 106 | xcpretty-travis-formatter (>= 0.0.3) 107 | fourflusher (2.3.1) 108 | fuzzy_match (2.0.4) 109 | gh_inspector (1.1.3) 110 | google-api-client (0.23.9) 111 | addressable (~> 2.5, >= 2.5.1) 112 | googleauth (>= 0.5, < 0.7.0) 113 | httpclient (>= 2.8.1, < 3.0) 114 | mime-types (~> 3.0) 115 | representable (~> 3.0) 116 | retriable (>= 2.0, < 4.0) 117 | signet (~> 0.9) 118 | google-cloud-core (1.3.1) 119 | google-cloud-env (~> 1.0) 120 | google-cloud-env (1.2.1) 121 | faraday (~> 0.11) 122 | google-cloud-storage (1.16.0) 123 | digest-crc (~> 0.4) 124 | google-api-client (~> 0.23) 125 | google-cloud-core (~> 1.2) 126 | googleauth (>= 0.6.2, < 0.10.0) 127 | googleauth (0.6.7) 128 | faraday (~> 0.12) 129 | jwt (>= 1.4, < 3.0) 130 | memoist (~> 0.16) 131 | multi_json (~> 1.11) 132 | os (>= 0.9, < 2.0) 133 | signet (~> 0.7) 134 | highline (1.7.10) 135 | http-cookie (1.0.3) 136 | domain_name (~> 0.5) 137 | httparty (0.17.0) 138 | mime-types (~> 3.0) 139 | multi_xml (>= 0.5.2) 140 | httpclient (2.8.3) 141 | i18n (0.9.5) 142 | concurrent-ruby (~> 1.0) 143 | json (2.2.0) 144 | jwt (2.1.0) 145 | memoist (0.16.0) 146 | mime-types (3.3) 147 | mime-types-data (~> 3.2015) 148 | mime-types-data (3.2019.0904) 149 | mini_magick (4.9.5) 150 | minitest (5.11.3) 151 | molinillo (0.6.6) 152 | multi_json (1.13.1) 153 | multi_xml (0.6.0) 154 | multipart-post (2.0.0) 155 | nanaimo (0.2.6) 156 | nap (1.1.0) 157 | naturally (2.2.0) 158 | netrc (0.11.0) 159 | os (1.0.1) 160 | plist (3.5.0) 161 | public_suffix (2.0.5) 162 | representable (3.0.4) 163 | declarative (< 0.1.0) 164 | declarative-option (< 0.2.0) 165 | uber (< 0.2.0) 166 | retriable (3.1.2) 167 | rouge (2.0.7) 168 | ruby-macho (1.4.0) 169 | rubyzip (1.2.4) 170 | security (0.1.3) 171 | signet (0.11.0) 172 | addressable (~> 2.3) 173 | faraday (~> 0.9) 174 | jwt (>= 1.5, < 3.0) 175 | multi_json (~> 1.10) 176 | simctl (1.6.5) 177 | CFPropertyList 178 | naturally 179 | slack-notifier (2.3.2) 180 | terminal-notifier (2.0.0) 181 | terminal-table (1.8.0) 182 | unicode-display_width (~> 1.1, >= 1.1.1) 183 | thread_safe (0.3.6) 184 | tty-cursor (0.7.0) 185 | tty-screen (0.7.0) 186 | tty-spinner (0.9.1) 187 | tty-cursor (~> 0.7) 188 | tzinfo (1.2.5) 189 | thread_safe (~> 0.1) 190 | uber (0.1.0) 191 | unf (0.1.4) 192 | unf_ext 193 | unf_ext (0.0.7.6) 194 | unicode-display_width (1.6.0) 195 | word_wrap (1.0.0) 196 | xcodeproj (1.12.0) 197 | CFPropertyList (>= 2.3.3, < 4.0) 198 | atomos (~> 0.1.3) 199 | claide (>= 1.0.2, < 2.0) 200 | colored2 (~> 3.1) 201 | nanaimo (~> 0.2.6) 202 | xcpretty (0.3.0) 203 | rouge (~> 2.0.7) 204 | xcpretty-travis-formatter (1.0.0) 205 | xcpretty (~> 0.2, >= 0.0.7) 206 | 207 | PLATFORMS 208 | ruby 209 | 210 | DEPENDENCIES 211 | cocoapods 212 | fastlane 213 | httparty 214 | json 215 | rubyzip 216 | 217 | BUNDLED WITH 218 | 2.0.2 219 | -------------------------------------------------------------------------------- /versions/1.3/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.1) 5 | activesupport (4.2.11.1) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.7.0) 11 | public_suffix (>= 2.0.2, < 5.0) 12 | atomos (0.1.3) 13 | babosa (1.0.2) 14 | claide (1.0.3) 15 | cocoapods (1.7.5) 16 | activesupport (>= 4.0.2, < 5) 17 | claide (>= 1.0.2, < 2.0) 18 | cocoapods-core (= 1.7.5) 19 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 20 | cocoapods-downloader (>= 1.2.2, < 2.0) 21 | cocoapods-plugins (>= 1.0.0, < 2.0) 22 | cocoapods-search (>= 1.0.0, < 2.0) 23 | cocoapods-stats (>= 1.0.0, < 2.0) 24 | cocoapods-trunk (>= 1.3.1, < 2.0) 25 | cocoapods-try (>= 1.1.0, < 2.0) 26 | colored2 (~> 3.1) 27 | escape (~> 0.0.4) 28 | fourflusher (>= 2.3.0, < 3.0) 29 | gh_inspector (~> 1.0) 30 | molinillo (~> 0.6.6) 31 | nap (~> 1.0) 32 | ruby-macho (~> 1.4) 33 | xcodeproj (>= 1.10.0, < 2.0) 34 | cocoapods-core (1.7.5) 35 | activesupport (>= 4.0.2, < 6) 36 | fuzzy_match (~> 2.0.4) 37 | nap (~> 1.0) 38 | cocoapods-deintegrate (1.0.4) 39 | cocoapods-downloader (1.2.2) 40 | cocoapods-plugins (1.0.0) 41 | nap 42 | cocoapods-search (1.0.0) 43 | cocoapods-stats (1.1.0) 44 | cocoapods-trunk (1.4.0) 45 | nap (>= 0.8, < 2.0) 46 | netrc (~> 0.11) 47 | cocoapods-try (1.1.0) 48 | colored (1.2) 49 | colored2 (3.1.2) 50 | commander-fastlane (4.4.6) 51 | highline (~> 1.7.2) 52 | concurrent-ruby (1.1.5) 53 | declarative (0.0.10) 54 | declarative-option (0.1.0) 55 | digest-crc (0.4.1) 56 | domain_name (0.5.20190701) 57 | unf (>= 0.0.5, < 1.0.0) 58 | dotenv (2.7.5) 59 | emoji_regex (1.0.1) 60 | escape (0.0.4) 61 | excon (0.66.0) 62 | faraday (0.15.4) 63 | multipart-post (>= 1.2, < 3) 64 | faraday-cookie_jar (0.0.6) 65 | faraday (>= 0.7.4) 66 | http-cookie (~> 1.0.0) 67 | faraday_middleware (0.13.1) 68 | faraday (>= 0.7.4, < 1.0) 69 | fastimage (2.1.7) 70 | fastlane (2.130.0) 71 | CFPropertyList (>= 2.3, < 4.0.0) 72 | addressable (>= 2.3, < 3.0.0) 73 | babosa (>= 1.0.2, < 2.0.0) 74 | bundler (>= 1.12.0, < 3.0.0) 75 | colored 76 | commander-fastlane (>= 4.4.6, < 5.0.0) 77 | dotenv (>= 2.1.1, < 3.0.0) 78 | emoji_regex (>= 0.1, < 2.0) 79 | excon (>= 0.45.0, < 1.0.0) 80 | faraday (~> 0.9) 81 | faraday-cookie_jar (~> 0.0.6) 82 | faraday_middleware (~> 0.9) 83 | fastimage (>= 2.1.0, < 3.0.0) 84 | gh_inspector (>= 1.1.2, < 2.0.0) 85 | google-api-client (>= 0.21.2, < 0.24.0) 86 | google-cloud-storage (>= 1.15.0, < 2.0.0) 87 | highline (>= 1.7.2, < 2.0.0) 88 | json (< 3.0.0) 89 | jwt (~> 2.1.0) 90 | mini_magick (>= 4.9.4, < 5.0.0) 91 | multi_xml (~> 0.5) 92 | multipart-post (~> 2.0.0) 93 | plist (>= 3.1.0, < 4.0.0) 94 | public_suffix (~> 2.0.0) 95 | rubyzip (>= 1.2.2, < 2.0.0) 96 | security (= 0.1.3) 97 | simctl (~> 1.6.3) 98 | slack-notifier (>= 2.0.0, < 3.0.0) 99 | terminal-notifier (>= 2.0.0, < 3.0.0) 100 | terminal-table (>= 1.4.5, < 2.0.0) 101 | tty-screen (>= 0.6.3, < 1.0.0) 102 | tty-spinner (>= 0.8.0, < 1.0.0) 103 | word_wrap (~> 1.0.0) 104 | xcodeproj (>= 1.8.1, < 2.0.0) 105 | xcpretty (~> 0.3.0) 106 | xcpretty-travis-formatter (>= 0.0.3) 107 | fourflusher (2.3.1) 108 | fuzzy_match (2.0.4) 109 | gh_inspector (1.1.3) 110 | google-api-client (0.23.9) 111 | addressable (~> 2.5, >= 2.5.1) 112 | googleauth (>= 0.5, < 0.7.0) 113 | httpclient (>= 2.8.1, < 3.0) 114 | mime-types (~> 3.0) 115 | representable (~> 3.0) 116 | retriable (>= 2.0, < 4.0) 117 | signet (~> 0.9) 118 | google-cloud-core (1.3.1) 119 | google-cloud-env (~> 1.0) 120 | google-cloud-env (1.2.1) 121 | faraday (~> 0.11) 122 | google-cloud-storage (1.16.0) 123 | digest-crc (~> 0.4) 124 | google-api-client (~> 0.23) 125 | google-cloud-core (~> 1.2) 126 | googleauth (>= 0.6.2, < 0.10.0) 127 | googleauth (0.6.7) 128 | faraday (~> 0.12) 129 | jwt (>= 1.4, < 3.0) 130 | memoist (~> 0.16) 131 | multi_json (~> 1.11) 132 | os (>= 0.9, < 2.0) 133 | signet (~> 0.7) 134 | highline (1.7.10) 135 | http-cookie (1.0.3) 136 | domain_name (~> 0.5) 137 | httparty (0.17.0) 138 | mime-types (~> 3.0) 139 | multi_xml (>= 0.5.2) 140 | httpclient (2.8.3) 141 | i18n (0.9.5) 142 | concurrent-ruby (~> 1.0) 143 | json (2.2.0) 144 | jwt (2.1.0) 145 | memoist (0.16.0) 146 | mime-types (3.3) 147 | mime-types-data (~> 3.2015) 148 | mime-types-data (3.2019.0904) 149 | mini_magick (4.9.5) 150 | minitest (5.11.3) 151 | molinillo (0.6.6) 152 | multi_json (1.13.1) 153 | multi_xml (0.6.0) 154 | multipart-post (2.0.0) 155 | nanaimo (0.2.6) 156 | nap (1.1.0) 157 | naturally (2.2.0) 158 | netrc (0.11.0) 159 | os (1.0.1) 160 | plist (3.5.0) 161 | public_suffix (2.0.5) 162 | representable (3.0.4) 163 | declarative (< 0.1.0) 164 | declarative-option (< 0.2.0) 165 | uber (< 0.2.0) 166 | retriable (3.1.2) 167 | rouge (2.0.7) 168 | ruby-macho (1.4.0) 169 | rubyzip (1.2.4) 170 | security (0.1.3) 171 | signet (0.11.0) 172 | addressable (~> 2.3) 173 | faraday (~> 0.9) 174 | jwt (>= 1.5, < 3.0) 175 | multi_json (~> 1.10) 176 | simctl (1.6.5) 177 | CFPropertyList 178 | naturally 179 | slack-notifier (2.3.2) 180 | terminal-notifier (2.0.0) 181 | terminal-table (1.8.0) 182 | unicode-display_width (~> 1.1, >= 1.1.1) 183 | thread_safe (0.3.6) 184 | tty-cursor (0.7.0) 185 | tty-screen (0.7.0) 186 | tty-spinner (0.9.1) 187 | tty-cursor (~> 0.7) 188 | tzinfo (1.2.5) 189 | thread_safe (~> 0.1) 190 | uber (0.1.0) 191 | unf (0.1.4) 192 | unf_ext 193 | unf_ext (0.0.7.6) 194 | unicode-display_width (1.6.0) 195 | word_wrap (1.0.0) 196 | xcodeproj (1.12.0) 197 | CFPropertyList (>= 2.3.3, < 4.0) 198 | atomos (~> 0.1.3) 199 | claide (>= 1.0.2, < 2.0) 200 | colored2 (~> 3.1) 201 | nanaimo (~> 0.2.6) 202 | xcpretty (0.3.0) 203 | rouge (~> 2.0.7) 204 | xcpretty-travis-formatter (1.0.0) 205 | xcpretty (~> 0.2, >= 0.0.7) 206 | 207 | PLATFORMS 208 | ruby 209 | 210 | DEPENDENCIES 211 | cocoapods 212 | fastlane 213 | httparty 214 | json 215 | rubyzip 216 | 217 | BUNDLED WITH 218 | 2.0.2 219 | -------------------------------------------------------------------------------- /versions/1.4/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.1) 5 | activesupport (4.2.11.1) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.7.0) 11 | public_suffix (>= 2.0.2, < 5.0) 12 | atomos (0.1.3) 13 | babosa (1.0.2) 14 | claide (1.0.3) 15 | cocoapods (1.7.5) 16 | activesupport (>= 4.0.2, < 5) 17 | claide (>= 1.0.2, < 2.0) 18 | cocoapods-core (= 1.7.5) 19 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 20 | cocoapods-downloader (>= 1.2.2, < 2.0) 21 | cocoapods-plugins (>= 1.0.0, < 2.0) 22 | cocoapods-search (>= 1.0.0, < 2.0) 23 | cocoapods-stats (>= 1.0.0, < 2.0) 24 | cocoapods-trunk (>= 1.3.1, < 2.0) 25 | cocoapods-try (>= 1.1.0, < 2.0) 26 | colored2 (~> 3.1) 27 | escape (~> 0.0.4) 28 | fourflusher (>= 2.3.0, < 3.0) 29 | gh_inspector (~> 1.0) 30 | molinillo (~> 0.6.6) 31 | nap (~> 1.0) 32 | ruby-macho (~> 1.4) 33 | xcodeproj (>= 1.10.0, < 2.0) 34 | cocoapods-core (1.7.5) 35 | activesupport (>= 4.0.2, < 6) 36 | fuzzy_match (~> 2.0.4) 37 | nap (~> 1.0) 38 | cocoapods-deintegrate (1.0.4) 39 | cocoapods-downloader (1.2.2) 40 | cocoapods-plugins (1.0.0) 41 | nap 42 | cocoapods-search (1.0.0) 43 | cocoapods-stats (1.1.0) 44 | cocoapods-trunk (1.4.0) 45 | nap (>= 0.8, < 2.0) 46 | netrc (~> 0.11) 47 | cocoapods-try (1.1.0) 48 | colored (1.2) 49 | colored2 (3.1.2) 50 | commander-fastlane (4.4.6) 51 | highline (~> 1.7.2) 52 | concurrent-ruby (1.1.5) 53 | declarative (0.0.10) 54 | declarative-option (0.1.0) 55 | digest-crc (0.4.1) 56 | domain_name (0.5.20190701) 57 | unf (>= 0.0.5, < 1.0.0) 58 | dotenv (2.7.5) 59 | emoji_regex (1.0.1) 60 | escape (0.0.4) 61 | excon (0.66.0) 62 | faraday (0.15.4) 63 | multipart-post (>= 1.2, < 3) 64 | faraday-cookie_jar (0.0.6) 65 | faraday (>= 0.7.4) 66 | http-cookie (~> 1.0.0) 67 | faraday_middleware (0.13.1) 68 | faraday (>= 0.7.4, < 1.0) 69 | fastimage (2.1.7) 70 | fastlane (2.130.0) 71 | CFPropertyList (>= 2.3, < 4.0.0) 72 | addressable (>= 2.3, < 3.0.0) 73 | babosa (>= 1.0.2, < 2.0.0) 74 | bundler (>= 1.12.0, < 3.0.0) 75 | colored 76 | commander-fastlane (>= 4.4.6, < 5.0.0) 77 | dotenv (>= 2.1.1, < 3.0.0) 78 | emoji_regex (>= 0.1, < 2.0) 79 | excon (>= 0.45.0, < 1.0.0) 80 | faraday (~> 0.9) 81 | faraday-cookie_jar (~> 0.0.6) 82 | faraday_middleware (~> 0.9) 83 | fastimage (>= 2.1.0, < 3.0.0) 84 | gh_inspector (>= 1.1.2, < 2.0.0) 85 | google-api-client (>= 0.21.2, < 0.24.0) 86 | google-cloud-storage (>= 1.15.0, < 2.0.0) 87 | highline (>= 1.7.2, < 2.0.0) 88 | json (< 3.0.0) 89 | jwt (~> 2.1.0) 90 | mini_magick (>= 4.9.4, < 5.0.0) 91 | multi_xml (~> 0.5) 92 | multipart-post (~> 2.0.0) 93 | plist (>= 3.1.0, < 4.0.0) 94 | public_suffix (~> 2.0.0) 95 | rubyzip (>= 1.2.2, < 2.0.0) 96 | security (= 0.1.3) 97 | simctl (~> 1.6.3) 98 | slack-notifier (>= 2.0.0, < 3.0.0) 99 | terminal-notifier (>= 2.0.0, < 3.0.0) 100 | terminal-table (>= 1.4.5, < 2.0.0) 101 | tty-screen (>= 0.6.3, < 1.0.0) 102 | tty-spinner (>= 0.8.0, < 1.0.0) 103 | word_wrap (~> 1.0.0) 104 | xcodeproj (>= 1.8.1, < 2.0.0) 105 | xcpretty (~> 0.3.0) 106 | xcpretty-travis-formatter (>= 0.0.3) 107 | fourflusher (2.3.1) 108 | fuzzy_match (2.0.4) 109 | gh_inspector (1.1.3) 110 | google-api-client (0.23.9) 111 | addressable (~> 2.5, >= 2.5.1) 112 | googleauth (>= 0.5, < 0.7.0) 113 | httpclient (>= 2.8.1, < 3.0) 114 | mime-types (~> 3.0) 115 | representable (~> 3.0) 116 | retriable (>= 2.0, < 4.0) 117 | signet (~> 0.9) 118 | google-cloud-core (1.3.1) 119 | google-cloud-env (~> 1.0) 120 | google-cloud-env (1.2.1) 121 | faraday (~> 0.11) 122 | google-cloud-storage (1.16.0) 123 | digest-crc (~> 0.4) 124 | google-api-client (~> 0.23) 125 | google-cloud-core (~> 1.2) 126 | googleauth (>= 0.6.2, < 0.10.0) 127 | googleauth (0.6.7) 128 | faraday (~> 0.12) 129 | jwt (>= 1.4, < 3.0) 130 | memoist (~> 0.16) 131 | multi_json (~> 1.11) 132 | os (>= 0.9, < 2.0) 133 | signet (~> 0.7) 134 | highline (1.7.10) 135 | http-cookie (1.0.3) 136 | domain_name (~> 0.5) 137 | httparty (0.17.0) 138 | mime-types (~> 3.0) 139 | multi_xml (>= 0.5.2) 140 | httpclient (2.8.3) 141 | i18n (0.9.5) 142 | concurrent-ruby (~> 1.0) 143 | json (2.2.0) 144 | jwt (2.1.0) 145 | memoist (0.16.0) 146 | mime-types (3.3) 147 | mime-types-data (~> 3.2015) 148 | mime-types-data (3.2019.0904) 149 | mini_magick (4.9.5) 150 | minitest (5.11.3) 151 | molinillo (0.6.6) 152 | multi_json (1.13.1) 153 | multi_xml (0.6.0) 154 | multipart-post (2.0.0) 155 | nanaimo (0.2.6) 156 | nap (1.1.0) 157 | naturally (2.2.0) 158 | netrc (0.11.0) 159 | os (1.0.1) 160 | plist (3.5.0) 161 | public_suffix (2.0.5) 162 | representable (3.0.4) 163 | declarative (< 0.1.0) 164 | declarative-option (< 0.2.0) 165 | uber (< 0.2.0) 166 | retriable (3.1.2) 167 | rouge (2.0.7) 168 | ruby-macho (1.4.0) 169 | rubyzip (1.2.4) 170 | security (0.1.3) 171 | signet (0.11.0) 172 | addressable (~> 2.3) 173 | faraday (~> 0.9) 174 | jwt (>= 1.5, < 3.0) 175 | multi_json (~> 1.10) 176 | simctl (1.6.5) 177 | CFPropertyList 178 | naturally 179 | slack-notifier (2.3.2) 180 | terminal-notifier (2.0.0) 181 | terminal-table (1.8.0) 182 | unicode-display_width (~> 1.1, >= 1.1.1) 183 | thread_safe (0.3.6) 184 | tty-cursor (0.7.0) 185 | tty-screen (0.7.0) 186 | tty-spinner (0.9.1) 187 | tty-cursor (~> 0.7) 188 | tzinfo (1.2.5) 189 | thread_safe (~> 0.1) 190 | uber (0.1.0) 191 | unf (0.1.4) 192 | unf_ext 193 | unf_ext (0.0.7.6) 194 | unicode-display_width (1.6.0) 195 | word_wrap (1.0.0) 196 | xcodeproj (1.12.0) 197 | CFPropertyList (>= 2.3.3, < 4.0) 198 | atomos (~> 0.1.3) 199 | claide (>= 1.0.2, < 2.0) 200 | colored2 (~> 3.1) 201 | nanaimo (~> 0.2.6) 202 | xcpretty (0.3.0) 203 | rouge (~> 2.0.7) 204 | xcpretty-travis-formatter (1.0.0) 205 | xcpretty (~> 0.2, >= 0.0.7) 206 | 207 | PLATFORMS 208 | ruby 209 | 210 | DEPENDENCIES 211 | cocoapods 212 | fastlane 213 | httparty 214 | json 215 | rubyzip 216 | 217 | BUNDLED WITH 218 | 2.0.2 219 | -------------------------------------------------------------------------------- /versions/1.5/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.1) 5 | activesupport (4.2.11.1) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.7.0) 11 | public_suffix (>= 2.0.2, < 5.0) 12 | atomos (0.1.3) 13 | babosa (1.0.2) 14 | claide (1.0.3) 15 | cocoapods (1.7.5) 16 | activesupport (>= 4.0.2, < 5) 17 | claide (>= 1.0.2, < 2.0) 18 | cocoapods-core (= 1.7.5) 19 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 20 | cocoapods-downloader (>= 1.2.2, < 2.0) 21 | cocoapods-plugins (>= 1.0.0, < 2.0) 22 | cocoapods-search (>= 1.0.0, < 2.0) 23 | cocoapods-stats (>= 1.0.0, < 2.0) 24 | cocoapods-trunk (>= 1.3.1, < 2.0) 25 | cocoapods-try (>= 1.1.0, < 2.0) 26 | colored2 (~> 3.1) 27 | escape (~> 0.0.4) 28 | fourflusher (>= 2.3.0, < 3.0) 29 | gh_inspector (~> 1.0) 30 | molinillo (~> 0.6.6) 31 | nap (~> 1.0) 32 | ruby-macho (~> 1.4) 33 | xcodeproj (>= 1.10.0, < 2.0) 34 | cocoapods-core (1.7.5) 35 | activesupport (>= 4.0.2, < 6) 36 | fuzzy_match (~> 2.0.4) 37 | nap (~> 1.0) 38 | cocoapods-deintegrate (1.0.4) 39 | cocoapods-downloader (1.2.2) 40 | cocoapods-plugins (1.0.0) 41 | nap 42 | cocoapods-search (1.0.0) 43 | cocoapods-stats (1.1.0) 44 | cocoapods-trunk (1.4.0) 45 | nap (>= 0.8, < 2.0) 46 | netrc (~> 0.11) 47 | cocoapods-try (1.1.0) 48 | colored (1.2) 49 | colored2 (3.1.2) 50 | commander-fastlane (4.4.6) 51 | highline (~> 1.7.2) 52 | concurrent-ruby (1.1.5) 53 | declarative (0.0.10) 54 | declarative-option (0.1.0) 55 | digest-crc (0.4.1) 56 | domain_name (0.5.20190701) 57 | unf (>= 0.0.5, < 1.0.0) 58 | dotenv (2.7.5) 59 | emoji_regex (1.0.1) 60 | escape (0.0.4) 61 | excon (0.66.0) 62 | faraday (0.15.4) 63 | multipart-post (>= 1.2, < 3) 64 | faraday-cookie_jar (0.0.6) 65 | faraday (>= 0.7.4) 66 | http-cookie (~> 1.0.0) 67 | faraday_middleware (0.13.1) 68 | faraday (>= 0.7.4, < 1.0) 69 | fastimage (2.1.7) 70 | fastlane (2.130.0) 71 | CFPropertyList (>= 2.3, < 4.0.0) 72 | addressable (>= 2.3, < 3.0.0) 73 | babosa (>= 1.0.2, < 2.0.0) 74 | bundler (>= 1.12.0, < 3.0.0) 75 | colored 76 | commander-fastlane (>= 4.4.6, < 5.0.0) 77 | dotenv (>= 2.1.1, < 3.0.0) 78 | emoji_regex (>= 0.1, < 2.0) 79 | excon (>= 0.45.0, < 1.0.0) 80 | faraday (~> 0.9) 81 | faraday-cookie_jar (~> 0.0.6) 82 | faraday_middleware (~> 0.9) 83 | fastimage (>= 2.1.0, < 3.0.0) 84 | gh_inspector (>= 1.1.2, < 2.0.0) 85 | google-api-client (>= 0.21.2, < 0.24.0) 86 | google-cloud-storage (>= 1.15.0, < 2.0.0) 87 | highline (>= 1.7.2, < 2.0.0) 88 | json (< 3.0.0) 89 | jwt (~> 2.1.0) 90 | mini_magick (>= 4.9.4, < 5.0.0) 91 | multi_xml (~> 0.5) 92 | multipart-post (~> 2.0.0) 93 | plist (>= 3.1.0, < 4.0.0) 94 | public_suffix (~> 2.0.0) 95 | rubyzip (>= 1.2.2, < 2.0.0) 96 | security (= 0.1.3) 97 | simctl (~> 1.6.3) 98 | slack-notifier (>= 2.0.0, < 3.0.0) 99 | terminal-notifier (>= 2.0.0, < 3.0.0) 100 | terminal-table (>= 1.4.5, < 2.0.0) 101 | tty-screen (>= 0.6.3, < 1.0.0) 102 | tty-spinner (>= 0.8.0, < 1.0.0) 103 | word_wrap (~> 1.0.0) 104 | xcodeproj (>= 1.8.1, < 2.0.0) 105 | xcpretty (~> 0.3.0) 106 | xcpretty-travis-formatter (>= 0.0.3) 107 | fourflusher (2.3.1) 108 | fuzzy_match (2.0.4) 109 | gh_inspector (1.1.3) 110 | google-api-client (0.23.9) 111 | addressable (~> 2.5, >= 2.5.1) 112 | googleauth (>= 0.5, < 0.7.0) 113 | httpclient (>= 2.8.1, < 3.0) 114 | mime-types (~> 3.0) 115 | representable (~> 3.0) 116 | retriable (>= 2.0, < 4.0) 117 | signet (~> 0.9) 118 | google-cloud-core (1.3.1) 119 | google-cloud-env (~> 1.0) 120 | google-cloud-env (1.2.1) 121 | faraday (~> 0.11) 122 | google-cloud-storage (1.16.0) 123 | digest-crc (~> 0.4) 124 | google-api-client (~> 0.23) 125 | google-cloud-core (~> 1.2) 126 | googleauth (>= 0.6.2, < 0.10.0) 127 | googleauth (0.6.7) 128 | faraday (~> 0.12) 129 | jwt (>= 1.4, < 3.0) 130 | memoist (~> 0.16) 131 | multi_json (~> 1.11) 132 | os (>= 0.9, < 2.0) 133 | signet (~> 0.7) 134 | highline (1.7.10) 135 | http-cookie (1.0.3) 136 | domain_name (~> 0.5) 137 | httparty (0.17.0) 138 | mime-types (~> 3.0) 139 | multi_xml (>= 0.5.2) 140 | httpclient (2.8.3) 141 | i18n (0.9.5) 142 | concurrent-ruby (~> 1.0) 143 | json (2.2.0) 144 | jwt (2.1.0) 145 | memoist (0.16.0) 146 | mime-types (3.3) 147 | mime-types-data (~> 3.2015) 148 | mime-types-data (3.2019.0904) 149 | mini_magick (4.9.5) 150 | minitest (5.11.3) 151 | molinillo (0.6.6) 152 | multi_json (1.13.1) 153 | multi_xml (0.6.0) 154 | multipart-post (2.0.0) 155 | nanaimo (0.2.6) 156 | nap (1.1.0) 157 | naturally (2.2.0) 158 | netrc (0.11.0) 159 | os (1.0.1) 160 | plist (3.5.0) 161 | public_suffix (2.0.5) 162 | representable (3.0.4) 163 | declarative (< 0.1.0) 164 | declarative-option (< 0.2.0) 165 | uber (< 0.2.0) 166 | retriable (3.1.2) 167 | rouge (2.0.7) 168 | ruby-macho (1.4.0) 169 | rubyzip (1.2.4) 170 | security (0.1.3) 171 | signet (0.11.0) 172 | addressable (~> 2.3) 173 | faraday (~> 0.9) 174 | jwt (>= 1.5, < 3.0) 175 | multi_json (~> 1.10) 176 | simctl (1.6.5) 177 | CFPropertyList 178 | naturally 179 | slack-notifier (2.3.2) 180 | terminal-notifier (2.0.0) 181 | terminal-table (1.8.0) 182 | unicode-display_width (~> 1.1, >= 1.1.1) 183 | thread_safe (0.3.6) 184 | tty-cursor (0.7.0) 185 | tty-screen (0.7.0) 186 | tty-spinner (0.9.1) 187 | tty-cursor (~> 0.7) 188 | tzinfo (1.2.5) 189 | thread_safe (~> 0.1) 190 | uber (0.1.0) 191 | unf (0.1.4) 192 | unf_ext 193 | unf_ext (0.0.7.6) 194 | unicode-display_width (1.6.0) 195 | word_wrap (1.0.0) 196 | xcodeproj (1.12.0) 197 | CFPropertyList (>= 2.3.3, < 4.0) 198 | atomos (~> 0.1.3) 199 | claide (>= 1.0.2, < 2.0) 200 | colored2 (~> 3.1) 201 | nanaimo (~> 0.2.6) 202 | xcpretty (0.3.0) 203 | rouge (~> 2.0.7) 204 | xcpretty-travis-formatter (1.0.0) 205 | xcpretty (~> 0.2, >= 0.0.7) 206 | 207 | PLATFORMS 208 | ruby 209 | 210 | DEPENDENCIES 211 | cocoapods 212 | fastlane 213 | httparty 214 | json 215 | rubyzip 216 | 217 | BUNDLED WITH 218 | 2.0.2 219 | -------------------------------------------------------------------------------- /versions/2.0/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.1) 5 | activesupport (4.2.11.1) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.7.0) 11 | public_suffix (>= 2.0.2, < 5.0) 12 | atomos (0.1.3) 13 | babosa (1.0.2) 14 | claide (1.0.3) 15 | cocoapods (1.7.5) 16 | activesupport (>= 4.0.2, < 5) 17 | claide (>= 1.0.2, < 2.0) 18 | cocoapods-core (= 1.7.5) 19 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 20 | cocoapods-downloader (>= 1.2.2, < 2.0) 21 | cocoapods-plugins (>= 1.0.0, < 2.0) 22 | cocoapods-search (>= 1.0.0, < 2.0) 23 | cocoapods-stats (>= 1.0.0, < 2.0) 24 | cocoapods-trunk (>= 1.3.1, < 2.0) 25 | cocoapods-try (>= 1.1.0, < 2.0) 26 | colored2 (~> 3.1) 27 | escape (~> 0.0.4) 28 | fourflusher (>= 2.3.0, < 3.0) 29 | gh_inspector (~> 1.0) 30 | molinillo (~> 0.6.6) 31 | nap (~> 1.0) 32 | ruby-macho (~> 1.4) 33 | xcodeproj (>= 1.10.0, < 2.0) 34 | cocoapods-core (1.7.5) 35 | activesupport (>= 4.0.2, < 6) 36 | fuzzy_match (~> 2.0.4) 37 | nap (~> 1.0) 38 | cocoapods-deintegrate (1.0.4) 39 | cocoapods-downloader (1.2.2) 40 | cocoapods-plugins (1.0.0) 41 | nap 42 | cocoapods-search (1.0.0) 43 | cocoapods-stats (1.1.0) 44 | cocoapods-trunk (1.4.0) 45 | nap (>= 0.8, < 2.0) 46 | netrc (~> 0.11) 47 | cocoapods-try (1.1.0) 48 | colored (1.2) 49 | colored2 (3.1.2) 50 | commander-fastlane (4.4.6) 51 | highline (~> 1.7.2) 52 | concurrent-ruby (1.1.5) 53 | declarative (0.0.10) 54 | declarative-option (0.1.0) 55 | digest-crc (0.4.1) 56 | domain_name (0.5.20190701) 57 | unf (>= 0.0.5, < 1.0.0) 58 | dotenv (2.7.5) 59 | emoji_regex (1.0.1) 60 | escape (0.0.4) 61 | excon (0.66.0) 62 | faraday (0.15.4) 63 | multipart-post (>= 1.2, < 3) 64 | faraday-cookie_jar (0.0.6) 65 | faraday (>= 0.7.4) 66 | http-cookie (~> 1.0.0) 67 | faraday_middleware (0.13.1) 68 | faraday (>= 0.7.4, < 1.0) 69 | fastimage (2.1.7) 70 | fastlane (2.130.0) 71 | CFPropertyList (>= 2.3, < 4.0.0) 72 | addressable (>= 2.3, < 3.0.0) 73 | babosa (>= 1.0.2, < 2.0.0) 74 | bundler (>= 1.12.0, < 3.0.0) 75 | colored 76 | commander-fastlane (>= 4.4.6, < 5.0.0) 77 | dotenv (>= 2.1.1, < 3.0.0) 78 | emoji_regex (>= 0.1, < 2.0) 79 | excon (>= 0.45.0, < 1.0.0) 80 | faraday (~> 0.9) 81 | faraday-cookie_jar (~> 0.0.6) 82 | faraday_middleware (~> 0.9) 83 | fastimage (>= 2.1.0, < 3.0.0) 84 | gh_inspector (>= 1.1.2, < 2.0.0) 85 | google-api-client (>= 0.21.2, < 0.24.0) 86 | google-cloud-storage (>= 1.15.0, < 2.0.0) 87 | highline (>= 1.7.2, < 2.0.0) 88 | json (< 3.0.0) 89 | jwt (~> 2.1.0) 90 | mini_magick (>= 4.9.4, < 5.0.0) 91 | multi_xml (~> 0.5) 92 | multipart-post (~> 2.0.0) 93 | plist (>= 3.1.0, < 4.0.0) 94 | public_suffix (~> 2.0.0) 95 | rubyzip (>= 1.2.2, < 2.0.0) 96 | security (= 0.1.3) 97 | simctl (~> 1.6.3) 98 | slack-notifier (>= 2.0.0, < 3.0.0) 99 | terminal-notifier (>= 2.0.0, < 3.0.0) 100 | terminal-table (>= 1.4.5, < 2.0.0) 101 | tty-screen (>= 0.6.3, < 1.0.0) 102 | tty-spinner (>= 0.8.0, < 1.0.0) 103 | word_wrap (~> 1.0.0) 104 | xcodeproj (>= 1.8.1, < 2.0.0) 105 | xcpretty (~> 0.3.0) 106 | xcpretty-travis-formatter (>= 0.0.3) 107 | fourflusher (2.3.1) 108 | fuzzy_match (2.0.4) 109 | gh_inspector (1.1.3) 110 | google-api-client (0.23.9) 111 | addressable (~> 2.5, >= 2.5.1) 112 | googleauth (>= 0.5, < 0.7.0) 113 | httpclient (>= 2.8.1, < 3.0) 114 | mime-types (~> 3.0) 115 | representable (~> 3.0) 116 | retriable (>= 2.0, < 4.0) 117 | signet (~> 0.9) 118 | google-cloud-core (1.3.1) 119 | google-cloud-env (~> 1.0) 120 | google-cloud-env (1.2.1) 121 | faraday (~> 0.11) 122 | google-cloud-storage (1.16.0) 123 | digest-crc (~> 0.4) 124 | google-api-client (~> 0.23) 125 | google-cloud-core (~> 1.2) 126 | googleauth (>= 0.6.2, < 0.10.0) 127 | googleauth (0.6.7) 128 | faraday (~> 0.12) 129 | jwt (>= 1.4, < 3.0) 130 | memoist (~> 0.16) 131 | multi_json (~> 1.11) 132 | os (>= 0.9, < 2.0) 133 | signet (~> 0.7) 134 | highline (1.7.10) 135 | http-cookie (1.0.3) 136 | domain_name (~> 0.5) 137 | httparty (0.17.0) 138 | mime-types (~> 3.0) 139 | multi_xml (>= 0.5.2) 140 | httpclient (2.8.3) 141 | i18n (0.9.5) 142 | concurrent-ruby (~> 1.0) 143 | json (2.2.0) 144 | jwt (2.1.0) 145 | memoist (0.16.0) 146 | mime-types (3.3) 147 | mime-types-data (~> 3.2015) 148 | mime-types-data (3.2019.0904) 149 | mini_magick (4.9.5) 150 | minitest (5.11.3) 151 | molinillo (0.6.6) 152 | multi_json (1.13.1) 153 | multi_xml (0.6.0) 154 | multipart-post (2.0.0) 155 | nanaimo (0.2.6) 156 | nap (1.1.0) 157 | naturally (2.2.0) 158 | netrc (0.11.0) 159 | os (1.0.1) 160 | plist (3.5.0) 161 | public_suffix (2.0.5) 162 | representable (3.0.4) 163 | declarative (< 0.1.0) 164 | declarative-option (< 0.2.0) 165 | uber (< 0.2.0) 166 | retriable (3.1.2) 167 | rouge (2.0.7) 168 | ruby-macho (1.4.0) 169 | rubyzip (1.2.4) 170 | security (0.1.3) 171 | signet (0.11.0) 172 | addressable (~> 2.3) 173 | faraday (~> 0.9) 174 | jwt (>= 1.5, < 3.0) 175 | multi_json (~> 1.10) 176 | simctl (1.6.5) 177 | CFPropertyList 178 | naturally 179 | slack-notifier (2.3.2) 180 | terminal-notifier (2.0.0) 181 | terminal-table (1.8.0) 182 | unicode-display_width (~> 1.1, >= 1.1.1) 183 | thread_safe (0.3.6) 184 | tty-cursor (0.7.0) 185 | tty-screen (0.7.0) 186 | tty-spinner (0.9.1) 187 | tty-cursor (~> 0.7) 188 | tzinfo (1.2.5) 189 | thread_safe (~> 0.1) 190 | uber (0.1.0) 191 | unf (0.1.4) 192 | unf_ext 193 | unf_ext (0.0.7.6) 194 | unicode-display_width (1.6.0) 195 | word_wrap (1.0.0) 196 | xcodeproj (1.12.0) 197 | CFPropertyList (>= 2.3.3, < 4.0) 198 | atomos (~> 0.1.3) 199 | claide (>= 1.0.2, < 2.0) 200 | colored2 (~> 3.1) 201 | nanaimo (~> 0.2.6) 202 | xcpretty (0.3.0) 203 | rouge (~> 2.0.7) 204 | xcpretty-travis-formatter (1.0.0) 205 | xcpretty (~> 0.2, >= 0.0.7) 206 | 207 | PLATFORMS 208 | ruby 209 | 210 | DEPENDENCIES 211 | cocoapods 212 | fastlane 213 | httparty 214 | json 215 | rubyzip 216 | 217 | BUNDLED WITH 218 | 2.0.2 219 | -------------------------------------------------------------------------------- /versions/2.1/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.1) 5 | activesupport (4.2.11.1) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.7.0) 11 | public_suffix (>= 2.0.2, < 5.0) 12 | atomos (0.1.3) 13 | babosa (1.0.2) 14 | claide (1.0.3) 15 | cocoapods (1.7.5) 16 | activesupport (>= 4.0.2, < 5) 17 | claide (>= 1.0.2, < 2.0) 18 | cocoapods-core (= 1.7.5) 19 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 20 | cocoapods-downloader (>= 1.2.2, < 2.0) 21 | cocoapods-plugins (>= 1.0.0, < 2.0) 22 | cocoapods-search (>= 1.0.0, < 2.0) 23 | cocoapods-stats (>= 1.0.0, < 2.0) 24 | cocoapods-trunk (>= 1.3.1, < 2.0) 25 | cocoapods-try (>= 1.1.0, < 2.0) 26 | colored2 (~> 3.1) 27 | escape (~> 0.0.4) 28 | fourflusher (>= 2.3.0, < 3.0) 29 | gh_inspector (~> 1.0) 30 | molinillo (~> 0.6.6) 31 | nap (~> 1.0) 32 | ruby-macho (~> 1.4) 33 | xcodeproj (>= 1.10.0, < 2.0) 34 | cocoapods-core (1.7.5) 35 | activesupport (>= 4.0.2, < 6) 36 | fuzzy_match (~> 2.0.4) 37 | nap (~> 1.0) 38 | cocoapods-deintegrate (1.0.4) 39 | cocoapods-downloader (1.2.2) 40 | cocoapods-plugins (1.0.0) 41 | nap 42 | cocoapods-search (1.0.0) 43 | cocoapods-stats (1.1.0) 44 | cocoapods-trunk (1.4.0) 45 | nap (>= 0.8, < 2.0) 46 | netrc (~> 0.11) 47 | cocoapods-try (1.1.0) 48 | colored (1.2) 49 | colored2 (3.1.2) 50 | commander-fastlane (4.4.6) 51 | highline (~> 1.7.2) 52 | concurrent-ruby (1.1.5) 53 | declarative (0.0.10) 54 | declarative-option (0.1.0) 55 | digest-crc (0.4.1) 56 | domain_name (0.5.20190701) 57 | unf (>= 0.0.5, < 1.0.0) 58 | dotenv (2.7.5) 59 | emoji_regex (1.0.1) 60 | escape (0.0.4) 61 | excon (0.66.0) 62 | faraday (0.15.4) 63 | multipart-post (>= 1.2, < 3) 64 | faraday-cookie_jar (0.0.6) 65 | faraday (>= 0.7.4) 66 | http-cookie (~> 1.0.0) 67 | faraday_middleware (0.13.1) 68 | faraday (>= 0.7.4, < 1.0) 69 | fastimage (2.1.7) 70 | fastlane (2.130.0) 71 | CFPropertyList (>= 2.3, < 4.0.0) 72 | addressable (>= 2.3, < 3.0.0) 73 | babosa (>= 1.0.2, < 2.0.0) 74 | bundler (>= 1.12.0, < 3.0.0) 75 | colored 76 | commander-fastlane (>= 4.4.6, < 5.0.0) 77 | dotenv (>= 2.1.1, < 3.0.0) 78 | emoji_regex (>= 0.1, < 2.0) 79 | excon (>= 0.45.0, < 1.0.0) 80 | faraday (~> 0.9) 81 | faraday-cookie_jar (~> 0.0.6) 82 | faraday_middleware (~> 0.9) 83 | fastimage (>= 2.1.0, < 3.0.0) 84 | gh_inspector (>= 1.1.2, < 2.0.0) 85 | google-api-client (>= 0.21.2, < 0.24.0) 86 | google-cloud-storage (>= 1.15.0, < 2.0.0) 87 | highline (>= 1.7.2, < 2.0.0) 88 | json (< 3.0.0) 89 | jwt (~> 2.1.0) 90 | mini_magick (>= 4.9.4, < 5.0.0) 91 | multi_xml (~> 0.5) 92 | multipart-post (~> 2.0.0) 93 | plist (>= 3.1.0, < 4.0.0) 94 | public_suffix (~> 2.0.0) 95 | rubyzip (>= 1.2.2, < 2.0.0) 96 | security (= 0.1.3) 97 | simctl (~> 1.6.3) 98 | slack-notifier (>= 2.0.0, < 3.0.0) 99 | terminal-notifier (>= 2.0.0, < 3.0.0) 100 | terminal-table (>= 1.4.5, < 2.0.0) 101 | tty-screen (>= 0.6.3, < 1.0.0) 102 | tty-spinner (>= 0.8.0, < 1.0.0) 103 | word_wrap (~> 1.0.0) 104 | xcodeproj (>= 1.8.1, < 2.0.0) 105 | xcpretty (~> 0.3.0) 106 | xcpretty-travis-formatter (>= 0.0.3) 107 | fourflusher (2.3.1) 108 | fuzzy_match (2.0.4) 109 | gh_inspector (1.1.3) 110 | google-api-client (0.23.9) 111 | addressable (~> 2.5, >= 2.5.1) 112 | googleauth (>= 0.5, < 0.7.0) 113 | httpclient (>= 2.8.1, < 3.0) 114 | mime-types (~> 3.0) 115 | representable (~> 3.0) 116 | retriable (>= 2.0, < 4.0) 117 | signet (~> 0.9) 118 | google-cloud-core (1.3.1) 119 | google-cloud-env (~> 1.0) 120 | google-cloud-env (1.2.1) 121 | faraday (~> 0.11) 122 | google-cloud-storage (1.16.0) 123 | digest-crc (~> 0.4) 124 | google-api-client (~> 0.23) 125 | google-cloud-core (~> 1.2) 126 | googleauth (>= 0.6.2, < 0.10.0) 127 | googleauth (0.6.7) 128 | faraday (~> 0.12) 129 | jwt (>= 1.4, < 3.0) 130 | memoist (~> 0.16) 131 | multi_json (~> 1.11) 132 | os (>= 0.9, < 2.0) 133 | signet (~> 0.7) 134 | highline (1.7.10) 135 | http-cookie (1.0.3) 136 | domain_name (~> 0.5) 137 | httparty (0.17.0) 138 | mime-types (~> 3.0) 139 | multi_xml (>= 0.5.2) 140 | httpclient (2.8.3) 141 | i18n (0.9.5) 142 | concurrent-ruby (~> 1.0) 143 | json (2.2.0) 144 | jwt (2.1.0) 145 | memoist (0.16.0) 146 | mime-types (3.3) 147 | mime-types-data (~> 3.2015) 148 | mime-types-data (3.2019.0904) 149 | mini_magick (4.9.5) 150 | minitest (5.11.3) 151 | molinillo (0.6.6) 152 | multi_json (1.13.1) 153 | multi_xml (0.6.0) 154 | multipart-post (2.0.0) 155 | nanaimo (0.2.6) 156 | nap (1.1.0) 157 | naturally (2.2.0) 158 | netrc (0.11.0) 159 | os (1.0.1) 160 | plist (3.5.0) 161 | public_suffix (2.0.5) 162 | representable (3.0.4) 163 | declarative (< 0.1.0) 164 | declarative-option (< 0.2.0) 165 | uber (< 0.2.0) 166 | retriable (3.1.2) 167 | rouge (2.0.7) 168 | ruby-macho (1.4.0) 169 | rubyzip (1.2.4) 170 | security (0.1.3) 171 | signet (0.11.0) 172 | addressable (~> 2.3) 173 | faraday (~> 0.9) 174 | jwt (>= 1.5, < 3.0) 175 | multi_json (~> 1.10) 176 | simctl (1.6.5) 177 | CFPropertyList 178 | naturally 179 | slack-notifier (2.3.2) 180 | terminal-notifier (2.0.0) 181 | terminal-table (1.8.0) 182 | unicode-display_width (~> 1.1, >= 1.1.1) 183 | thread_safe (0.3.6) 184 | tty-cursor (0.7.0) 185 | tty-screen (0.7.0) 186 | tty-spinner (0.9.1) 187 | tty-cursor (~> 0.7) 188 | tzinfo (1.2.5) 189 | thread_safe (~> 0.1) 190 | uber (0.1.0) 191 | unf (0.1.4) 192 | unf_ext 193 | unf_ext (0.0.7.6) 194 | unicode-display_width (1.6.0) 195 | word_wrap (1.0.0) 196 | xcodeproj (1.12.0) 197 | CFPropertyList (>= 2.3.3, < 4.0) 198 | atomos (~> 0.1.3) 199 | claide (>= 1.0.2, < 2.0) 200 | colored2 (~> 3.1) 201 | nanaimo (~> 0.2.6) 202 | xcpretty (0.3.0) 203 | rouge (~> 2.0.7) 204 | xcpretty-travis-formatter (1.0.0) 205 | xcpretty (~> 0.2, >= 0.0.7) 206 | 207 | PLATFORMS 208 | ruby 209 | 210 | DEPENDENCIES 211 | cocoapods 212 | fastlane 213 | httparty 214 | json 215 | rubyzip 216 | 217 | BUNDLED WITH 218 | 2.0.2 219 | -------------------------------------------------------------------------------- /versions/development/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.1) 5 | activesupport (4.2.11.1) 6 | i18n (~> 0.7) 7 | minitest (~> 5.1) 8 | thread_safe (~> 0.3, >= 0.3.4) 9 | tzinfo (~> 1.1) 10 | addressable (2.7.0) 11 | public_suffix (>= 2.0.2, < 5.0) 12 | atomos (0.1.3) 13 | babosa (1.0.2) 14 | claide (1.0.3) 15 | cocoapods (1.7.5) 16 | activesupport (>= 4.0.2, < 5) 17 | claide (>= 1.0.2, < 2.0) 18 | cocoapods-core (= 1.7.5) 19 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 20 | cocoapods-downloader (>= 1.2.2, < 2.0) 21 | cocoapods-plugins (>= 1.0.0, < 2.0) 22 | cocoapods-search (>= 1.0.0, < 2.0) 23 | cocoapods-stats (>= 1.0.0, < 2.0) 24 | cocoapods-trunk (>= 1.3.1, < 2.0) 25 | cocoapods-try (>= 1.1.0, < 2.0) 26 | colored2 (~> 3.1) 27 | escape (~> 0.0.4) 28 | fourflusher (>= 2.3.0, < 3.0) 29 | gh_inspector (~> 1.0) 30 | molinillo (~> 0.6.6) 31 | nap (~> 1.0) 32 | ruby-macho (~> 1.4) 33 | xcodeproj (>= 1.10.0, < 2.0) 34 | cocoapods-core (1.7.5) 35 | activesupport (>= 4.0.2, < 6) 36 | fuzzy_match (~> 2.0.4) 37 | nap (~> 1.0) 38 | cocoapods-deintegrate (1.0.4) 39 | cocoapods-downloader (1.2.2) 40 | cocoapods-plugins (1.0.0) 41 | nap 42 | cocoapods-search (1.0.0) 43 | cocoapods-stats (1.1.0) 44 | cocoapods-trunk (1.4.0) 45 | nap (>= 0.8, < 2.0) 46 | netrc (~> 0.11) 47 | cocoapods-try (1.1.0) 48 | colored (1.2) 49 | colored2 (3.1.2) 50 | commander-fastlane (4.4.6) 51 | highline (~> 1.7.2) 52 | concurrent-ruby (1.1.5) 53 | declarative (0.0.10) 54 | declarative-option (0.1.0) 55 | digest-crc (0.4.1) 56 | domain_name (0.5.20190701) 57 | unf (>= 0.0.5, < 1.0.0) 58 | dotenv (2.7.5) 59 | emoji_regex (1.0.1) 60 | escape (0.0.4) 61 | excon (0.66.0) 62 | faraday (0.15.4) 63 | multipart-post (>= 1.2, < 3) 64 | faraday-cookie_jar (0.0.6) 65 | faraday (>= 0.7.4) 66 | http-cookie (~> 1.0.0) 67 | faraday_middleware (0.13.1) 68 | faraday (>= 0.7.4, < 1.0) 69 | fastimage (2.1.7) 70 | fastlane (2.130.0) 71 | CFPropertyList (>= 2.3, < 4.0.0) 72 | addressable (>= 2.3, < 3.0.0) 73 | babosa (>= 1.0.2, < 2.0.0) 74 | bundler (>= 1.12.0, < 3.0.0) 75 | colored 76 | commander-fastlane (>= 4.4.6, < 5.0.0) 77 | dotenv (>= 2.1.1, < 3.0.0) 78 | emoji_regex (>= 0.1, < 2.0) 79 | excon (>= 0.45.0, < 1.0.0) 80 | faraday (~> 0.9) 81 | faraday-cookie_jar (~> 0.0.6) 82 | faraday_middleware (~> 0.9) 83 | fastimage (>= 2.1.0, < 3.0.0) 84 | gh_inspector (>= 1.1.2, < 2.0.0) 85 | google-api-client (>= 0.21.2, < 0.24.0) 86 | google-cloud-storage (>= 1.15.0, < 2.0.0) 87 | highline (>= 1.7.2, < 2.0.0) 88 | json (< 3.0.0) 89 | jwt (~> 2.1.0) 90 | mini_magick (>= 4.9.4, < 5.0.0) 91 | multi_xml (~> 0.5) 92 | multipart-post (~> 2.0.0) 93 | plist (>= 3.1.0, < 4.0.0) 94 | public_suffix (~> 2.0.0) 95 | rubyzip (>= 1.2.2, < 2.0.0) 96 | security (= 0.1.3) 97 | simctl (~> 1.6.3) 98 | slack-notifier (>= 2.0.0, < 3.0.0) 99 | terminal-notifier (>= 2.0.0, < 3.0.0) 100 | terminal-table (>= 1.4.5, < 2.0.0) 101 | tty-screen (>= 0.6.3, < 1.0.0) 102 | tty-spinner (>= 0.8.0, < 1.0.0) 103 | word_wrap (~> 1.0.0) 104 | xcodeproj (>= 1.8.1, < 2.0.0) 105 | xcpretty (~> 0.3.0) 106 | xcpretty-travis-formatter (>= 0.0.3) 107 | fourflusher (2.3.1) 108 | fuzzy_match (2.0.4) 109 | gh_inspector (1.1.3) 110 | google-api-client (0.23.9) 111 | addressable (~> 2.5, >= 2.5.1) 112 | googleauth (>= 0.5, < 0.7.0) 113 | httpclient (>= 2.8.1, < 3.0) 114 | mime-types (~> 3.0) 115 | representable (~> 3.0) 116 | retriable (>= 2.0, < 4.0) 117 | signet (~> 0.9) 118 | google-cloud-core (1.3.1) 119 | google-cloud-env (~> 1.0) 120 | google-cloud-env (1.2.1) 121 | faraday (~> 0.11) 122 | google-cloud-storage (1.16.0) 123 | digest-crc (~> 0.4) 124 | google-api-client (~> 0.23) 125 | google-cloud-core (~> 1.2) 126 | googleauth (>= 0.6.2, < 0.10.0) 127 | googleauth (0.6.7) 128 | faraday (~> 0.12) 129 | jwt (>= 1.4, < 3.0) 130 | memoist (~> 0.16) 131 | multi_json (~> 1.11) 132 | os (>= 0.9, < 2.0) 133 | signet (~> 0.7) 134 | highline (1.7.10) 135 | http-cookie (1.0.3) 136 | domain_name (~> 0.5) 137 | httparty (0.17.0) 138 | mime-types (~> 3.0) 139 | multi_xml (>= 0.5.2) 140 | httpclient (2.8.3) 141 | i18n (0.9.5) 142 | concurrent-ruby (~> 1.0) 143 | json (2.2.0) 144 | jwt (2.1.0) 145 | memoist (0.16.0) 146 | mime-types (3.3) 147 | mime-types-data (~> 3.2015) 148 | mime-types-data (3.2019.0904) 149 | mini_magick (4.9.5) 150 | minitest (5.11.3) 151 | molinillo (0.6.6) 152 | multi_json (1.13.1) 153 | multi_xml (0.6.0) 154 | multipart-post (2.0.0) 155 | nanaimo (0.2.6) 156 | nap (1.1.0) 157 | naturally (2.2.0) 158 | netrc (0.11.0) 159 | os (1.0.1) 160 | plist (3.5.0) 161 | public_suffix (2.0.5) 162 | representable (3.0.4) 163 | declarative (< 0.1.0) 164 | declarative-option (< 0.2.0) 165 | uber (< 0.2.0) 166 | retriable (3.1.2) 167 | rouge (2.0.7) 168 | ruby-macho (1.4.0) 169 | rubyzip (1.2.4) 170 | security (0.1.3) 171 | signet (0.11.0) 172 | addressable (~> 2.3) 173 | faraday (~> 0.9) 174 | jwt (>= 1.5, < 3.0) 175 | multi_json (~> 1.10) 176 | simctl (1.6.5) 177 | CFPropertyList 178 | naturally 179 | slack-notifier (2.3.2) 180 | terminal-notifier (2.0.0) 181 | terminal-table (1.8.0) 182 | unicode-display_width (~> 1.1, >= 1.1.1) 183 | thread_safe (0.3.6) 184 | tty-cursor (0.7.0) 185 | tty-screen (0.7.0) 186 | tty-spinner (0.9.1) 187 | tty-cursor (~> 0.7) 188 | tzinfo (1.2.5) 189 | thread_safe (~> 0.1) 190 | uber (0.1.0) 191 | unf (0.1.4) 192 | unf_ext 193 | unf_ext (0.0.7.6) 194 | unicode-display_width (1.6.0) 195 | word_wrap (1.0.0) 196 | xcodeproj (1.12.0) 197 | CFPropertyList (>= 2.3.3, < 4.0) 198 | atomos (~> 0.1.3) 199 | claide (>= 1.0.2, < 2.0) 200 | colored2 (~> 3.1) 201 | nanaimo (~> 0.2.6) 202 | xcpretty (0.3.0) 203 | rouge (~> 2.0.7) 204 | xcpretty-travis-formatter (1.0.0) 205 | xcpretty (~> 0.2, >= 0.0.7) 206 | 207 | PLATFORMS 208 | ruby 209 | 210 | DEPENDENCIES 211 | cocoapods 212 | fastlane 213 | httparty 214 | json 215 | rubyzip 216 | 217 | BUNDLED WITH 218 | 2.0.2 219 | -------------------------------------------------------------------------------- /versions/2.2/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.2) 5 | activesupport (5.2.4.4) 6 | concurrent-ruby (~> 1.0, >= 1.0.2) 7 | i18n (>= 0.7, < 2) 8 | minitest (~> 5.1) 9 | tzinfo (~> 1.1) 10 | addressable (2.7.0) 11 | public_suffix (>= 2.0.2, < 5.0) 12 | algoliasearch (1.27.4) 13 | httpclient (~> 2.8, >= 2.8.3) 14 | json (>= 1.5.1) 15 | atomos (0.1.3) 16 | aws-eventstream (1.1.0) 17 | aws-partitions (1.386.0) 18 | aws-sdk-core (3.109.1) 19 | aws-eventstream (~> 1, >= 1.0.2) 20 | aws-partitions (~> 1, >= 1.239.0) 21 | aws-sigv4 (~> 1.1) 22 | jmespath (~> 1.0) 23 | aws-sdk-kms (1.39.0) 24 | aws-sdk-core (~> 3, >= 3.109.0) 25 | aws-sigv4 (~> 1.1) 26 | aws-sdk-s3 (1.83.1) 27 | aws-sdk-core (~> 3, >= 3.109.0) 28 | aws-sdk-kms (~> 1) 29 | aws-sigv4 (~> 1.1) 30 | aws-sigv4 (1.2.2) 31 | aws-eventstream (~> 1, >= 1.0.2) 32 | babosa (1.0.4) 33 | claide (1.0.3) 34 | cocoapods (1.10.0) 35 | addressable (~> 2.6) 36 | claide (>= 1.0.2, < 2.0) 37 | cocoapods-core (= 1.10.0) 38 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 39 | cocoapods-downloader (>= 1.4.0, < 2.0) 40 | cocoapods-plugins (>= 1.0.0, < 2.0) 41 | cocoapods-search (>= 1.0.0, < 2.0) 42 | cocoapods-trunk (>= 1.4.0, < 2.0) 43 | cocoapods-try (>= 1.1.0, < 2.0) 44 | colored2 (~> 3.1) 45 | escape (~> 0.0.4) 46 | fourflusher (>= 2.3.0, < 3.0) 47 | gh_inspector (~> 1.0) 48 | molinillo (~> 0.6.6) 49 | nap (~> 1.0) 50 | ruby-macho (~> 1.4) 51 | xcodeproj (>= 1.19.0, < 2.0) 52 | cocoapods-core (1.10.0) 53 | activesupport (> 5.0, < 6) 54 | addressable (~> 2.6) 55 | algoliasearch (~> 1.0) 56 | concurrent-ruby (~> 1.1) 57 | fuzzy_match (~> 2.0.4) 58 | nap (~> 1.0) 59 | netrc (~> 0.11) 60 | public_suffix 61 | typhoeus (~> 1.0) 62 | cocoapods-deintegrate (1.0.4) 63 | cocoapods-downloader (1.4.0) 64 | cocoapods-plugins (1.0.0) 65 | nap 66 | cocoapods-search (1.0.0) 67 | cocoapods-trunk (1.5.0) 68 | nap (>= 0.8, < 2.0) 69 | netrc (~> 0.11) 70 | cocoapods-try (1.2.0) 71 | colored (1.2) 72 | colored2 (3.1.2) 73 | commander-fastlane (4.4.6) 74 | highline (~> 1.7.2) 75 | concurrent-ruby (1.1.7) 76 | declarative (0.0.20) 77 | declarative-option (0.1.0) 78 | digest-crc (0.6.1) 79 | rake (~> 13.0) 80 | domain_name (0.5.20190701) 81 | unf (>= 0.0.5, < 1.0.0) 82 | dotenv (2.7.6) 83 | emoji_regex (3.0.0) 84 | escape (0.0.4) 85 | ethon (0.12.0) 86 | ffi (>= 1.3.0) 87 | excon (0.78.0) 88 | faraday (1.1.0) 89 | multipart-post (>= 1.2, < 3) 90 | ruby2_keywords 91 | faraday-cookie_jar (0.0.7) 92 | faraday (>= 0.8.0) 93 | http-cookie (~> 1.0.0) 94 | faraday_middleware (1.0.0) 95 | faraday (~> 1.0) 96 | fastimage (2.2.0) 97 | fastlane (2.165.0) 98 | CFPropertyList (>= 2.3, < 4.0.0) 99 | addressable (>= 2.3, < 3.0.0) 100 | aws-sdk-s3 (~> 1.0) 101 | babosa (>= 1.0.3, < 2.0.0) 102 | bundler (>= 1.12.0, < 3.0.0) 103 | colored 104 | commander-fastlane (>= 4.4.6, < 5.0.0) 105 | dotenv (>= 2.1.1, < 3.0.0) 106 | emoji_regex (>= 0.1, < 4.0) 107 | excon (>= 0.71.0, < 1.0.0) 108 | faraday (~> 1.0) 109 | faraday-cookie_jar (~> 0.0.6) 110 | faraday_middleware (~> 1.0) 111 | fastimage (>= 2.1.0, < 3.0.0) 112 | gh_inspector (>= 1.1.2, < 2.0.0) 113 | google-api-client (>= 0.37.0, < 0.39.0) 114 | google-cloud-storage (>= 1.15.0, < 2.0.0) 115 | highline (>= 1.7.2, < 2.0.0) 116 | json (< 3.0.0) 117 | jwt (>= 2.1.0, < 3) 118 | mini_magick (>= 4.9.4, < 5.0.0) 119 | multipart-post (~> 2.0.0) 120 | plist (>= 3.1.0, < 4.0.0) 121 | rubyzip (>= 2.0.0, < 3.0.0) 122 | security (= 0.1.3) 123 | simctl (~> 1.6.3) 124 | slack-notifier (>= 2.0.0, < 3.0.0) 125 | terminal-notifier (>= 2.0.0, < 3.0.0) 126 | terminal-table (>= 1.4.5, < 2.0.0) 127 | tty-screen (>= 0.6.3, < 1.0.0) 128 | tty-spinner (>= 0.8.0, < 1.0.0) 129 | word_wrap (~> 1.0.0) 130 | xcodeproj (>= 1.13.0, < 2.0.0) 131 | xcpretty (~> 0.3.0) 132 | xcpretty-travis-formatter (>= 0.0.3) 133 | ffi (1.13.1) 134 | fourflusher (2.3.1) 135 | fuzzy_match (2.0.4) 136 | gh_inspector (1.1.3) 137 | google-api-client (0.38.0) 138 | addressable (~> 2.5, >= 2.5.1) 139 | googleauth (~> 0.9) 140 | httpclient (>= 2.8.1, < 3.0) 141 | mini_mime (~> 1.0) 142 | representable (~> 3.0) 143 | retriable (>= 2.0, < 4.0) 144 | signet (~> 0.12) 145 | google-cloud-core (1.5.0) 146 | google-cloud-env (~> 1.0) 147 | google-cloud-errors (~> 1.0) 148 | google-cloud-env (1.4.0) 149 | faraday (>= 0.17.3, < 2.0) 150 | google-cloud-errors (1.0.1) 151 | google-cloud-storage (1.29.1) 152 | addressable (~> 2.5) 153 | digest-crc (~> 0.4) 154 | google-api-client (~> 0.33) 155 | google-cloud-core (~> 1.2) 156 | googleauth (~> 0.9) 157 | mini_mime (~> 1.0) 158 | googleauth (0.14.0) 159 | faraday (>= 0.17.3, < 2.0) 160 | jwt (>= 1.4, < 3.0) 161 | memoist (~> 0.16) 162 | multi_json (~> 1.11) 163 | os (>= 0.9, < 2.0) 164 | signet (~> 0.14) 165 | highline (1.7.10) 166 | http-cookie (1.0.3) 167 | domain_name (~> 0.5) 168 | httparty (0.18.1) 169 | mime-types (~> 3.0) 170 | multi_xml (>= 0.5.2) 171 | httpclient (2.8.3) 172 | i18n (1.8.5) 173 | concurrent-ruby (~> 1.0) 174 | jmespath (1.4.0) 175 | json (2.3.1) 176 | jwt (2.2.2) 177 | memoist (0.16.2) 178 | mime-types (3.3.1) 179 | mime-types-data (~> 3.2015) 180 | mime-types-data (3.2020.0512) 181 | mini_magick (4.10.1) 182 | mini_mime (1.0.2) 183 | minitest (5.14.2) 184 | molinillo (0.6.6) 185 | multi_json (1.15.0) 186 | multi_xml (0.6.0) 187 | multipart-post (2.0.0) 188 | nanaimo (0.3.0) 189 | nap (1.1.0) 190 | naturally (2.2.0) 191 | netrc (0.11.0) 192 | os (1.1.1) 193 | plist (3.5.0) 194 | public_suffix (4.0.6) 195 | rake (13.0.1) 196 | representable (3.0.4) 197 | declarative (< 0.1.0) 198 | declarative-option (< 0.2.0) 199 | uber (< 0.2.0) 200 | retriable (3.1.2) 201 | rouge (2.0.7) 202 | ruby-macho (1.4.0) 203 | ruby2_keywords (0.0.2) 204 | rubyzip (2.3.0) 205 | security (0.1.3) 206 | signet (0.14.0) 207 | addressable (~> 2.3) 208 | faraday (>= 0.17.3, < 2.0) 209 | jwt (>= 1.5, < 3.0) 210 | multi_json (~> 1.10) 211 | simctl (1.6.8) 212 | CFPropertyList 213 | naturally 214 | slack-notifier (2.3.2) 215 | terminal-notifier (2.0.0) 216 | terminal-table (1.8.0) 217 | unicode-display_width (~> 1.1, >= 1.1.1) 218 | thread_safe (0.3.6) 219 | tty-cursor (0.7.1) 220 | tty-screen (0.8.1) 221 | tty-spinner (0.9.3) 222 | tty-cursor (~> 0.7) 223 | typhoeus (1.4.0) 224 | ethon (>= 0.9.0) 225 | tzinfo (1.2.7) 226 | thread_safe (~> 0.1) 227 | uber (0.1.0) 228 | unf (0.1.4) 229 | unf_ext 230 | unf_ext (0.0.7.7) 231 | unicode-display_width (1.7.0) 232 | word_wrap (1.0.0) 233 | xcodeproj (1.19.0) 234 | CFPropertyList (>= 2.3.3, < 4.0) 235 | atomos (~> 0.1.3) 236 | claide (>= 1.0.2, < 2.0) 237 | colored2 (~> 3.1) 238 | nanaimo (~> 0.3.0) 239 | xcpretty (0.3.0) 240 | rouge (~> 2.0.7) 241 | xcpretty-travis-formatter (1.0.0) 242 | xcpretty (~> 0.2, >= 0.0.7) 243 | 244 | PLATFORMS 245 | ruby 246 | 247 | DEPENDENCIES 248 | cocoapods 249 | fastlane 250 | httparty 251 | json 252 | rubyzip 253 | 254 | BUNDLED WITH 255 | 2.1.4 256 | -------------------------------------------------------------------------------- /versions/0.1/parse_project_settings.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'yaml' 3 | require 'xcodeproj' 4 | require 'fileutils' 5 | require 'pp' 6 | require 'plist' 7 | require 'hockeyver' 8 | require 'json' 9 | 10 | # ------- 11 | # Constants 12 | # ------- 13 | 14 | PROJECT_FILE_NAME='project.yml' 15 | TARGET_FILE='build_config.json' 16 | DEBUG_MODE=false 17 | VERBOSE=false 18 | 19 | # ------- 20 | # Helpers 21 | # ------- 22 | 23 | def colorize(text, color_code) 24 | "\e[#{color_code}m#{text}\e[0m" 25 | end 26 | def red(text); colorize(text, 31); end 27 | def green(text); colorize(text, 32); end 28 | def yellow(text); colorize(text, 33); end 29 | def bold(text); "\e[1m#{text}\e[22m" end 30 | 31 | class Version < Array 32 | def initialize s 33 | super(s.split('.').map { |e| e.to_i }) 34 | end 35 | def < x 36 | (self <=> x) < 0 37 | end 38 | def > x 39 | (self <=> x) > 0 40 | end 41 | def == x 42 | (self <=> x) == 0 43 | end 44 | def >= x 45 | (self <=> x) >= 0 46 | end 47 | end 48 | 49 | def addErrorMessage(message) 50 | File.open('error_message', 'w') { |file| file.write(message) } 51 | end 52 | 53 | # ------- 54 | # Main 55 | # ------- 56 | 57 | # Load YAML 58 | puts bold "Loading settings from #{PROJECT_FILE_NAME}" 59 | unless File.exist?(PROJECT_FILE_NAME) 60 | message = "|- Couldn't find project.yml file" 61 | addErrorMessage(message) 62 | raise red message 63 | end 64 | 65 | project_settings = YAML.load_file(PROJECT_FILE_NAME) 66 | 67 | # Load some settings 68 | xcodeproj_path = project_settings['xcodeproj'] 69 | configuration = project_settings["configuration"] 70 | PROJECT_ROOT_DIR = File.dirname(xcodeproj_path) + "/" 71 | export_method = project_settings['method'] ||= "app-store" 72 | ci_version = project_settings['ci-version'] 73 | 74 | # Load Xcode project 75 | unless File.exist?(xcodeproj_path) 76 | message = "|- Couldn't find Xcode project at: #{xcodeproj_path}" 77 | addErrorMessage(message) 78 | raise red message 79 | end 80 | 81 | xcode_project = Xcodeproj::Project.open xcodeproj_path 82 | 83 | # Validate configuration 84 | avialable_configurations = xcode_project.build_configurations.map { |x| 85 | puts "|- #{x.name}" if VERBOSE 86 | x.name 87 | } 88 | unless avialable_configurations.include? configuration 89 | message = "|- Can't find configuration #{configuration}" 90 | addErrorMessage(message) 91 | raise red message 92 | end 93 | 94 | # Notify 95 | puts green "|- Settings loaded succesfully with configuration: #{project_settings["configuration"]}." 96 | 97 | # Load upload settings 98 | hockey_upload = project_settings['hockey-upload'] ? 1 : 0 99 | testflight_upload = project_settings['testflight-upload'] ? 1 : 0 100 | puts "" 101 | puts bold "Checking upload settings" 102 | if hockey_upload == 1 103 | puts green "|- Will upload to hockey" 104 | else 105 | puts yellow "|- Skipping hockey upload" 106 | end 107 | if testflight_upload == 1 108 | puts green "|- Will upload to testflight" 109 | else 110 | puts yellow "|- Skipping testflight upload" 111 | end 112 | 113 | 114 | # Get available targets 115 | validated_targets = Hash.new 116 | 117 | # Validate targets 118 | puts "" 119 | puts bold "Validating target settings" 120 | project_settings["targets"].each_pair { |key, val| 121 | xcode_target = xcode_project.targets.select { |tar| tar.name == key }.first 122 | 123 | # Check for target existence 124 | if xcode_target.nil? 125 | puts yellow "|- Skipping target #{key}, as Xcode doesn't contain corresponding target." 126 | next 127 | end 128 | 129 | # Check if enabled 130 | unless val["enabled"] 131 | puts yellow "|- Skipping target #{key}, because it is disabled." 132 | next 133 | end 134 | 135 | # Validate scheme 136 | unless Xcodeproj::Project.schemes(xcodeproj_path).include? val["scheme"] 137 | puts yellow """|- Skipping target #{key}, because the specified scheme can't be found. 138 | Did you set it the scheme as shared?""" 139 | next 140 | end 141 | 142 | puts green "|- Found valid target #{key}." 143 | validated_targets[key] = { "settings" => val, "target" => xcode_target } 144 | } 145 | 146 | 147 | # Make sure we have something to build 148 | unless validated_targets.count > 0 149 | message = "|- No valid targets to build, build failed." 150 | addErrorMessage(message) 151 | raise red message 152 | end 153 | 154 | # Temp fix for riide, will make this more reusable in the future. This breaks down the 155 | # targets into groups of 6, and uses the RIIDE_PROJECT env var to determine which 156 | # of the subset to use 157 | length = 6 158 | if validated_targets.count > length 159 | start = ENV["RIIDE_PROJECT"].to_i * length 160 | start -= length 161 | validated_targets = validated_targets.select { |k, v| validated_targets.keys[start, length].include? k } 162 | end 163 | 164 | puts "" 165 | puts bold "Starting Hockey versions verification" 166 | 167 | valid = true 168 | 169 | unless DEBUG_MODE 170 | # Get version and build numbers 171 | message = "" 172 | validated_targets.each_pair { |key, val| 173 | 174 | # Find the correct configuration 175 | configs = val["target"].build_configurations 176 | index = configs.index { |x| x.name == configuration } 177 | 178 | # Get info plist 179 | info_plist = configs[index].build_settings["INFOPLIST_FILE"] 180 | info_plist_path = PROJECT_ROOT_DIR + info_plist 181 | 182 | plist = Plist.parse_xml info_plist_path 183 | xcode_version = plist["CFBundleShortVersionString"] 184 | xcode_build = plist["CFBundleVersion"].to_i 185 | 186 | puts "|- Verifying '#{key}' with version #{xcode_version} (#{xcode_build})." 187 | 188 | # Get hockey app id object 189 | hockey_app_id = val["settings"]["hockey-app-id"] 190 | 191 | # Figure out if hockey app id object is a hash (for configuration mapping to ids) 192 | # or a String with static hockey app id 193 | if hockey_app_id.respond_to?(:has_key?) then 194 | raise red """|- HockeyApp app id is missing for the current configuration, please add it or switch to static app id.""" unless hockey_app_id.has_key?(configuration) 195 | 196 | # Parse from nested dict 197 | hockey_app_id = hockey_app_id[configuration] 198 | val["settings"]["hockey-app-id"] = hockey_app_id 199 | end 200 | 201 | # Check if hockey id is filled in correctly 202 | if hockey_app_id.empty? || !hockey_app_id.is_a?(String) then 203 | raise red """|- HockeyApp app id is missing, can't continue with build as version and build number can't be verified. 204 | All apps should have an associated HockeyApp app.""" 205 | end 206 | 207 | buildnumber = HockeyVer.parse_hockey_version hockey_app_id, ENV["HOCKEY_API_TOKEN"] 208 | 209 | # Check if build number from hockey is nil 210 | if buildnumber.nil? 211 | puts yellow "|- No build found on Hockey, proceeding with build" 212 | next 213 | end 214 | 215 | hockey_version = buildnumber["version"] 216 | hockey_build = buildnumber["build"].to_i 217 | 218 | # Compare, make sure that build is always higher and version is at least higher or equal 219 | unless (Version.new(xcode_version) >= Version.new(hockey_version)) && (xcode_build > hockey_build) 220 | valid = false 221 | warning_message = """#{key}: Xcode version #{xcode_version} (#{xcode_build}) is lower or equal than the one on Hockey #{hockey_version} (#{hockey_build}).""" 222 | message +="#{warning_message} \n" 223 | puts yellow "|- #{warning_message}" 224 | end 225 | } 226 | end 227 | 228 | # Check if we can continue 229 | unless valid 230 | message += "Can't continue with build, as version and build numbers must be higher than the ones on Hockey." 231 | addErrorMessage(message) 232 | raise red message 233 | end 234 | 235 | 236 | # All done 237 | puts green "|- All version and build numbers are correct." 238 | 239 | puts "" 240 | puts bold "Creating information required for build" 241 | 242 | build_config = Hash.new 243 | 244 | validated_targets.each_pair { |key, val| 245 | content = val['settings'] 246 | 247 | # Pass platform, xcodeproj 248 | content['xcodeproj'] = xcode_project.path.to_path 249 | content['workspace'] = project_settings['workspace'] 250 | content['platform'] = val['target'].platform_name 251 | content['configuration'] = configuration 252 | content['bundle_id'] = val['target'].build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] 253 | 254 | # Get extensions from content and remove them (will re-added if validated) 255 | extensions_bundle_ids = content['extensions-bundle-ids'] ||= Array.new 256 | content['extensions-bundle-ids'] = Hash.new 257 | 258 | # Validate extensions 259 | extensions_bundle_ids.each { |extension_id| 260 | # Fetch extension target 261 | extension_target = xcode_project.targets.select { |tar| 262 | tar.build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] == extension_id 263 | }.first 264 | 265 | # If we didn't find extesion, skip to next one 266 | if extension_target.nil? 267 | puts yellow "Skipping extension with bundle id #{extension_id} as a target with this id does not exist." 268 | next 269 | end 270 | 271 | # Bail if not an extension type 272 | unless extension_target.extension_target_type? 273 | puts yellow "Skipping extension with bundle id #{extension_id} as this target is not an extension target." 274 | next 275 | end 276 | 277 | # Add validated ID to extensions hash 278 | content['extensions-bundle-ids'][extension_target.name] = extension_id 279 | } 280 | 281 | # Extract build number 282 | info_plist = val['target'].build_settings(configuration)["INFOPLIST_FILE"] 283 | info_plist_path = PROJECT_ROOT_DIR + info_plist 284 | plist = Plist.parse_xml info_plist_path 285 | xcode_version = plist["CFBundleShortVersionString"] 286 | xcode_build = plist["CFBundleVersion"].to_i 287 | content['xcode_version'] = "#{xcode_version}" 288 | content['xcode_build'] = "#{xcode_build}" 289 | 290 | build_config[key] = content 291 | } 292 | 293 | # Save to env 294 | system "bitrise envman add --key BUILD_CONFIG --value '#{build_config.to_json}' --no-expand" unless DEBUG_MODE 295 | system "bitrise envman add --key EXPORT_METHOD --value #{export_method} --no-expand" unless DEBUG_MODE 296 | system "bitrise envman add --key HOCKEY_UPLOAD_FLAG --value '#{hockey_upload}' --no-expand" unless DEBUG_MODE 297 | system "bitrise envman add --key TESTFLIGHT_UPLOAD_FLAG --value '#{testflight_upload}' --no-expand" unless DEBUG_MODE 298 | system "bitrise envman add --key SLACK_CHANNEL --value '#{project_settings['slack-channel']}' --no-expand " unless DEBUG_MODE 299 | system "bitrise envman add --key CI_VERSION --value '#{ci_version}' --no-expand " unless DEBUG_MODE 300 | puts green "|- Succesfully generated build config." 301 | pp build_config unless not VERBOSE 302 | -------------------------------------------------------------------------------- /versions/0.2/parse_project_settings.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'yaml' 3 | require 'xcodeproj' 4 | require 'fileutils' 5 | require 'pp' 6 | require 'plist' 7 | require 'hockeyver' 8 | require 'json' 9 | 10 | # ------- 11 | # Constants 12 | # ------- 13 | 14 | PROJECT_FILE_NAME='project.yml' 15 | TARGET_FILE='build_config.json' 16 | DEBUG_MODE=false 17 | VERBOSE=false 18 | 19 | # ------- 20 | # Helpers 21 | # ------- 22 | 23 | def colorize(text, color_code) 24 | "\e[#{color_code}m#{text}\e[0m" 25 | end 26 | def red(text); colorize(text, 31); end 27 | def green(text); colorize(text, 32); end 28 | def yellow(text); colorize(text, 33); end 29 | def bold(text); "\e[1m#{text}\e[22m" end 30 | 31 | class Version < Array 32 | def initialize s 33 | super(s.split('.').map { |e| e.to_i }) 34 | end 35 | def < x 36 | (self <=> x) < 0 37 | end 38 | def > x 39 | (self <=> x) > 0 40 | end 41 | def == x 42 | (self <=> x) == 0 43 | end 44 | def >= x 45 | (self <=> x) >= 0 46 | end 47 | end 48 | 49 | def addErrorMessage(message) 50 | File.open('error_message', 'w') { |file| file.write(message) } 51 | end 52 | 53 | # ------- 54 | # Main 55 | # ------- 56 | 57 | # Load YAML 58 | puts bold "Loading settings from #{PROJECT_FILE_NAME}" 59 | unless File.exist?(PROJECT_FILE_NAME) 60 | message = "|- Couldn't find project.yml file" 61 | addErrorMessage(message) 62 | raise red message 63 | end 64 | 65 | project_settings = YAML.load_file(PROJECT_FILE_NAME) 66 | 67 | # Load some settings 68 | xcodeproj_path = project_settings['xcodeproj'] 69 | configuration = project_settings["configuration"] 70 | PROJECT_ROOT_DIR = File.dirname(xcodeproj_path) + "/" 71 | export_method = project_settings['method'] ||= "app-store" 72 | ci_version = project_settings['ci-version'] 73 | 74 | # Load Xcode project 75 | unless File.exist?(xcodeproj_path) 76 | message = "|- Couldn't find Xcode project at: #{xcodeproj_path}" 77 | addErrorMessage(message) 78 | raise red message 79 | end 80 | 81 | xcode_project = Xcodeproj::Project.open xcodeproj_path 82 | 83 | # Validate configuration 84 | avialable_configurations = xcode_project.build_configurations.map { |x| 85 | puts "|- #{x.name}" if VERBOSE 86 | x.name 87 | } 88 | unless avialable_configurations.include? configuration 89 | message = "|- Can't find configuration #{configuration}" 90 | addErrorMessage(message) 91 | raise red message 92 | end 93 | 94 | # Notify 95 | puts green "|- Settings loaded succesfully with configuration: #{project_settings["configuration"]}." 96 | 97 | # Load upload settings 98 | hockey_upload = project_settings['hockey-upload'] ? 1 : 0 99 | testflight_upload = project_settings['testflight-upload'] ? 1 : 0 100 | puts "" 101 | puts bold "Checking upload settings" 102 | if hockey_upload == 1 103 | puts green "|- Will upload to hockey" 104 | else 105 | puts yellow "|- Skipping hockey upload" 106 | end 107 | if testflight_upload == 1 108 | puts green "|- Will upload to testflight" 109 | else 110 | puts yellow "|- Skipping testflight upload" 111 | end 112 | 113 | 114 | # Get available targets 115 | validated_targets = Hash.new 116 | 117 | # Validate targets 118 | puts "" 119 | puts bold "Validating target settings" 120 | project_settings["targets"].each_pair { |key, val| 121 | xcode_target = xcode_project.targets.select { |tar| tar.name == key }.first 122 | 123 | # Check for target existence 124 | if xcode_target.nil? 125 | puts yellow "|- Skipping target #{key}, as Xcode doesn't contain corresponding target." 126 | next 127 | end 128 | 129 | # Check if enabled 130 | unless val["enabled"] 131 | puts yellow "|- Skipping target #{key}, because it is disabled." 132 | next 133 | end 134 | 135 | # Validate scheme 136 | unless Xcodeproj::Project.schemes(xcodeproj_path).include? val["scheme"] 137 | puts yellow """|- Skipping target #{key}, because the specified scheme can't be found. 138 | Did you set it the scheme as shared?""" 139 | next 140 | end 141 | 142 | puts green "|- Found valid target #{key}." 143 | validated_targets[key] = { "settings" => val, "target" => xcode_target } 144 | } 145 | 146 | 147 | # Make sure we have something to build 148 | unless validated_targets.count > 0 149 | message = "|- No valid targets to build, build failed." 150 | addErrorMessage(message) 151 | raise red message 152 | end 153 | 154 | # Temp fix for riide, will make this more reusable in the future. This breaks down the 155 | # targets into groups of 6, and uses the RIIDE_PROJECT env var to determine which 156 | # of the subset to use 157 | length = 6 158 | if validated_targets.count > length 159 | start = ENV["RIIDE_PROJECT"].to_i * length 160 | start -= length 161 | validated_targets = validated_targets.select { |k, v| validated_targets.keys[start, length].include? k } 162 | end 163 | 164 | puts "" 165 | puts bold "Starting Hockey versions verification" 166 | 167 | valid = true 168 | 169 | unless DEBUG_MODE 170 | # Get version and build numbers 171 | message = "" 172 | validated_targets.each_pair { |key, val| 173 | 174 | # Find the correct configuration 175 | configs = val["target"].build_configurations 176 | index = configs.index { |x| x.name == configuration } 177 | 178 | # Get info plist 179 | info_plist = configs[index].build_settings["INFOPLIST_FILE"] 180 | info_plist_path = PROJECT_ROOT_DIR + info_plist 181 | 182 | plist = Plist.parse_xml info_plist_path 183 | xcode_version = plist["CFBundleShortVersionString"] 184 | xcode_build = plist["CFBundleVersion"].to_i 185 | 186 | puts "|- Verifying '#{key}' with version #{xcode_version} (#{xcode_build})." 187 | 188 | # Get hockey app id object 189 | hockey_app_id = val["settings"]["hockey-app-id"] 190 | 191 | # Figure out if hockey app id object is a hash (for configuration mapping to ids) 192 | # or a String with static hockey app id 193 | if hockey_app_id.respond_to?(:has_key?) then 194 | raise red """|- HockeyApp app id is missing for the current configuration, please add it or switch to static app id.""" unless hockey_app_id.has_key?(configuration) 195 | 196 | # Parse from nested dict 197 | hockey_app_id = hockey_app_id[configuration] 198 | val["settings"]["hockey-app-id"] = hockey_app_id 199 | end 200 | 201 | # Check if hockey id is filled in correctly 202 | if hockey_app_id.empty? || !hockey_app_id.is_a?(String) then 203 | raise red """|- HockeyApp app id is missing, can't continue with build as version and build number can't be verified. 204 | All apps should have an associated HockeyApp app.""" 205 | end 206 | 207 | buildnumber = HockeyVer.parse_hockey_version hockey_app_id, ENV["HOCKEY_API_TOKEN"] 208 | 209 | # Check if build number from hockey is nil 210 | if buildnumber.nil? 211 | puts yellow "|- No build found on Hockey, proceeding with build" 212 | next 213 | end 214 | 215 | hockey_version = buildnumber["version"] 216 | hockey_build = buildnumber["build"].to_i 217 | 218 | # Compare, make sure that build is always higher and version is at least higher or equal 219 | unless (Version.new(xcode_version) >= Version.new(hockey_version)) && (xcode_build > hockey_build) 220 | valid = false 221 | warning_message = """#{key}: Xcode version #{xcode_version} (#{xcode_build}) is lower or equal than the one on Hockey #{hockey_version} (#{hockey_build}).""" 222 | message +="#{warning_message} \n" 223 | puts yellow "|- #{warning_message}" 224 | end 225 | } 226 | end 227 | 228 | # Check if we can continue 229 | unless valid 230 | message += "Can't continue with build, as version and build numbers must be higher than the ones on Hockey." 231 | addErrorMessage(message) 232 | raise red message 233 | end 234 | 235 | 236 | # All done 237 | puts green "|- All version and build numbers are correct." 238 | 239 | puts "" 240 | puts bold "Creating information required for build" 241 | 242 | build_config = Hash.new 243 | 244 | validated_targets.each_pair { |key, val| 245 | content = val['settings'] 246 | 247 | # Pass platform, xcodeproj 248 | content['xcodeproj'] = xcode_project.path.to_path 249 | content['workspace'] = project_settings['workspace'] 250 | content['platform'] = val['target'].platform_name 251 | content['configuration'] = configuration 252 | content['bundle_id'] = val['target'].build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] 253 | 254 | # Get extensions from content and remove them (will re-added if validated) 255 | extensions_bundle_ids = content['extensions-bundle-ids'] ||= Array.new 256 | content['extensions-bundle-ids'] = Hash.new 257 | 258 | # Validate extensions 259 | extensions_bundle_ids.each { |extension_id| 260 | # Fetch extension target 261 | extension_target = xcode_project.targets.select { |tar| 262 | tar.build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] == extension_id 263 | }.first 264 | 265 | # If we didn't find extesion, skip to next one 266 | if extension_target.nil? 267 | puts yellow "Skipping extension with bundle id #{extension_id} as a target with this id does not exist." 268 | next 269 | end 270 | 271 | # Bail if not an extension type 272 | unless extension_target.extension_target_type? 273 | puts yellow "Skipping extension with bundle id #{extension_id} as this target is not an extension target." 274 | next 275 | end 276 | 277 | # Add validated ID to extensions hash 278 | content['extensions-bundle-ids'][extension_target.name] = extension_id 279 | } 280 | 281 | # Extract build number 282 | info_plist = val['target'].build_settings(configuration)["INFOPLIST_FILE"] 283 | info_plist_path = PROJECT_ROOT_DIR + info_plist 284 | plist = Plist.parse_xml info_plist_path 285 | xcode_version = plist["CFBundleShortVersionString"] 286 | xcode_build = plist["CFBundleVersion"].to_i 287 | content['xcode_version'] = "#{xcode_version}" 288 | content['xcode_build'] = "#{xcode_build}" 289 | 290 | build_config[key] = content 291 | } 292 | 293 | # Save to env 294 | system "bitrise envman add --key BUILD_CONFIG --value '#{build_config.to_json}' --no-expand" unless DEBUG_MODE 295 | system "bitrise envman add --key EXPORT_METHOD --value #{export_method} --no-expand" unless DEBUG_MODE 296 | system "bitrise envman add --key HOCKEY_UPLOAD_FLAG --value '#{hockey_upload}' --no-expand" unless DEBUG_MODE 297 | system "bitrise envman add --key TESTFLIGHT_UPLOAD_FLAG --value '#{testflight_upload}' --no-expand" unless DEBUG_MODE 298 | system "bitrise envman add --key SLACK_CHANNEL --value '#{project_settings['slack-channel']}' --no-expand " unless DEBUG_MODE 299 | system "bitrise envman add --key CI_VERSION --value '#{ci_version}' --no-expand " unless DEBUG_MODE 300 | puts green "|- Succesfully generated build config." 301 | pp build_config unless not VERBOSE 302 | -------------------------------------------------------------------------------- /versions/1.0/parse_project_settings.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'yaml' 3 | require 'xcodeproj' 4 | require 'fileutils' 5 | require 'pp' 6 | require 'plist' 7 | require 'hockeyver' 8 | require 'json' 9 | 10 | # ------- 11 | # Constants 12 | # ------- 13 | 14 | PROJECT_FILE_NAME='project.yml' 15 | TARGET_FILE='build_config.json' 16 | DEBUG_MODE=false 17 | VERBOSE=false 18 | 19 | # ------- 20 | # Helpers 21 | # ------- 22 | 23 | def colorize(text, color_code) 24 | "\e[#{color_code}m#{text}\e[0m" 25 | end 26 | def red(text); colorize(text, 31); end 27 | def green(text); colorize(text, 32); end 28 | def yellow(text); colorize(text, 33); end 29 | def bold(text); "\e[1m#{text}\e[22m" end 30 | 31 | class Version < Array 32 | def initialize s 33 | super(s.split('.').map { |e| e.to_i }) 34 | end 35 | def < x 36 | (self <=> x) < 0 37 | end 38 | def > x 39 | (self <=> x) > 0 40 | end 41 | def == x 42 | (self <=> x) == 0 43 | end 44 | def >= x 45 | (self <=> x) >= 0 46 | end 47 | end 48 | 49 | def addErrorMessage(message) 50 | File.open('error_message', 'w') { |file| file.write(message) } 51 | end 52 | 53 | # ------- 54 | # Main 55 | # ------- 56 | 57 | # Load YAML 58 | puts bold "Loading settings from #{PROJECT_FILE_NAME}" 59 | unless File.exist?(PROJECT_FILE_NAME) 60 | message = "|- Couldn't find project.yml file" 61 | addErrorMessage(message) 62 | raise red message 63 | end 64 | 65 | project_settings = YAML.load_file(PROJECT_FILE_NAME) 66 | 67 | # Load some settings 68 | xcodeproj_path = project_settings['xcodeproj'] 69 | configuration = project_settings["configuration"] 70 | PROJECT_ROOT_DIR = File.dirname(xcodeproj_path) + "/" 71 | export_method = project_settings['method'] ||= "app-store" 72 | ci_version = project_settings['ci-version'] 73 | 74 | # Load Xcode project 75 | unless File.exist?(xcodeproj_path) 76 | message = "|- Couldn't find Xcode project at: #{xcodeproj_path}" 77 | addErrorMessage(message) 78 | raise red message 79 | end 80 | 81 | xcode_project = Xcodeproj::Project.open xcodeproj_path 82 | 83 | # Validate configuration 84 | avialable_configurations = xcode_project.build_configurations.map { |x| 85 | puts "|- #{x.name}" if VERBOSE 86 | x.name 87 | } 88 | unless avialable_configurations.include? configuration 89 | message = "|- Can't find configuration #{configuration}" 90 | addErrorMessage(message) 91 | raise red message 92 | end 93 | 94 | # Notify 95 | puts green "|- Settings loaded succesfully with configuration: #{project_settings["configuration"]}." 96 | 97 | # Load upload settings 98 | hockey_upload = project_settings['hockey-upload'] ? 1 : 0 99 | testflight_upload = project_settings['testflight-upload'] ? 1 : 0 100 | puts "" 101 | puts bold "Checking upload settings" 102 | if hockey_upload == 1 103 | puts green "|- Will upload to hockey" 104 | else 105 | puts yellow "|- Skipping hockey upload" 106 | end 107 | if testflight_upload == 1 108 | puts green "|- Will upload to testflight" 109 | else 110 | puts yellow "|- Skipping testflight upload" 111 | end 112 | 113 | 114 | # Get available targets 115 | validated_targets = Hash.new 116 | 117 | # Validate targets 118 | puts "" 119 | puts bold "Validating target settings" 120 | project_settings["targets"].each_pair { |key, val| 121 | xcode_target = xcode_project.targets.select { |tar| tar.name == key }.first 122 | 123 | # Check for target existence 124 | if xcode_target.nil? 125 | puts yellow "|- Skipping target #{key}, as Xcode doesn't contain corresponding target." 126 | next 127 | end 128 | 129 | # Check if enabled 130 | unless val["enabled"] 131 | puts yellow "|- Skipping target #{key}, because it is disabled." 132 | next 133 | end 134 | 135 | # Validate scheme 136 | unless Xcodeproj::Project.schemes(xcodeproj_path).include? val["scheme"] 137 | puts yellow """|- Skipping target #{key}, because the specified scheme can't be found. 138 | Did you set it the scheme as shared?""" 139 | next 140 | end 141 | 142 | puts green "|- Found valid target #{key}." 143 | validated_targets[key] = { "settings" => val, "target" => xcode_target } 144 | } 145 | 146 | 147 | # Make sure we have something to build 148 | unless validated_targets.count > 0 149 | message = "|- No valid targets to build, build failed." 150 | addErrorMessage(message) 151 | raise red message 152 | end 153 | 154 | # Temp fix for riide, will make this more reusable in the future. This breaks down the 155 | # targets into groups of 6, and uses the RIIDE_PROJECT env var to determine which 156 | # of the subset to use 157 | length = 6 158 | if validated_targets.count > length 159 | start = ENV["RIIDE_PROJECT"].to_i * length 160 | start -= length 161 | validated_targets = validated_targets.select { |k, v| validated_targets.keys[start, length].include? k } 162 | end 163 | 164 | puts "" 165 | puts bold "Starting Hockey versions verification" 166 | 167 | valid = true 168 | 169 | unless DEBUG_MODE 170 | # Get version and build numbers 171 | message = "" 172 | validated_targets.each_pair { |key, val| 173 | 174 | # Find the correct configuration 175 | configs = val["target"].build_configurations 176 | index = configs.index { |x| x.name == configuration } 177 | 178 | # Get info plist 179 | info_plist = configs[index].build_settings["INFOPLIST_FILE"] 180 | info_plist_path = PROJECT_ROOT_DIR + info_plist 181 | 182 | plist = Plist.parse_xml info_plist_path 183 | xcode_version = plist["CFBundleShortVersionString"] 184 | xcode_build = plist["CFBundleVersion"].to_i 185 | 186 | puts "|- Verifying '#{key}' with version #{xcode_version} (#{xcode_build})." 187 | 188 | # Get hockey app id object 189 | hockey_app_id = val["settings"]["hockey-app-id"] 190 | 191 | # Figure out if hockey app id object is a hash (for configuration mapping to ids) 192 | # or a String with static hockey app id 193 | if hockey_app_id.respond_to?(:has_key?) then 194 | raise red """|- HockeyApp app id is missing for the current configuration, please add it or switch to static app id.""" unless hockey_app_id.has_key?(configuration) 195 | 196 | # Parse from nested dict 197 | hockey_app_id = hockey_app_id[configuration] 198 | val["settings"]["hockey-app-id"] = hockey_app_id 199 | end 200 | 201 | # Check if hockey id is filled in correctly 202 | if hockey_app_id.empty? || !hockey_app_id.is_a?(String) then 203 | raise red """|- HockeyApp app id is missing, can't continue with build as version and build number can't be verified. 204 | All apps should have an associated HockeyApp app.""" 205 | end 206 | 207 | buildnumber = HockeyVer.parse_hockey_version hockey_app_id, ENV["HOCKEY_API_TOKEN"] 208 | 209 | # Check if build number from hockey is nil 210 | if buildnumber.nil? 211 | puts yellow "|- No build found on Hockey, proceeding with build" 212 | next 213 | end 214 | 215 | hockey_version = buildnumber["version"] 216 | hockey_build = buildnumber["build"].to_i 217 | 218 | # Compare, make sure that build is always higher and version is at least higher or equal 219 | unless (Version.new(xcode_version) >= Version.new(hockey_version)) && (xcode_build > hockey_build) 220 | valid = false 221 | warning_message = """#{key}: Xcode version #{xcode_version} (#{xcode_build}) is lower or equal than the one on Hockey #{hockey_version} (#{hockey_build}).""" 222 | message +="#{warning_message} \n" 223 | puts yellow "|- #{warning_message}" 224 | end 225 | } 226 | end 227 | 228 | # Check if we can continue 229 | unless valid 230 | message += "Can't continue with build, as version and build numbers must be higher than the ones on Hockey." 231 | addErrorMessage(message) 232 | raise red message 233 | end 234 | 235 | 236 | # All done 237 | puts green "|- All version and build numbers are correct." 238 | 239 | puts "" 240 | puts bold "Creating information required for build" 241 | 242 | build_config = Hash.new 243 | 244 | validated_targets.each_pair { |key, val| 245 | content = val['settings'] 246 | 247 | # Pass platform, xcodeproj 248 | content['xcodeproj'] = xcode_project.path.to_path 249 | content['workspace'] = project_settings['workspace'] 250 | content['platform'] = val['target'].platform_name 251 | content['configuration'] = configuration 252 | content['bundle_id'] = val['target'].build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] 253 | 254 | # Get extensions from content and remove them (will re-added if validated) 255 | extensions_bundle_ids = content['extensions-bundle-ids'] ||= Array.new 256 | content['extensions-bundle-ids'] = Hash.new 257 | 258 | # Validate extensions 259 | extensions_bundle_ids.each { |extension_id| 260 | # Fetch extension target 261 | extension_target = xcode_project.targets.select { |tar| 262 | tar.build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] == extension_id 263 | }.first 264 | 265 | # If we didn't find extesion, skip to next one 266 | if extension_target.nil? 267 | puts yellow "Skipping extension with bundle id #{extension_id} as a target with this id does not exist." 268 | next 269 | end 270 | 271 | # Bail if not an extension type 272 | unless extension_target.extension_target_type? 273 | puts yellow "Skipping extension with bundle id #{extension_id} as this target is not an extension target." 274 | next 275 | end 276 | 277 | # Add validated ID to extensions hash 278 | content['extensions-bundle-ids'][extension_target.name] = extension_id 279 | } 280 | 281 | # Extract build number 282 | info_plist = val['target'].build_settings(configuration)["INFOPLIST_FILE"] 283 | info_plist_path = PROJECT_ROOT_DIR + info_plist 284 | plist = Plist.parse_xml info_plist_path 285 | xcode_version = plist["CFBundleShortVersionString"] 286 | xcode_build = plist["CFBundleVersion"].to_i 287 | content['xcode_version'] = "#{xcode_version}" 288 | content['xcode_build'] = "#{xcode_build}" 289 | 290 | build_config[key] = content 291 | } 292 | 293 | # Save to env 294 | system "bitrise envman add --key BUILD_CONFIG --value '#{build_config.to_json}' --no-expand" unless DEBUG_MODE 295 | system "bitrise envman add --key EXPORT_METHOD --value #{export_method} --no-expand" unless DEBUG_MODE 296 | system "bitrise envman add --key HOCKEY_UPLOAD_FLAG --value '#{hockey_upload}' --no-expand" unless DEBUG_MODE 297 | system "bitrise envman add --key TESTFLIGHT_UPLOAD_FLAG --value '#{testflight_upload}' --no-expand" unless DEBUG_MODE 298 | system "bitrise envman add --key SLACK_CHANNEL --value '#{project_settings['slack-channel']}' --no-expand " unless DEBUG_MODE 299 | system "bitrise envman add --key CI_VERSION --value '#{ci_version}' --no-expand " unless DEBUG_MODE 300 | puts green "|- Succesfully generated build config." 301 | pp build_config unless not VERBOSE 302 | -------------------------------------------------------------------------------- /versions/1.0-beta/parse_project_settings.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'yaml' 3 | require 'xcodeproj' 4 | require 'fileutils' 5 | require 'pp' 6 | require 'plist' 7 | require 'hockeyver' 8 | require 'json' 9 | 10 | # ------- 11 | # Constants 12 | # ------- 13 | 14 | PROJECT_FILE_NAME='project.yml' 15 | TARGET_FILE='build_config.json' 16 | DEBUG_MODE=false 17 | VERBOSE=false 18 | 19 | # ------- 20 | # Helpers 21 | # ------- 22 | 23 | def colorize(text, color_code) 24 | "\e[#{color_code}m#{text}\e[0m" 25 | end 26 | def red(text); colorize(text, 31); end 27 | def green(text); colorize(text, 32); end 28 | def yellow(text); colorize(text, 33); end 29 | def bold(text); "\e[1m#{text}\e[22m" end 30 | 31 | class Version < Array 32 | def initialize s 33 | super(s.split('.').map { |e| e.to_i }) 34 | end 35 | def < x 36 | (self <=> x) < 0 37 | end 38 | def > x 39 | (self <=> x) > 0 40 | end 41 | def == x 42 | (self <=> x) == 0 43 | end 44 | def >= x 45 | (self <=> x) >= 0 46 | end 47 | end 48 | 49 | def addErrorMessage(message) 50 | File.open('error_message', 'w') { |file| file.write(message) } 51 | end 52 | 53 | # ------- 54 | # Main 55 | # ------- 56 | 57 | # Load YAML 58 | puts bold "Loading settings from #{PROJECT_FILE_NAME}" 59 | unless File.exist?(PROJECT_FILE_NAME) 60 | message = "|- Couldn't find project.yml file" 61 | addErrorMessage(message) 62 | raise red message 63 | end 64 | 65 | project_settings = YAML.load_file(PROJECT_FILE_NAME) 66 | 67 | # Load some settings 68 | xcodeproj_path = project_settings['xcodeproj'] 69 | configuration = project_settings["configuration"] 70 | PROJECT_ROOT_DIR = File.dirname(xcodeproj_path) + "/" 71 | export_method = project_settings['method'] ||= "app-store" 72 | ci_version = project_settings['ci-version'] 73 | 74 | # Load Xcode project 75 | unless File.exist?(xcodeproj_path) 76 | message = "|- Couldn't find Xcode project at: #{xcodeproj_path}" 77 | addErrorMessage(message) 78 | raise red message 79 | end 80 | 81 | xcode_project = Xcodeproj::Project.open xcodeproj_path 82 | 83 | # Validate configuration 84 | avialable_configurations = xcode_project.build_configurations.map { |x| 85 | puts "|- #{x.name}" if VERBOSE 86 | x.name 87 | } 88 | unless avialable_configurations.include? configuration 89 | message = "|- Can't find configuration #{configuration}" 90 | addErrorMessage(message) 91 | raise red message 92 | end 93 | 94 | # Notify 95 | puts green "|- Settings loaded succesfully with configuration: #{project_settings["configuration"]}." 96 | 97 | # Load upload settings 98 | hockey_upload = project_settings['hockey-upload'] ? 1 : 0 99 | testflight_upload = project_settings['testflight-upload'] ? 1 : 0 100 | puts "" 101 | puts bold "Checking upload settings" 102 | if hockey_upload == 1 103 | puts green "|- Will upload to hockey" 104 | else 105 | puts yellow "|- Skipping hockey upload" 106 | end 107 | if testflight_upload == 1 108 | puts green "|- Will upload to testflight" 109 | else 110 | puts yellow "|- Skipping testflight upload" 111 | end 112 | 113 | 114 | # Get available targets 115 | validated_targets = Hash.new 116 | 117 | # Validate targets 118 | puts "" 119 | puts bold "Validating target settings" 120 | project_settings["targets"].each_pair { |key, val| 121 | xcode_target = xcode_project.targets.select { |tar| tar.name == key }.first 122 | 123 | # Check for target existence 124 | if xcode_target.nil? 125 | puts yellow "|- Skipping target #{key}, as Xcode doesn't contain corresponding target." 126 | next 127 | end 128 | 129 | # Check if enabled 130 | unless val["enabled"] 131 | puts yellow "|- Skipping target #{key}, because it is disabled." 132 | next 133 | end 134 | 135 | # Validate scheme 136 | unless Xcodeproj::Project.schemes(xcodeproj_path).include? val["scheme"] 137 | puts yellow """|- Skipping target #{key}, because the specified scheme can't be found. 138 | Did you set it the scheme as shared?""" 139 | next 140 | end 141 | 142 | puts green "|- Found valid target #{key}." 143 | validated_targets[key] = { "settings" => val, "target" => xcode_target } 144 | } 145 | 146 | 147 | # Make sure we have something to build 148 | unless validated_targets.count > 0 149 | message = "|- No valid targets to build, build failed." 150 | addErrorMessage(message) 151 | raise red message 152 | end 153 | 154 | # Temp fix for riide, will make this more reusable in the future. This breaks down the 155 | # targets into groups of 6, and uses the RIIDE_PROJECT env var to determine which 156 | # of the subset to use 157 | length = 6 158 | if validated_targets.count > length 159 | start = ENV["RIIDE_PROJECT"].to_i * length 160 | start -= length 161 | validated_targets = validated_targets.select { |k, v| validated_targets.keys[start, length].include? k } 162 | end 163 | 164 | puts "" 165 | puts bold "Starting Hockey versions verification" 166 | 167 | valid = true 168 | 169 | unless DEBUG_MODE 170 | # Get version and build numbers 171 | message = "" 172 | validated_targets.each_pair { |key, val| 173 | 174 | # Find the correct configuration 175 | configs = val["target"].build_configurations 176 | index = configs.index { |x| x.name == configuration } 177 | 178 | # Get info plist 179 | info_plist = configs[index].build_settings["INFOPLIST_FILE"] 180 | info_plist_path = PROJECT_ROOT_DIR + info_plist 181 | 182 | plist = Plist.parse_xml info_plist_path 183 | xcode_version = plist["CFBundleShortVersionString"] 184 | xcode_build = plist["CFBundleVersion"].to_i 185 | 186 | puts "|- Verifying '#{key}' with version #{xcode_version} (#{xcode_build})." 187 | 188 | # Get hockey app id object 189 | hockey_app_id = val["settings"]["hockey-app-id"] 190 | 191 | # Figure out if hockey app id object is a hash (for configuration mapping to ids) 192 | # or a String with static hockey app id 193 | if hockey_app_id.respond_to?(:has_key?) then 194 | raise red """|- HockeyApp app id is missing for the current configuration, please add it or switch to static app id.""" unless hockey_app_id.has_key?(configuration) 195 | 196 | # Parse from nested dict 197 | hockey_app_id = hockey_app_id[configuration] 198 | val["settings"]["hockey-app-id"] = hockey_app_id 199 | end 200 | 201 | # Check if hockey id is filled in correctly 202 | if hockey_app_id.empty? || !hockey_app_id.is_a?(String) then 203 | raise red """|- HockeyApp app id is missing, can't continue with build as version and build number can't be verified. 204 | All apps should have an associated HockeyApp app.""" 205 | end 206 | 207 | buildnumber = HockeyVer.parse_hockey_version hockey_app_id, ENV["HOCKEY_API_TOKEN"] 208 | 209 | # Check if build number from hockey is nil 210 | if buildnumber.nil? 211 | puts yellow "|- No build found on Hockey, proceeding with build" 212 | next 213 | end 214 | 215 | hockey_version = buildnumber["version"] 216 | hockey_build = buildnumber["build"].to_i 217 | 218 | # Compare, make sure that build is always higher and version is at least higher or equal 219 | unless (Version.new(xcode_version) >= Version.new(hockey_version)) && (xcode_build > hockey_build) 220 | valid = false 221 | warning_message = """#{key}: Xcode version #{xcode_version} (#{xcode_build}) is lower or equal than the one on Hockey #{hockey_version} (#{hockey_build}).""" 222 | message +="#{warning_message} \n" 223 | puts yellow "|- #{warning_message}" 224 | end 225 | } 226 | end 227 | 228 | # Check if we can continue 229 | unless valid 230 | message += "Can't continue with build, as version and build numbers must be higher than the ones on Hockey." 231 | addErrorMessage(message) 232 | raise red message 233 | end 234 | 235 | 236 | # All done 237 | puts green "|- All version and build numbers are correct." 238 | 239 | puts "" 240 | puts bold "Creating information required for build" 241 | 242 | build_config = Hash.new 243 | 244 | validated_targets.each_pair { |key, val| 245 | content = val['settings'] 246 | 247 | # Pass platform, xcodeproj 248 | content['xcodeproj'] = xcode_project.path.to_path 249 | content['workspace'] = project_settings['workspace'] 250 | content['platform'] = val['target'].platform_name 251 | content['configuration'] = configuration 252 | content['bundle_id'] = val['target'].build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] 253 | 254 | # Get extensions from content and remove them (will re-added if validated) 255 | extensions_bundle_ids = content['extensions-bundle-ids'] ||= Array.new 256 | content['extensions-bundle-ids'] = Hash.new 257 | 258 | # Validate extensions 259 | extensions_bundle_ids.each { |extension_id| 260 | # Fetch extension target 261 | extension_target = xcode_project.targets.select { |tar| 262 | tar.build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] == extension_id 263 | }.first 264 | 265 | # If we didn't find extesion, skip to next one 266 | if extension_target.nil? 267 | puts yellow "Skipping extension with bundle id #{extension_id} as a target with this id does not exist." 268 | next 269 | end 270 | 271 | # Bail if not an extension type 272 | unless extension_target.extension_target_type? 273 | puts yellow "Skipping extension with bundle id #{extension_id} as this target is not an extension target." 274 | next 275 | end 276 | 277 | # Add validated ID to extensions hash 278 | content['extensions-bundle-ids'][extension_target.name] = extension_id 279 | } 280 | 281 | # Extract build number 282 | info_plist = val['target'].build_settings(configuration)["INFOPLIST_FILE"] 283 | info_plist_path = PROJECT_ROOT_DIR + info_plist 284 | plist = Plist.parse_xml info_plist_path 285 | xcode_version = plist["CFBundleShortVersionString"] 286 | xcode_build = plist["CFBundleVersion"].to_i 287 | content['xcode_version'] = "#{xcode_version}" 288 | content['xcode_build'] = "#{xcode_build}" 289 | 290 | build_config[key] = content 291 | } 292 | 293 | # Save to env 294 | system "bitrise envman add --key BUILD_CONFIG --value '#{build_config.to_json}' --no-expand" unless DEBUG_MODE 295 | system "bitrise envman add --key EXPORT_METHOD --value #{export_method} --no-expand" unless DEBUG_MODE 296 | system "bitrise envman add --key HOCKEY_UPLOAD_FLAG --value '#{hockey_upload}' --no-expand" unless DEBUG_MODE 297 | system "bitrise envman add --key TESTFLIGHT_UPLOAD_FLAG --value '#{testflight_upload}' --no-expand" unless DEBUG_MODE 298 | system "bitrise envman add --key SLACK_CHANNEL --value '#{project_settings['slack-channel']}' --no-expand " unless DEBUG_MODE 299 | system "bitrise envman add --key CI_VERSION --value '#{ci_version}' --no-expand " unless DEBUG_MODE 300 | puts green "|- Succesfully generated build config." 301 | pp build_config unless not VERBOSE 302 | -------------------------------------------------------------------------------- /versions/development/parse_project_settings.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'yaml' 3 | require 'xcodeproj' 4 | require 'fileutils' 5 | require 'pp' 6 | require 'plist' 7 | require 'hockeyver' 8 | require 'json' 9 | require 'zip' 10 | 11 | # ------- 12 | # Constants 13 | # ------- 14 | 15 | PROJECT_FILE_NAME='project.yml' 16 | TARGET_FILE='build_config.json' 17 | DEBUG_MODE=false 18 | VERBOSE=false 19 | 20 | # ------- 21 | # Helpers 22 | # ------- 23 | 24 | def colorize(text, color_code) 25 | "\e[#{color_code}m#{text}\e[0m" 26 | end 27 | def red(text); colorize(text, 31); end 28 | def green(text); colorize(text, 32); end 29 | def yellow(text); colorize(text, 33); end 30 | def bold(text); "\e[1m#{text}\e[22m" end 31 | 32 | class Version < Array 33 | def initialize s 34 | super(s.split('.').map { |e| e.to_i }) 35 | end 36 | def < x 37 | (self <=> x) < 0 38 | end 39 | def > x 40 | (self <=> x) > 0 41 | end 42 | def == x 43 | (self <=> x) == 0 44 | end 45 | def >= x 46 | (self <=> x) >= 0 47 | end 48 | end 49 | 50 | def addErrorMessage(message) 51 | File.open('error_message', 'w') { |file| file.write(message) } 52 | end 53 | 54 | # ------- 55 | # Main 56 | # ------- 57 | 58 | # Load YAML 59 | puts bold "Loading settings from #{PROJECT_FILE_NAME}" 60 | unless File.exist?(PROJECT_FILE_NAME) 61 | message = "|- Couldn't find project.yml file" 62 | addErrorMessage(message) 63 | raise red message 64 | end 65 | 66 | project_settings = YAML.load_file(PROJECT_FILE_NAME) 67 | 68 | # Load some settings 69 | xcodeproj_path = project_settings['xcodeproj'] 70 | configuration = project_settings["configuration"] 71 | PROJECT_ROOT_DIR = File.dirname(xcodeproj_path) + "/" 72 | ci_version = project_settings['ci-version'] 73 | 74 | # Load Xcode project 75 | unless File.exist?(xcodeproj_path) 76 | message = "|- Couldn't find Xcode project at: #{xcodeproj_path}" 77 | addErrorMessage(message) 78 | raise red message 79 | end 80 | 81 | xcode_project = Xcodeproj::Project.open xcodeproj_path 82 | 83 | # Validate configuration 84 | avialable_configurations = xcode_project.build_configurations.map { |x| 85 | puts "|- #{x.name}" if VERBOSE 86 | x.name 87 | } 88 | unless avialable_configurations.include? configuration 89 | message = "|- Can't find configuration #{configuration}" 90 | addErrorMessage(message) 91 | raise red message 92 | end 93 | 94 | # Notify 95 | puts green "|- Settings loaded succesfully with configuration: #{project_settings["configuration"]} and export method: #{project_settings["export-method"]}." 96 | 97 | # Load upload settings 98 | export_method = project_settings['export-method'] 99 | hockey_upload = project_settings['hockey-upload'] ? 1 : 0 100 | testflight_upload = project_settings['testflight-upload'] ? 1 : 0 101 | obfucaste_code_for_archive = project_settings['obfuscate'] ? 1 : 0 102 | 103 | puts "" 104 | puts bold "Checking upload settings" 105 | if hockey_upload == 1 106 | puts green "|- Will upload to hockey" 107 | else 108 | puts yellow "|- Skipping hockey upload" 109 | end 110 | if testflight_upload == 1 111 | puts green "|- Will upload to testflight" 112 | else 113 | puts yellow "|- Skipping testflight upload" 114 | end 115 | if obfucaste_code_for_archive == 1 116 | puts green "|- Will obfuscate code" 117 | else 118 | puts yellow "|- Skipping code obfuscation" 119 | end 120 | 121 | # Get available targets 122 | validated_targets = Hash.new 123 | 124 | # Validate targets 125 | puts "" 126 | puts bold "Validating target settings" 127 | project_settings["targets"].each_pair { |key, val| 128 | xcode_target = xcode_project.targets.select { |tar| tar.name == key }.first 129 | 130 | # Check for target existence 131 | if xcode_target.nil? 132 | puts yellow "|- Skipping target #{key}, as Xcode doesn't contain corresponding target." 133 | next 134 | end 135 | 136 | # Check if enabled 137 | unless val["enabled"] 138 | puts yellow "|- Skipping target #{key}, because it is disabled." 139 | next 140 | end 141 | 142 | # Validate scheme 143 | unless Xcodeproj::Project.schemes(xcodeproj_path).include? val["scheme"] 144 | puts yellow """|- Skipping target #{key}, because the specified scheme can't be found. 145 | Did you set it the scheme as shared?""" 146 | next 147 | end 148 | 149 | puts green "|- Found valid target #{key}." 150 | validated_targets[key] = { "settings" => val, "target" => xcode_target } 151 | } 152 | 153 | 154 | # Make sure we have something to build 155 | unless validated_targets.count > 0 156 | message = "|- No valid targets to build, build failed." 157 | addErrorMessage(message) 158 | raise red message 159 | end 160 | 161 | # Temp fix for riide, will make this more reusable in the future. This breaks down the 162 | # targets into groups of 6, and uses the RIIDE_PROJECT env var to determine which 163 | # of the subset to use 164 | length = 6 165 | if validated_targets.count > length 166 | start = ENV["RIIDE_PROJECT"].to_i * length 167 | start -= length 168 | validated_targets = validated_targets.select { |k, v| validated_targets.keys[start, length].include? k } 169 | end 170 | 171 | puts "" 172 | puts bold "Starting Hockey versions verification" 173 | 174 | valid = true 175 | 176 | unless DEBUG_MODE 177 | # Get version and build numbers 178 | message = "" 179 | validated_targets.each_pair { |key, val| 180 | 181 | # Find the correct configuration 182 | configs = val["target"].build_configurations 183 | index = configs.index { |x| x.name == configuration } 184 | 185 | # Get info plist 186 | info_plist = configs[index].build_settings["INFOPLIST_FILE"] 187 | info_plist_path = PROJECT_ROOT_DIR + info_plist 188 | 189 | plist = Plist.parse_xml info_plist_path 190 | xcode_version = plist["CFBundleShortVersionString"] 191 | xcode_build = plist["CFBundleVersion"].to_i 192 | 193 | puts "|- Verifying '#{key}' with version #{xcode_version} (#{xcode_build})." 194 | 195 | # Get hockey app id object 196 | hockey_app_id = val["settings"]["hockey-app-id"] 197 | 198 | # Figure out if hockey app id object is a hash (for configuration mapping to ids) 199 | # or a String with static hockey app id 200 | if hockey_app_id.respond_to?(:has_key?) then 201 | raise red """|- HockeyApp app id is missing for the current configuration, please add it or switch to static app id.""" unless hockey_app_id.has_key?(configuration) 202 | 203 | # Parse from nested dict 204 | hockey_app_id = hockey_app_id[configuration] 205 | val["settings"]["hockey-app-id"] = hockey_app_id 206 | end 207 | 208 | # Check if hockey id is filled in correctly 209 | if hockey_app_id.empty? || !hockey_app_id.is_a?(String) then 210 | raise red """|- HockeyApp app id is missing, can't continue with build as version and build number can't be verified. 211 | All apps should have an associated HockeyApp app.""" 212 | end 213 | 214 | buildnumber = HockeyVer.parse_hockey_version hockey_app_id, ENV["HOCKEY_API_TOKEN"] 215 | 216 | # Check if build number from hockey is nil 217 | if buildnumber.nil? 218 | puts yellow "|- No build found on Hockey, proceeding with build" 219 | next 220 | end 221 | 222 | hockey_version = buildnumber["version"] 223 | hockey_build = buildnumber["build"].to_i 224 | 225 | # Compare, make sure that build is always higher and version is at least higher or equal 226 | unless (Version.new(xcode_version) >= Version.new(hockey_version)) && (xcode_build > hockey_build) 227 | valid = false 228 | warning_message = """#{key}: Xcode version #{xcode_version} (#{xcode_build}) is lower or equal than the one on Hockey #{hockey_version} (#{hockey_build}).""" 229 | message +="#{warning_message} \n" 230 | puts yellow "|- #{warning_message}" 231 | end 232 | } 233 | end 234 | 235 | # Check if we can continue 236 | unless valid 237 | message += "Can't continue with build, as version and build numbers must be higher than the ones on Hockey." 238 | addErrorMessage(message) 239 | raise red message 240 | end 241 | 242 | 243 | # All done 244 | puts green "|- All version and build numbers are correct." 245 | 246 | puts "" 247 | puts bold "Creating information required for build" 248 | 249 | build_config = Hash.new 250 | 251 | validated_targets.each_pair { |key, val| 252 | content = val['settings'] 253 | 254 | # Pass platform, xcodeproj 255 | content['xcodeproj'] = xcode_project.path.to_path 256 | content['workspace'] = project_settings['workspace'] 257 | content['platform'] = val['target'].platform_name 258 | content['configuration'] = configuration 259 | content['bundle_id'] = val['target'].build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] 260 | 261 | # Get extensions from content and remove them (will re-added if validated) 262 | extensions_bundle_ids = content['extensions-bundle-ids'] ||= Array.new 263 | content['extensions-bundle-ids'] = Hash.new 264 | 265 | # Validate extensions 266 | extensions_bundle_ids.each { |extension_id| 267 | # Fetch extension target 268 | extension_target = xcode_project.targets.select { |tar| 269 | tar.build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] == extension_id 270 | }.first 271 | 272 | # If we didn't find extesion, skip to next one 273 | if extension_target.nil? 274 | puts yellow "Skipping extension with bundle id #{extension_id} as a target with this id does not exist." 275 | next 276 | end 277 | 278 | # Bail if not an extension type 279 | unless extension_target.extension_target_type? 280 | puts yellow "Skipping extension with bundle id #{extension_id} as this target is not an extension target." 281 | next 282 | end 283 | 284 | # Add validated ID to extensions hash 285 | content['extensions-bundle-ids'][extension_target.name] = extension_id 286 | } 287 | 288 | # Extract build number 289 | info_plist = val['target'].build_settings(configuration)["INFOPLIST_FILE"] 290 | info_plist_path = PROJECT_ROOT_DIR + info_plist 291 | plist = Plist.parse_xml info_plist_path 292 | xcode_version = plist["CFBundleShortVersionString"] 293 | xcode_build = plist["CFBundleVersion"].to_i 294 | content['xcode_version'] = "#{xcode_version}" 295 | content['xcode_build'] = "#{xcode_build}" 296 | 297 | build_config[key] = content 298 | } 299 | 300 | # Save to env 301 | system "bitrise envman add --key BUILD_CONFIG --value '#{build_config.to_json}' --no-expand" unless DEBUG_MODE 302 | system "bitrise envman add --key EXPORT_METHOD --value '#{export_method}' --no-expand" unless DEBUG_MODE 303 | system "bitrise envman add --key HOCKEY_UPLOAD_FLAG --value '#{hockey_upload}' --no-expand" unless DEBUG_MODE 304 | system "bitrise envman add --key TESTFLIGHT_UPLOAD_FLAG --value '#{testflight_upload}' --no-expand" unless DEBUG_MODE 305 | system "bitrise envman add --key SLACK_CHANNEL --value '#{project_settings['slack-channel']}' --no-expand " unless DEBUG_MODE 306 | system "bitrise envman add --key OBFUSCATE_CODE --value '#{obfucaste_code_for_archive}' --no-expand " unless DEBUG_MODE 307 | system "bitrise envman add --key CI_VERSION --value '#{ci_version}' --no-expand " unless DEBUG_MODE 308 | puts green "|- Succesfully generated build config." 309 | pp build_config unless not VERBOSE 310 | -------------------------------------------------------------------------------- /versions/1.1-beta/parse_project_settings.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'yaml' 3 | require 'xcodeproj' 4 | require 'fileutils' 5 | require 'pp' 6 | require 'plist' 7 | require 'hockeyver' 8 | require 'json' 9 | 10 | # ------- 11 | # Constants 12 | # ------- 13 | 14 | PROJECT_FILE_NAME='project.yml' 15 | TARGET_FILE='build_config.json' 16 | DEBUG_MODE=false 17 | VERBOSE=false 18 | 19 | # ------- 20 | # Helpers 21 | # ------- 22 | 23 | def colorize(text, color_code) 24 | "\e[#{color_code}m#{text}\e[0m" 25 | end 26 | def red(text); colorize(text, 31); end 27 | def green(text); colorize(text, 32); end 28 | def yellow(text); colorize(text, 33); end 29 | def bold(text); "\e[1m#{text}\e[22m" end 30 | 31 | class Version < Array 32 | def initialize s 33 | super(s.split('.').map { |e| e.to_i }) 34 | end 35 | def < x 36 | (self <=> x) < 0 37 | end 38 | def > x 39 | (self <=> x) > 0 40 | end 41 | def == x 42 | (self <=> x) == 0 43 | end 44 | def >= x 45 | (self <=> x) >= 0 46 | end 47 | end 48 | 49 | def addErrorMessage(message) 50 | File.open('error_message', 'w') { |file| file.write(message) } 51 | end 52 | 53 | # ------- 54 | # Main 55 | # ------- 56 | 57 | # Load YAML 58 | puts bold "Loading settings from #{PROJECT_FILE_NAME}" 59 | unless File.exist?(PROJECT_FILE_NAME) 60 | message = "|- Couldn't find project.yml file" 61 | addErrorMessage(message) 62 | raise red message 63 | end 64 | 65 | project_settings = YAML.load_file(PROJECT_FILE_NAME) 66 | 67 | # Load some settings 68 | xcodeproj_path = project_settings['xcodeproj'] 69 | configuration = project_settings["configuration"] 70 | PROJECT_ROOT_DIR = File.dirname(xcodeproj_path) + "/" 71 | export_method = project_settings['method'] ||= "app-store" 72 | ci_version = project_settings['ci-version'] 73 | 74 | # Load Xcode project 75 | unless File.exist?(xcodeproj_path) 76 | message = "|- Couldn't find Xcode project at: #{xcodeproj_path}" 77 | addErrorMessage(message) 78 | raise red message 79 | end 80 | 81 | xcode_project = Xcodeproj::Project.open xcodeproj_path 82 | 83 | # Validate configuration 84 | avialable_configurations = xcode_project.build_configurations.map { |x| 85 | puts "|- #{x.name}" if VERBOSE 86 | x.name 87 | } 88 | unless avialable_configurations.include? configuration 89 | message = "|- Can't find configuration #{configuration}" 90 | addErrorMessage(message) 91 | raise red message 92 | end 93 | 94 | # Notify 95 | puts green "|- Settings loaded succesfully with configuration: #{project_settings["configuration"]}." 96 | 97 | # Load upload settings 98 | hockey_upload = project_settings['hockey-upload'] ? 1 : 0 99 | testflight_upload = project_settings['testflight-upload'] ? 1 : 0 100 | puts "" 101 | puts bold "Checking upload settings" 102 | if hockey_upload == 1 103 | puts green "|- Will upload to hockey" 104 | else 105 | puts yellow "|- Skipping hockey upload" 106 | end 107 | if testflight_upload == 1 108 | puts green "|- Will upload to testflight" 109 | else 110 | puts yellow "|- Skipping testflight upload" 111 | end 112 | 113 | 114 | # Get available targets 115 | validated_targets = Hash.new 116 | 117 | # Validate targets 118 | puts "" 119 | puts bold "Validating target settings" 120 | project_settings["targets"].each_pair { |key, val| 121 | xcode_target = xcode_project.targets.select { |tar| tar.name == key }.first 122 | 123 | # Check for target existence 124 | if xcode_target.nil? 125 | puts yellow "|- Skipping target #{key}, as Xcode doesn't contain corresponding target." 126 | next 127 | end 128 | 129 | # Check if enabled 130 | unless val["enabled"] 131 | puts yellow "|- Skipping target #{key}, because it is disabled." 132 | next 133 | end 134 | 135 | # Validate scheme 136 | unless Xcodeproj::Project.schemes(xcodeproj_path).include? val["scheme"] 137 | puts yellow """|- Skipping target #{key}, because the specified scheme can't be found. 138 | Did you set it the scheme as shared?""" 139 | next 140 | end 141 | 142 | puts green "|- Found valid target #{key}." 143 | validated_targets[key] = { "settings" => val, "target" => xcode_target } 144 | } 145 | 146 | 147 | # Make sure we have something to build 148 | unless validated_targets.count > 0 149 | message = "|- No valid targets to build, build failed." 150 | addErrorMessage(message) 151 | raise red message 152 | end 153 | 154 | # Temp fix for riide, will make this more reusable in the future. This breaks down the 155 | # targets into groups of 6, and uses the RIIDE_PROJECT env var to determine which 156 | # of the subset to use 157 | length = 6 158 | if validated_targets.count > length 159 | start = ENV["RIIDE_PROJECT"].to_i * length 160 | start -= length 161 | validated_targets = validated_targets.select { |k, v| validated_targets.keys[start, length].include? k } 162 | end 163 | 164 | puts "" 165 | puts bold "Starting Hockey versions verification" 166 | 167 | valid = true 168 | 169 | unless DEBUG_MODE 170 | # Get version and build numbers 171 | message = "" 172 | validated_targets.each_pair { |key, val| 173 | 174 | # Find the correct configuration 175 | configs = val["target"].build_configurations 176 | index = configs.index { |x| x.name == configuration } 177 | 178 | # Get info plist 179 | info_plist = configs[index].build_settings["INFOPLIST_FILE"] 180 | info_plist_path = PROJECT_ROOT_DIR + info_plist 181 | 182 | plist = Plist.parse_xml info_plist_path 183 | xcode_version = plist["CFBundleShortVersionString"] 184 | xcode_build = plist["CFBundleVersion"].to_i 185 | 186 | puts "|- Verifying '#{key}' with version #{xcode_version} (#{xcode_build})." 187 | 188 | # Get hockey app id object 189 | hockey_app_id = val["settings"]["hockey-app-id"] 190 | 191 | # Figure out if hockey app id object is a hash (for configuration mapping to ids) 192 | # or a String with static hockey app id 193 | if hockey_app_id.respond_to?(:has_key?) then 194 | raise red """|- HockeyApp app id is missing for the current configuration, please add it or switch to static app id.""" unless hockey_app_id.has_key?(configuration) 195 | 196 | # Parse from nested dict 197 | hockey_app_id = hockey_app_id[configuration] 198 | val["settings"]["hockey-app-id"] = hockey_app_id 199 | end 200 | 201 | # Check if hockey id is filled in correctly 202 | if hockey_app_id.empty? || !hockey_app_id.is_a?(String) then 203 | raise red """|- HockeyApp app id is missing, can't continue with build as version and build number can't be verified. 204 | All apps should have an associated HockeyApp app.""" 205 | end 206 | 207 | disable_hockey_version_check = project_settings['disable-hockey-version-check'] ? true : false 208 | 209 | if disable_hockey_version_check 210 | puts yellow "Hockey version number check is disabled. The build will fail uploading to TestFlight if you try to upload an already existing version." 211 | end 212 | 213 | #If hockey check has been disabled, skip version check 214 | unless disable_hockey_version_check 215 | buildnumber = HockeyVer.parse_hockey_version hockey_app_id, ENV["HOCKEY_API_TOKEN"] 216 | 217 | # Check if build number from hockey is nil 218 | if buildnumber.nil? 219 | puts yellow "|- No build found on Hockey, proceeding with build" 220 | next 221 | end 222 | 223 | hockey_version = buildnumber["version"] 224 | hockey_build = buildnumber["build"].to_i 225 | 226 | # Compare, make sure that build is always higher and version is at least higher or equal 227 | 228 | unless (Version.new(xcode_version) >= Version.new(hockey_version)) && (xcode_build > hockey_build) 229 | valid = false 230 | warning_message = """#{key}: Xcode version #{xcode_version} (#{xcode_build}) is lower or equal than the one on Hockey #{hockey_version} (#{hockey_build}).""" 231 | message +="#{warning_message} \n" 232 | puts yellow "|- #{warning_message}" 233 | end 234 | end 235 | } 236 | end 237 | 238 | # Check if we can continue 239 | unless valid 240 | message += "Can't continue with build, as version and build numbers must be higher than the ones on Hockey." 241 | addErrorMessage(message) 242 | raise red message 243 | end 244 | 245 | 246 | # All done 247 | puts green "|- All version and build numbers are correct." 248 | 249 | puts "" 250 | puts bold "Creating information required for build" 251 | 252 | build_config = Hash.new 253 | 254 | validated_targets.each_pair { |key, val| 255 | content = val['settings'] 256 | 257 | # Pass platform, xcodeproj 258 | content['xcodeproj'] = xcode_project.path.to_path 259 | content['workspace'] = project_settings['workspace'] 260 | content['platform'] = val['target'].platform_name 261 | content['configuration'] = configuration 262 | content['bundle_id'] = val['target'].build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] 263 | 264 | # Get extensions from content and remove them (will re-added if validated) 265 | extensions_bundle_ids = content['extensions-bundle-ids'] ||= Array.new 266 | content['extensions-bundle-ids'] = Hash.new 267 | 268 | # Validate extensions 269 | extensions_bundle_ids.each { |extension_id| 270 | # Fetch extension target 271 | extension_target = xcode_project.targets.select { |tar| 272 | tar.build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] == extension_id 273 | }.first 274 | 275 | # If we didn't find extesion, skip to next one 276 | if extension_target.nil? 277 | puts yellow "Skipping extension with bundle id #{extension_id} as a target with this id does not exist." 278 | next 279 | end 280 | 281 | # Bail if not an extension type 282 | unless extension_target.extension_target_type? 283 | puts yellow "Skipping extension with bundle id #{extension_id} as this target is not an extension target." 284 | next 285 | end 286 | 287 | # Add validated ID to extensions hash 288 | content['extensions-bundle-ids'][extension_target.name] = extension_id 289 | } 290 | 291 | # Extract build number 292 | info_plist = val['target'].build_settings(configuration)["INFOPLIST_FILE"] 293 | info_plist_path = PROJECT_ROOT_DIR + info_plist 294 | plist = Plist.parse_xml info_plist_path 295 | xcode_version = plist["CFBundleShortVersionString"] 296 | xcode_build = plist["CFBundleVersion"].to_i 297 | content['xcode_version'] = "#{xcode_version}" 298 | content['xcode_build'] = "#{xcode_build}" 299 | 300 | build_config[key] = content 301 | } 302 | 303 | # Save to env 304 | system "bitrise envman add --key BUILD_CONFIG --value '#{build_config.to_json}' --no-expand" unless DEBUG_MODE 305 | system "bitrise envman add --key EXPORT_METHOD --value #{export_method} --no-expand" unless DEBUG_MODE 306 | system "bitrise envman add --key HOCKEY_UPLOAD_FLAG --value '#{hockey_upload}' --no-expand" unless DEBUG_MODE 307 | system "bitrise envman add --key TESTFLIGHT_UPLOAD_FLAG --value '#{testflight_upload}' --no-expand" unless DEBUG_MODE 308 | system "bitrise envman add --key SLACK_CHANNEL --value '#{project_settings['slack-channel']}' --no-expand " unless DEBUG_MODE 309 | system "bitrise envman add --key CI_VERSION --value '#{ci_version}' --no-expand " unless DEBUG_MODE 310 | puts green "|- Succesfully generated build config." 311 | pp build_config unless not VERBOSE 312 | -------------------------------------------------------------------------------- /versions/1.3/parse_project_settings.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'yaml' 3 | require 'xcodeproj' 4 | require 'fileutils' 5 | require 'pp' 6 | require 'plist' 7 | require 'hockeyver' 8 | require 'json' 9 | require 'zip' 10 | 11 | # ------- 12 | # Constants 13 | # ------- 14 | 15 | PROJECT_FILE_NAME='project.yml' 16 | TARGET_FILE='build_config.json' 17 | DEBUG_MODE=false 18 | VERBOSE=false 19 | 20 | # ------- 21 | # Helpers 22 | # ------- 23 | 24 | def colorize(text, color_code) 25 | "\e[#{color_code}m#{text}\e[0m" 26 | end 27 | def red(text); colorize(text, 31); end 28 | def green(text); colorize(text, 32); end 29 | def yellow(text); colorize(text, 33); end 30 | def bold(text); "\e[1m#{text}\e[22m" end 31 | 32 | class Version < Array 33 | def initialize s 34 | super(s.split('.').map { |e| e.to_i }) 35 | end 36 | def < x 37 | (self <=> x) < 0 38 | end 39 | def > x 40 | (self <=> x) > 0 41 | end 42 | def == x 43 | (self <=> x) == 0 44 | end 45 | def >= x 46 | (self <=> x) >= 0 47 | end 48 | end 49 | 50 | def addErrorMessage(message) 51 | File.open('error_message', 'w') { |file| file.write(message) } 52 | end 53 | 54 | # ------- 55 | # Main 56 | # ------- 57 | 58 | # Load YAML 59 | puts bold "Loading settings from #{PROJECT_FILE_NAME}" 60 | unless File.exist?(PROJECT_FILE_NAME) 61 | message = "|- Couldn't find project.yml file" 62 | addErrorMessage(message) 63 | raise red message 64 | end 65 | 66 | project_settings = YAML.load_file(PROJECT_FILE_NAME) 67 | 68 | # Load some settings 69 | xcodeproj_path = project_settings['xcodeproj'] 70 | configuration = project_settings["configuration"] 71 | PROJECT_ROOT_DIR = File.dirname(xcodeproj_path) + "/" 72 | ci_version = project_settings['ci-version'] 73 | 74 | # Load Xcode project 75 | unless File.exist?(xcodeproj_path) 76 | message = "|- Couldn't find Xcode project at: #{xcodeproj_path}" 77 | addErrorMessage(message) 78 | raise red message 79 | end 80 | 81 | xcode_project = Xcodeproj::Project.open xcodeproj_path 82 | 83 | # Validate configuration 84 | avialable_configurations = xcode_project.build_configurations.map { |x| 85 | puts "|- #{x.name}" if VERBOSE 86 | x.name 87 | } 88 | unless avialable_configurations.include? configuration 89 | message = "|- Can't find configuration #{configuration}" 90 | addErrorMessage(message) 91 | raise red message 92 | end 93 | 94 | # Notify 95 | puts green "|- Settings loaded succesfully with configuration: #{project_settings["configuration"]} and export method: #{project_settings["export-method"]}." 96 | 97 | # Load upload settings 98 | export_method = project_settings['export-method'] 99 | hockey_upload = project_settings['hockey-upload'] ? 1 : 0 100 | testflight_upload = project_settings['testflight-upload'] ? 1 : 0 101 | obfucaste_code_for_archive = project_settings['obfuscate'] ? 1 : 0 102 | 103 | puts "" 104 | puts bold "Checking upload settings" 105 | if hockey_upload == 1 106 | puts green "|- Will upload to hockey" 107 | else 108 | puts yellow "|- Skipping hockey upload" 109 | end 110 | if testflight_upload == 1 111 | puts green "|- Will upload to testflight" 112 | else 113 | puts yellow "|- Skipping testflight upload" 114 | end 115 | if obfucaste_code_for_archive == 1 116 | puts green "|- Will obfuscate code" 117 | else 118 | puts yellow "|- Skipping code obfuscation" 119 | end 120 | 121 | # Get available targets 122 | validated_targets = Hash.new 123 | 124 | # Validate targets 125 | puts "" 126 | puts bold "Validating target settings" 127 | project_settings["targets"].each_pair { |key, val| 128 | xcode_target = xcode_project.targets.select { |tar| tar.name == key }.first 129 | 130 | # Check for target existence 131 | if xcode_target.nil? 132 | puts yellow "|- Skipping target #{key}, as Xcode doesn't contain corresponding target." 133 | next 134 | end 135 | 136 | # Check if enabled 137 | unless val["enabled"] 138 | puts yellow "|- Skipping target #{key}, because it is disabled." 139 | next 140 | end 141 | 142 | # Validate scheme 143 | unless Xcodeproj::Project.schemes(xcodeproj_path).include? val["scheme"] 144 | puts yellow """|- Skipping target #{key}, because the specified scheme can't be found. 145 | Did you set it the scheme as shared?""" 146 | next 147 | end 148 | 149 | puts green "|- Found valid target #{key}." 150 | validated_targets[key] = { "settings" => val, "target" => xcode_target } 151 | } 152 | 153 | 154 | # Make sure we have something to build 155 | unless validated_targets.count > 0 156 | message = "|- No valid targets to build, build failed." 157 | addErrorMessage(message) 158 | raise red message 159 | end 160 | 161 | # Temp fix for riide, will make this more reusable in the future. This breaks down the 162 | # targets into groups of 6, and uses the RIIDE_PROJECT env var to determine which 163 | # of the subset to use 164 | length = 6 165 | if validated_targets.count > length 166 | start = ENV["RIIDE_PROJECT"].to_i * length 167 | start -= length 168 | validated_targets = validated_targets.select { |k, v| validated_targets.keys[start, length].include? k } 169 | end 170 | 171 | puts "" 172 | puts bold "Starting Hockey versions verification" 173 | 174 | valid = true 175 | 176 | unless DEBUG_MODE 177 | # Get version and build numbers 178 | message = "" 179 | validated_targets.each_pair { |key, val| 180 | 181 | # Find the correct configuration 182 | configs = val["target"].build_configurations 183 | index = configs.index { |x| x.name == configuration } 184 | 185 | # Get info plist 186 | info_plist = configs[index].build_settings["INFOPLIST_FILE"] 187 | info_plist_path = PROJECT_ROOT_DIR + info_plist 188 | 189 | plist = Plist.parse_xml info_plist_path 190 | xcode_version = configs[index].build_settings["MARKETING_VERSION"] ||= plist["CFBundleShortVersionString"] 191 | xcode_build_source = configs[index].build_settings["CURRENT_PROJECT_VERSION"] ||= plist["CFBundleVersion"] 192 | xcode_build = xcode_build_source.to_i 193 | 194 | puts "|- Verifying '#{key}' with version #{xcode_version} (#{xcode_build})." 195 | 196 | # Get hockey app id object 197 | hockey_app_id = val["settings"]["hockey-app-id"] 198 | 199 | # Figure out if hockey app id object is a hash (for configuration mapping to ids) 200 | # or a String with static hockey app id 201 | if hockey_app_id.respond_to?(:has_key?) then 202 | raise red """|- HockeyApp app id is missing for the current configuration, please add it or switch to static app id.""" unless hockey_app_id.has_key?(configuration) 203 | 204 | # Parse from nested dict 205 | hockey_app_id = hockey_app_id[configuration] 206 | val["settings"]["hockey-app-id"] = hockey_app_id 207 | end 208 | 209 | # Check if hockey id is filled in correctly 210 | if hockey_app_id.empty? || !hockey_app_id.is_a?(String) then 211 | raise red """|- HockeyApp app id is missing, can't continue with build as version and build number can't be verified. 212 | All apps should have an associated HockeyApp app.""" 213 | end 214 | 215 | buildnumber = HockeyVer.parse_hockey_version hockey_app_id, ENV["HOCKEY_API_TOKEN"] 216 | 217 | # Check if build number from hockey is nil 218 | if buildnumber.nil? 219 | puts yellow "|- No build found on Hockey, proceeding with build" 220 | next 221 | end 222 | 223 | hockey_version = buildnumber["version"] 224 | hockey_build = buildnumber["build"].to_i 225 | 226 | # Compare, make sure that build is always higher and version is at least higher or equal 227 | unless (Version.new(xcode_version) >= Version.new(hockey_version)) && (xcode_build > hockey_build) 228 | valid = false 229 | warning_message = """#{key}: Xcode version #{xcode_version} (#{xcode_build}) is lower or equal than the one on Hockey #{hockey_version} (#{hockey_build}).""" 230 | message +="#{warning_message} \n" 231 | puts yellow "|- #{warning_message}" 232 | end 233 | } 234 | end 235 | 236 | # Check if we can continue 237 | unless valid 238 | message += "Can't continue with build, as version and build numbers must be higher than the ones on Hockey." 239 | addErrorMessage(message) 240 | raise red message 241 | end 242 | 243 | 244 | # All done 245 | puts green "|- All version and build numbers are correct." 246 | 247 | puts "" 248 | puts bold "Creating information required for build" 249 | 250 | build_config = Hash.new 251 | 252 | validated_targets.each_pair { |key, val| 253 | content = val['settings'] 254 | 255 | # Pass platform, xcodeproj 256 | content['xcodeproj'] = xcode_project.path.to_path 257 | content['workspace'] = project_settings['workspace'] 258 | content['platform'] = val['target'].platform_name 259 | content['configuration'] = configuration 260 | content['bundle_id'] = val['target'].build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] 261 | 262 | # Get extensions from content and remove them (will re-added if validated) 263 | extensions_bundle_ids = content['extensions-bundle-ids'] ||= Array.new 264 | content['extensions-bundle-ids'] = Hash.new 265 | 266 | # Validate extensions 267 | extensions_bundle_ids.each { |extension_id| 268 | # Fetch extension target 269 | extension_target = xcode_project.targets.select { |tar| 270 | tar.build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] == extension_id 271 | }.first 272 | 273 | # If we didn't find extesion, skip to next one 274 | if extension_target.nil? 275 | puts yellow "Skipping extension with bundle id #{extension_id} as a target with this id does not exist." 276 | next 277 | end 278 | 279 | # Bail if not an extension type 280 | unless extension_target.extension_target_type? 281 | puts yellow "Skipping extension with bundle id #{extension_id} as this target is not an extension target." 282 | next 283 | end 284 | 285 | # Add validated ID to extensions hash 286 | content['extensions-bundle-ids'][extension_target.name] = extension_id 287 | } 288 | 289 | # Extract build number 290 | info_plist = val['target'].build_settings(configuration)["INFOPLIST_FILE"] 291 | info_plist_path = PROJECT_ROOT_DIR + info_plist 292 | plist = Plist.parse_xml info_plist_path 293 | xcode_version = val['target'].build_settings(configuration)["MARKETING_VERSION"] ||= plist["CFBundleShortVersionString"] 294 | xcode_build_source = val['target'].build_settings(configuration)["CURRENT_PROJECT_VERSION"] ||= plist["CFBundleVersion"] 295 | xcode_build = xcode_build_source.to_i 296 | content['xcode_version'] = "#{xcode_version}" 297 | content['xcode_build'] = "#{xcode_build}" 298 | 299 | build_config[key] = content 300 | } 301 | 302 | # Save to env 303 | system "bitrise envman add --key BUILD_CONFIG --value '#{build_config.to_json}' --no-expand" unless DEBUG_MODE 304 | system "bitrise envman add --key EXPORT_METHOD --value '#{export_method}' --no-expand" unless DEBUG_MODE 305 | system "bitrise envman add --key HOCKEY_UPLOAD_FLAG --value '#{hockey_upload}' --no-expand" unless DEBUG_MODE 306 | system "bitrise envman add --key TESTFLIGHT_UPLOAD_FLAG --value '#{testflight_upload}' --no-expand" unless DEBUG_MODE 307 | system "bitrise envman add --key SLACK_CHANNEL --value '#{project_settings['slack-channel']}' --no-expand " unless DEBUG_MODE 308 | system "bitrise envman add --key OBFUSCATE_CODE --value '#{obfucaste_code_for_archive}' --no-expand " unless DEBUG_MODE 309 | system "bitrise envman add --key CI_VERSION --value '#{ci_version}' --no-expand " unless DEBUG_MODE 310 | puts green "|- Succesfully generated build config." 311 | pp build_config unless not VERBOSE 312 | -------------------------------------------------------------------------------- /versions/1.4/parse_project_settings.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'yaml' 3 | require 'xcodeproj' 4 | require 'fileutils' 5 | require 'pp' 6 | require 'plist' 7 | require 'hockeyver' 8 | require 'json' 9 | require 'zip' 10 | 11 | # ------- 12 | # Constants 13 | # ------- 14 | 15 | PROJECT_FILE_NAME='project.yml' 16 | TARGET_FILE='build_config.json' 17 | DEBUG_MODE=false 18 | VERBOSE=false 19 | 20 | # ------- 21 | # Helpers 22 | # ------- 23 | 24 | def colorize(text, color_code) 25 | "\e[#{color_code}m#{text}\e[0m" 26 | end 27 | def red(text); colorize(text, 31); end 28 | def green(text); colorize(text, 32); end 29 | def yellow(text); colorize(text, 33); end 30 | def bold(text); "\e[1m#{text}\e[22m" end 31 | 32 | class Version < Array 33 | def initialize s 34 | super(s.split('.').map { |e| e.to_i }) 35 | end 36 | def < x 37 | (self <=> x) < 0 38 | end 39 | def > x 40 | (self <=> x) > 0 41 | end 42 | def == x 43 | (self <=> x) == 0 44 | end 45 | def >= x 46 | (self <=> x) >= 0 47 | end 48 | end 49 | 50 | def addErrorMessage(message) 51 | File.open('error_message', 'w') { |file| file.write(message) } 52 | end 53 | 54 | # ------- 55 | # Main 56 | # ------- 57 | 58 | # Load YAML 59 | puts bold "Loading settings from #{PROJECT_FILE_NAME}" 60 | unless File.exist?(PROJECT_FILE_NAME) 61 | message = "|- Couldn't find project.yml file" 62 | addErrorMessage(message) 63 | raise red message 64 | end 65 | 66 | project_settings = YAML.load_file(PROJECT_FILE_NAME) 67 | 68 | # Load some settings 69 | xcodeproj_path = project_settings['xcodeproj'] 70 | configuration = project_settings["configuration"] 71 | PROJECT_ROOT_DIR = File.dirname(xcodeproj_path) + "/" 72 | ci_version = project_settings['ci-version'] 73 | 74 | # Load Xcode project 75 | unless File.exist?(xcodeproj_path) 76 | message = "|- Couldn't find Xcode project at: #{xcodeproj_path}" 77 | addErrorMessage(message) 78 | raise red message 79 | end 80 | 81 | xcode_project = Xcodeproj::Project.open xcodeproj_path 82 | 83 | # Validate configuration 84 | avialable_configurations = xcode_project.build_configurations.map { |x| 85 | puts "|- #{x.name}" if VERBOSE 86 | x.name 87 | } 88 | unless avialable_configurations.include? configuration 89 | message = "|- Can't find configuration #{configuration}" 90 | addErrorMessage(message) 91 | raise red message 92 | end 93 | 94 | # Notify 95 | puts green "|- Settings loaded succesfully with configuration: #{project_settings["configuration"]} and export method: #{project_settings["export-method"]}." 96 | 97 | # Load upload settings 98 | export_method = project_settings['export-method'] 99 | hockey_upload = project_settings['hockey-upload'] ? 1 : 0 100 | testflight_upload = project_settings['testflight-upload'] ? 1 : 0 101 | obfucaste_code_for_archive = project_settings['obfuscate'] ? 1 : 0 102 | 103 | puts "" 104 | puts bold "Checking upload settings" 105 | if hockey_upload == 1 106 | puts green "|- Will upload to hockey" 107 | else 108 | puts yellow "|- Skipping hockey upload" 109 | end 110 | if testflight_upload == 1 111 | puts green "|- Will upload to testflight" 112 | else 113 | puts yellow "|- Skipping testflight upload" 114 | end 115 | if obfucaste_code_for_archive == 1 116 | puts green "|- Will obfuscate code" 117 | else 118 | puts yellow "|- Skipping code obfuscation" 119 | end 120 | 121 | # Get available targets 122 | validated_targets = Hash.new 123 | 124 | # Validate targets 125 | puts "" 126 | puts bold "Validating target settings" 127 | project_settings["targets"].each_pair { |key, val| 128 | xcode_target = xcode_project.targets.select { |tar| tar.name == key }.first 129 | 130 | # Check for target existence 131 | if xcode_target.nil? 132 | puts yellow "|- Skipping target #{key}, as Xcode doesn't contain corresponding target." 133 | next 134 | end 135 | 136 | # Check if enabled 137 | unless val["enabled"] 138 | puts yellow "|- Skipping target #{key}, because it is disabled." 139 | next 140 | end 141 | 142 | # Validate scheme 143 | unless Xcodeproj::Project.schemes(xcodeproj_path).include? val["scheme"] 144 | puts yellow """|- Skipping target #{key}, because the specified scheme can't be found. 145 | Did you set it the scheme as shared?""" 146 | next 147 | end 148 | 149 | puts green "|- Found valid target #{key}." 150 | validated_targets[key] = { "settings" => val, "target" => xcode_target } 151 | } 152 | 153 | 154 | # Make sure we have something to build 155 | unless validated_targets.count > 0 156 | message = "|- No valid targets to build, build failed." 157 | addErrorMessage(message) 158 | raise red message 159 | end 160 | 161 | # Temp fix for riide, will make this more reusable in the future. This breaks down the 162 | # targets into groups of 6, and uses the RIIDE_PROJECT env var to determine which 163 | # of the subset to use 164 | length = 6 165 | if validated_targets.count > length 166 | start = ENV["RIIDE_PROJECT"].to_i * length 167 | start -= length 168 | validated_targets = validated_targets.select { |k, v| validated_targets.keys[start, length].include? k } 169 | end 170 | 171 | puts "" 172 | puts bold "Starting Hockey versions verification" 173 | 174 | valid = true 175 | 176 | unless DEBUG_MODE 177 | # Get version and build numbers 178 | message = "" 179 | validated_targets.each_pair { |key, val| 180 | 181 | # Find the correct configuration 182 | configs = val["target"].build_configurations 183 | index = configs.index { |x| x.name == configuration } 184 | 185 | # Get info plist 186 | info_plist = configs[index].build_settings["INFOPLIST_FILE"] 187 | info_plist_path = PROJECT_ROOT_DIR + info_plist 188 | 189 | plist = Plist.parse_xml info_plist_path 190 | xcode_version = configs[index].build_settings["MARKETING_VERSION"] ||= plist["CFBundleShortVersionString"] 191 | xcode_build_source = configs[index].build_settings["CURRENT_PROJECT_VERSION"] ||= plist["CFBundleVersion"] 192 | xcode_build = xcode_build_source.to_i 193 | 194 | puts "|- Verifying '#{key}' with version #{xcode_version} (#{xcode_build})." 195 | 196 | # Get hockey app id object 197 | hockey_app_id = val["settings"]["hockey-app-id"] 198 | 199 | # Figure out if hockey app id object is a hash (for configuration mapping to ids) 200 | # or a String with static hockey app id 201 | if hockey_app_id.respond_to?(:has_key?) then 202 | raise red """|- HockeyApp app id is missing for the current configuration, please add it or switch to static app id.""" unless hockey_app_id.has_key?(configuration) 203 | 204 | # Parse from nested dict 205 | hockey_app_id = hockey_app_id[configuration] 206 | val["settings"]["hockey-app-id"] = hockey_app_id 207 | end 208 | 209 | # Check if hockey id is filled in correctly 210 | if hockey_app_id.empty? || !hockey_app_id.is_a?(String) then 211 | raise red """|- HockeyApp app id is missing, can't continue with build as version and build number can't be verified. 212 | All apps should have an associated HockeyApp app.""" 213 | end 214 | 215 | buildnumber = HockeyVer.parse_hockey_version hockey_app_id, ENV["HOCKEY_API_TOKEN"] 216 | 217 | # Check if build number from hockey is nil 218 | if buildnumber.nil? 219 | puts yellow "|- No build found on Hockey, proceeding with build" 220 | next 221 | end 222 | 223 | hockey_version = buildnumber["version"] 224 | hockey_build = buildnumber["build"].to_i 225 | 226 | # Compare, make sure that build is always higher and version is at least higher or equal 227 | unless (Version.new(xcode_version) >= Version.new(hockey_version)) && (xcode_build > hockey_build) 228 | valid = false 229 | warning_message = """#{key}: Xcode version #{xcode_version} (#{xcode_build}) is lower or equal than the one on Hockey #{hockey_version} (#{hockey_build}).""" 230 | message +="#{warning_message} \n" 231 | puts yellow "|- #{warning_message}" 232 | end 233 | } 234 | end 235 | 236 | # Check if we can continue 237 | unless valid 238 | message += "Can't continue with build, as version and build numbers must be higher than the ones on Hockey." 239 | addErrorMessage(message) 240 | raise red message 241 | end 242 | 243 | 244 | # All done 245 | puts green "|- All version and build numbers are correct." 246 | 247 | puts "" 248 | puts bold "Creating information required for build" 249 | 250 | build_config = Hash.new 251 | 252 | validated_targets.each_pair { |key, val| 253 | content = val['settings'] 254 | 255 | # Pass platform, xcodeproj 256 | content['xcodeproj'] = xcode_project.path.to_path 257 | content['workspace'] = project_settings['workspace'] 258 | content['platform'] = val['target'].platform_name 259 | content['configuration'] = configuration 260 | content['bundle_id'] = val['target'].build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] 261 | 262 | # Get extensions from content and remove them (will re-added if validated) 263 | extensions_bundle_ids = content['extensions-bundle-ids'] ||= Array.new 264 | content['extensions-bundle-ids'] = Hash.new 265 | 266 | # Validate extensions 267 | extensions_bundle_ids.each { |extension_id| 268 | # Fetch extension target 269 | extension_target = xcode_project.targets.select { |tar| 270 | tar.build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] == extension_id 271 | }.first 272 | 273 | # If we didn't find extesion, skip to next one 274 | if extension_target.nil? 275 | puts yellow "Skipping extension with bundle id #{extension_id} as a target with this id does not exist." 276 | next 277 | end 278 | 279 | # Bail if not an extension type 280 | unless extension_target.extension_target_type? 281 | puts yellow "Skipping extension with bundle id #{extension_id} as this target is not an extension target." 282 | next 283 | end 284 | 285 | # Add validated ID to extensions hash 286 | content['extensions-bundle-ids'][extension_target.name] = extension_id 287 | } 288 | 289 | # Extract build number 290 | info_plist = val['target'].build_settings(configuration)["INFOPLIST_FILE"] 291 | info_plist_path = PROJECT_ROOT_DIR + info_plist 292 | plist = Plist.parse_xml info_plist_path 293 | xcode_version = val['target'].build_settings(configuration)["MARKETING_VERSION"] ||= plist["CFBundleShortVersionString"] 294 | xcode_build_source = val['target'].build_settings(configuration)["CURRENT_PROJECT_VERSION"] ||= plist["CFBundleVersion"] 295 | xcode_build = xcode_build_source.to_i 296 | content['xcode_version'] = "#{xcode_version}" 297 | content['xcode_build'] = "#{xcode_build}" 298 | 299 | build_config[key] = content 300 | } 301 | 302 | # Save to env 303 | system "bitrise envman add --key BUILD_CONFIG --value '#{build_config.to_json}' --no-expand" unless DEBUG_MODE 304 | system "bitrise envman add --key EXPORT_METHOD --value '#{export_method}' --no-expand" unless DEBUG_MODE 305 | system "bitrise envman add --key HOCKEY_UPLOAD_FLAG --value '#{hockey_upload}' --no-expand" unless DEBUG_MODE 306 | system "bitrise envman add --key TESTFLIGHT_UPLOAD_FLAG --value '#{testflight_upload}' --no-expand" unless DEBUG_MODE 307 | system "bitrise envman add --key SLACK_CHANNEL --value '#{project_settings['slack-channel']}' --no-expand " unless DEBUG_MODE 308 | system "bitrise envman add --key OBFUSCATE_CODE --value '#{obfucaste_code_for_archive}' --no-expand " unless DEBUG_MODE 309 | system "bitrise envman add --key CI_VERSION --value '#{ci_version}' --no-expand " unless DEBUG_MODE 310 | puts green "|- Succesfully generated build config." 311 | pp build_config unless not VERBOSE 312 | -------------------------------------------------------------------------------- /versions/1.5/parse_project_settings.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'yaml' 3 | require 'xcodeproj' 4 | require 'fileutils' 5 | require 'pp' 6 | require 'plist' 7 | require 'hockeyver' 8 | require 'json' 9 | require 'zip' 10 | 11 | # ------- 12 | # Constants 13 | # ------- 14 | 15 | PROJECT_FILE_NAME='project.yml' 16 | TARGET_FILE='build_config.json' 17 | DEBUG_MODE=false 18 | VERBOSE=false 19 | 20 | # ------- 21 | # Helpers 22 | # ------- 23 | 24 | def colorize(text, color_code) 25 | "\e[#{color_code}m#{text}\e[0m" 26 | end 27 | def red(text); colorize(text, 31); end 28 | def green(text); colorize(text, 32); end 29 | def yellow(text); colorize(text, 33); end 30 | def bold(text); "\e[1m#{text}\e[22m" end 31 | 32 | class Version < Array 33 | def initialize s 34 | super(s.split('.').map { |e| e.to_i }) 35 | end 36 | def < x 37 | (self <=> x) < 0 38 | end 39 | def > x 40 | (self <=> x) > 0 41 | end 42 | def == x 43 | (self <=> x) == 0 44 | end 45 | def >= x 46 | (self <=> x) >= 0 47 | end 48 | end 49 | 50 | def addErrorMessage(message) 51 | File.open('error_message', 'w') { |file| file.write(message) } 52 | end 53 | 54 | # ------- 55 | # Main 56 | # ------- 57 | 58 | # Load YAML 59 | puts bold "Loading settings from #{PROJECT_FILE_NAME}" 60 | unless File.exist?(PROJECT_FILE_NAME) 61 | message = "|- Couldn't find project.yml file" 62 | addErrorMessage(message) 63 | raise red message 64 | end 65 | 66 | project_settings = YAML.load_file(PROJECT_FILE_NAME) 67 | 68 | # Load some settings 69 | xcodeproj_path = project_settings['xcodeproj'] 70 | configuration = project_settings["configuration"] 71 | PROJECT_ROOT_DIR = File.dirname(xcodeproj_path) + "/" 72 | ci_version = project_settings['ci-version'] 73 | 74 | # Load Xcode project 75 | unless File.exist?(xcodeproj_path) 76 | message = "|- Couldn't find Xcode project at: #{xcodeproj_path}" 77 | addErrorMessage(message) 78 | raise red message 79 | end 80 | 81 | xcode_project = Xcodeproj::Project.open xcodeproj_path 82 | 83 | # Validate configuration 84 | avialable_configurations = xcode_project.build_configurations.map { |x| 85 | puts "|- #{x.name}" if VERBOSE 86 | x.name 87 | } 88 | unless avialable_configurations.include? configuration 89 | message = "|- Can't find configuration #{configuration}" 90 | addErrorMessage(message) 91 | raise red message 92 | end 93 | 94 | # Notify 95 | puts green "|- Settings loaded succesfully with configuration: #{project_settings["configuration"]} and export method: #{project_settings["export-method"]}." 96 | 97 | # Load upload settings 98 | export_method = project_settings['export-method'] 99 | hockey_upload = project_settings['hockey-upload'] ? 1 : 0 100 | testflight_upload = project_settings['testflight-upload'] ? 1 : 0 101 | obfucaste_code_for_archive = project_settings['obfuscate'] ? 1 : 0 102 | 103 | puts "" 104 | puts bold "Checking upload settings" 105 | if hockey_upload == 1 106 | puts green "|- Will upload to hockey" 107 | else 108 | puts yellow "|- Skipping hockey upload" 109 | end 110 | if testflight_upload == 1 111 | puts green "|- Will upload to testflight" 112 | else 113 | puts yellow "|- Skipping testflight upload" 114 | end 115 | if obfucaste_code_for_archive == 1 116 | puts green "|- Will obfuscate code" 117 | else 118 | puts yellow "|- Skipping code obfuscation" 119 | end 120 | 121 | # Get available targets 122 | validated_targets = Hash.new 123 | 124 | # Validate targets 125 | puts "" 126 | puts bold "Validating target settings" 127 | project_settings["targets"].each_pair { |key, val| 128 | xcode_target = xcode_project.targets.select { |tar| tar.name == key }.first 129 | 130 | # Check for target existence 131 | if xcode_target.nil? 132 | puts yellow "|- Skipping target #{key}, as Xcode doesn't contain corresponding target." 133 | next 134 | end 135 | 136 | # Check if enabled 137 | unless val["enabled"] 138 | puts yellow "|- Skipping target #{key}, because it is disabled." 139 | next 140 | end 141 | 142 | # Validate scheme 143 | unless Xcodeproj::Project.schemes(xcodeproj_path).include? val["scheme"] 144 | puts yellow """|- Skipping target #{key}, because the specified scheme can't be found. 145 | Did you set it the scheme as shared?""" 146 | next 147 | end 148 | 149 | puts green "|- Found valid target #{key}." 150 | validated_targets[key] = { "settings" => val, "target" => xcode_target } 151 | } 152 | 153 | 154 | # Make sure we have something to build 155 | unless validated_targets.count > 0 156 | message = "|- No valid targets to build, build failed." 157 | addErrorMessage(message) 158 | raise red message 159 | end 160 | 161 | # Temp fix for riide, will make this more reusable in the future. This breaks down the 162 | # targets into groups of 6, and uses the RIIDE_PROJECT env var to determine which 163 | # of the subset to use 164 | length = 6 165 | if validated_targets.count > length 166 | start = ENV["RIIDE_PROJECT"].to_i * length 167 | start -= length 168 | validated_targets = validated_targets.select { |k, v| validated_targets.keys[start, length].include? k } 169 | end 170 | 171 | puts "" 172 | puts bold "Starting Hockey versions verification" 173 | 174 | valid = true 175 | 176 | unless DEBUG_MODE 177 | # Get version and build numbers 178 | message = "" 179 | validated_targets.each_pair { |key, val| 180 | 181 | # Find the correct configuration 182 | configs = val["target"].build_configurations 183 | index = configs.index { |x| x.name == configuration } 184 | 185 | # Get info plist 186 | info_plist = configs[index].build_settings["INFOPLIST_FILE"] 187 | info_plist_path = PROJECT_ROOT_DIR + info_plist 188 | 189 | plist = Plist.parse_xml info_plist_path 190 | xcode_version = configs[index].build_settings["MARKETING_VERSION"] ||= plist["CFBundleShortVersionString"] 191 | xcode_build_source = configs[index].build_settings["CURRENT_PROJECT_VERSION"] ||= plist["CFBundleVersion"] 192 | xcode_build = xcode_build_source.to_i 193 | 194 | puts "|- Verifying '#{key}' with version #{xcode_version} (#{xcode_build})." 195 | 196 | # Get hockey app id object 197 | hockey_app_id = val["settings"]["hockey-app-id"] 198 | 199 | # Figure out if hockey app id object is a hash (for configuration mapping to ids) 200 | # or a String with static hockey app id 201 | if hockey_app_id.respond_to?(:has_key?) then 202 | raise red """|- HockeyApp app id is missing for the current configuration, please add it or switch to static app id.""" unless hockey_app_id.has_key?(configuration) 203 | 204 | # Parse from nested dict 205 | hockey_app_id = hockey_app_id[configuration] 206 | val["settings"]["hockey-app-id"] = hockey_app_id 207 | end 208 | 209 | # Check if hockey id is filled in correctly 210 | if hockey_app_id.empty? || !hockey_app_id.is_a?(String) then 211 | raise red """|- HockeyApp app id is missing, can't continue with build as version and build number can't be verified. 212 | All apps should have an associated HockeyApp app.""" 213 | end 214 | 215 | buildnumber = HockeyVer.parse_hockey_version hockey_app_id, ENV["HOCKEY_API_TOKEN"] 216 | 217 | # Check if build number from hockey is nil 218 | if buildnumber.nil? 219 | puts yellow "|- No build found on Hockey, proceeding with build" 220 | next 221 | end 222 | 223 | hockey_version = buildnumber["version"] 224 | hockey_build = buildnumber["build"].to_i 225 | 226 | # Compare, make sure that build is always higher and version is at least higher or equal 227 | unless (Version.new(xcode_version) >= Version.new(hockey_version)) && (xcode_build > hockey_build) 228 | valid = false 229 | warning_message = """#{key}: Xcode version #{xcode_version} (#{xcode_build}) is lower or equal than the one on Hockey #{hockey_version} (#{hockey_build}).""" 230 | message +="#{warning_message} \n" 231 | puts yellow "|- #{warning_message}" 232 | end 233 | } 234 | end 235 | 236 | # Check if we can continue 237 | unless valid 238 | message += "Can't continue with build, as version and build numbers must be higher than the ones on Hockey." 239 | addErrorMessage(message) 240 | raise red message 241 | end 242 | 243 | 244 | # All done 245 | puts green "|- All version and build numbers are correct." 246 | 247 | puts "" 248 | puts bold "Creating information required for build" 249 | 250 | build_config = Hash.new 251 | 252 | validated_targets.each_pair { |key, val| 253 | content = val['settings'] 254 | 255 | # Pass platform, xcodeproj 256 | content['xcodeproj'] = xcode_project.path.to_path 257 | content['workspace'] = project_settings['workspace'] 258 | content['platform'] = val['target'].platform_name 259 | content['configuration'] = configuration 260 | content['bundle_id'] = val['target'].build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] 261 | 262 | # Get extensions from content and remove them (will re-added if validated) 263 | extensions_bundle_ids = content['extensions-bundle-ids'] ||= Array.new 264 | content['extensions-bundle-ids'] = Hash.new 265 | 266 | # Validate extensions 267 | extensions_bundle_ids.each { |extension_id| 268 | # Fetch extension target 269 | extension_target = xcode_project.targets.select { |tar| 270 | tar.build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] == extension_id 271 | }.first 272 | 273 | # If we didn't find extesion, skip to next one 274 | if extension_target.nil? 275 | puts yellow "Skipping extension with bundle id #{extension_id} as a target with this id does not exist." 276 | next 277 | end 278 | 279 | # Bail if not an extension type 280 | unless extension_target.extension_target_type? 281 | puts yellow "Skipping extension with bundle id #{extension_id} as this target is not an extension target." 282 | next 283 | end 284 | 285 | # Add validated ID to extensions hash 286 | content['extensions-bundle-ids'][extension_target.name] = extension_id 287 | } 288 | 289 | # Extract build number 290 | info_plist = val['target'].build_settings(configuration)["INFOPLIST_FILE"] 291 | info_plist_path = PROJECT_ROOT_DIR + info_plist 292 | plist = Plist.parse_xml info_plist_path 293 | xcode_version = val['target'].build_settings(configuration)["MARKETING_VERSION"] ||= plist["CFBundleShortVersionString"] 294 | xcode_build_source = val['target'].build_settings(configuration)["CURRENT_PROJECT_VERSION"] ||= plist["CFBundleVersion"] 295 | xcode_build = xcode_build_source.to_i 296 | content['xcode_version'] = "#{xcode_version}" 297 | content['xcode_build'] = "#{xcode_build}" 298 | 299 | build_config[key] = content 300 | } 301 | 302 | # Save to env 303 | system "bitrise envman add --key BUILD_CONFIG --value '#{build_config.to_json}' --no-expand" unless DEBUG_MODE 304 | system "bitrise envman add --key EXPORT_METHOD --value '#{export_method}' --no-expand" unless DEBUG_MODE 305 | system "bitrise envman add --key HOCKEY_UPLOAD_FLAG --value '#{hockey_upload}' --no-expand" unless DEBUG_MODE 306 | system "bitrise envman add --key TESTFLIGHT_UPLOAD_FLAG --value '#{testflight_upload}' --no-expand" unless DEBUG_MODE 307 | system "bitrise envman add --key SLACK_CHANNEL --value '#{project_settings['slack-channel']}' --no-expand " unless DEBUG_MODE 308 | system "bitrise envman add --key OBFUSCATE_CODE --value '#{obfucaste_code_for_archive}' --no-expand " unless DEBUG_MODE 309 | system "bitrise envman add --key CI_VERSION --value '#{ci_version}' --no-expand " unless DEBUG_MODE 310 | puts green "|- Succesfully generated build config." 311 | pp build_config unless not VERBOSE 312 | -------------------------------------------------------------------------------- /versions/1.2/parse_project_settings.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'yaml' 3 | require 'xcodeproj' 4 | require 'fileutils' 5 | require 'pp' 6 | require 'plist' 7 | require 'hockeyver' 8 | require 'json' 9 | require 'zip' 10 | 11 | # ------- 12 | # Constants 13 | # ------- 14 | 15 | PROJECT_FILE_NAME='project.yml' 16 | TARGET_FILE='build_config.json' 17 | DEBUG_MODE=false 18 | VERBOSE=false 19 | 20 | # ------- 21 | # Helpers 22 | # ------- 23 | 24 | def colorize(text, color_code) 25 | "\e[#{color_code}m#{text}\e[0m" 26 | end 27 | def red(text); colorize(text, 31); end 28 | def green(text); colorize(text, 32); end 29 | def yellow(text); colorize(text, 33); end 30 | def bold(text); "\e[1m#{text}\e[22m" end 31 | 32 | class Version < Array 33 | def initialize s 34 | super(s.split('.').map { |e| e.to_i }) 35 | end 36 | def < x 37 | (self <=> x) < 0 38 | end 39 | def > x 40 | (self <=> x) > 0 41 | end 42 | def == x 43 | (self <=> x) == 0 44 | end 45 | def >= x 46 | (self <=> x) >= 0 47 | end 48 | end 49 | 50 | def addErrorMessage(message) 51 | File.open('error_message', 'w') { |file| file.write(message) } 52 | end 53 | 54 | # ------- 55 | # Main 56 | # ------- 57 | 58 | # Load YAML 59 | puts bold "Loading settings from #{PROJECT_FILE_NAME}" 60 | unless File.exist?(PROJECT_FILE_NAME) 61 | message = "|- Couldn't find project.yml file" 62 | addErrorMessage(message) 63 | raise red message 64 | end 65 | 66 | project_settings = YAML.load_file(PROJECT_FILE_NAME) 67 | 68 | # Load some settings 69 | xcodeproj_path = project_settings['xcodeproj'] 70 | configuration = project_settings["configuration"] 71 | PROJECT_ROOT_DIR = File.dirname(xcodeproj_path) + "/" 72 | export_method = project_settings['method'] ||= "app-store" 73 | ci_version = project_settings['ci-version'] 74 | 75 | # Load Xcode project 76 | unless File.exist?(xcodeproj_path) 77 | message = "|- Couldn't find Xcode project at: #{xcodeproj_path}" 78 | addErrorMessage(message) 79 | raise red message 80 | end 81 | 82 | xcode_project = Xcodeproj::Project.open xcodeproj_path 83 | 84 | # Validate configuration 85 | avialable_configurations = xcode_project.build_configurations.map { |x| 86 | puts "|- #{x.name}" if VERBOSE 87 | x.name 88 | } 89 | unless avialable_configurations.include? configuration 90 | message = "|- Can't find configuration #{configuration}" 91 | addErrorMessage(message) 92 | raise red message 93 | end 94 | 95 | # Notify 96 | puts green "|- Settings loaded succesfully with configuration: #{project_settings["configuration"]}." 97 | 98 | # Load upload settings 99 | hockey_upload = project_settings['hockey-upload'] ? 1 : 0 100 | testflight_upload = project_settings['testflight-upload'] ? 1 : 0 101 | opfucaste_code_for_archive = project_settings['obfuscate'] ? 1 : 0 102 | 103 | puts "" 104 | puts bold "Checking upload settings" 105 | if hockey_upload == 1 106 | puts green "|- Will upload to hockey" 107 | else 108 | puts yellow "|- Skipping hockey upload" 109 | end 110 | if testflight_upload == 1 111 | puts green "|- Will upload to testflight" 112 | else 113 | puts yellow "|- Skipping testflight upload" 114 | end 115 | if opfucaste_code_for_archive == 1 116 | puts green "|- Will obfuscate code" 117 | else 118 | puts yellow "|- Skipping code obfuscation" 119 | end 120 | 121 | # Get available targets 122 | validated_targets = Hash.new 123 | 124 | # Validate targets 125 | puts "" 126 | puts bold "Validating target settings" 127 | project_settings["targets"].each_pair { |key, val| 128 | xcode_target = xcode_project.targets.select { |tar| tar.name == key }.first 129 | 130 | # Check for target existence 131 | if xcode_target.nil? 132 | puts yellow "|- Skipping target #{key}, as Xcode doesn't contain corresponding target." 133 | next 134 | end 135 | 136 | # Check if enabled 137 | unless val["enabled"] 138 | puts yellow "|- Skipping target #{key}, because it is disabled." 139 | next 140 | end 141 | 142 | # Validate scheme 143 | unless Xcodeproj::Project.schemes(xcodeproj_path).include? val["scheme"] 144 | puts yellow """|- Skipping target #{key}, because the specified scheme can't be found. 145 | Did you set it the scheme as shared?""" 146 | next 147 | end 148 | 149 | puts green "|- Found valid target #{key}." 150 | validated_targets[key] = { "settings" => val, "target" => xcode_target } 151 | } 152 | 153 | 154 | # Make sure we have something to build 155 | unless validated_targets.count > 0 156 | message = "|- No valid targets to build, build failed." 157 | addErrorMessage(message) 158 | raise red message 159 | end 160 | 161 | # Temp fix for riide, will make this more reusable in the future. This breaks down the 162 | # targets into groups of 6, and uses the RIIDE_PROJECT env var to determine which 163 | # of the subset to use 164 | length = 6 165 | if validated_targets.count > length 166 | start = ENV["RIIDE_PROJECT"].to_i * length 167 | start -= length 168 | validated_targets = validated_targets.select { |k, v| validated_targets.keys[start, length].include? k } 169 | end 170 | 171 | puts "" 172 | puts bold "Starting Hockey versions verification" 173 | 174 | valid = true 175 | 176 | unless DEBUG_MODE 177 | # Get version and build numbers 178 | message = "" 179 | validated_targets.each_pair { |key, val| 180 | 181 | # Find the correct configuration 182 | configs = val["target"].build_configurations 183 | index = configs.index { |x| x.name == configuration } 184 | 185 | # Get info plist 186 | info_plist = configs[index].build_settings["INFOPLIST_FILE"] 187 | info_plist_path = PROJECT_ROOT_DIR + info_plist 188 | 189 | plist = Plist.parse_xml info_plist_path 190 | xcode_version = configs[index].build_settings["MARKETING_VERSION"] ||= plist["CFBundleShortVersionString"] 191 | xcode_build_source = configs[index].build_settings["CURRENT_PROJECT_VERSION"] ||= plist["CFBundleVersion"] 192 | xcode_build = xcode_build_source.to_i 193 | 194 | puts "|- Verifying '#{key}' with version #{xcode_version} (#{xcode_build})." 195 | 196 | # Get hockey app id object 197 | hockey_app_id = val["settings"]["hockey-app-id"] 198 | 199 | # Figure out if hockey app id object is a hash (for configuration mapping to ids) 200 | # or a String with static hockey app id 201 | if hockey_app_id.respond_to?(:has_key?) then 202 | raise red """|- HockeyApp app id is missing for the current configuration, please add it or switch to static app id.""" unless hockey_app_id.has_key?(configuration) 203 | 204 | # Parse from nested dict 205 | hockey_app_id = hockey_app_id[configuration] 206 | val["settings"]["hockey-app-id"] = hockey_app_id 207 | end 208 | 209 | # Check if hockey id is filled in correctly 210 | if hockey_app_id.empty? || !hockey_app_id.is_a?(String) then 211 | raise red """|- HockeyApp app id is missing, can't continue with build as version and build number can't be verified. 212 | All apps should have an associated HockeyApp app.""" 213 | end 214 | 215 | buildnumber = HockeyVer.parse_hockey_version hockey_app_id, ENV["HOCKEY_API_TOKEN"] 216 | 217 | # Check if build number from hockey is nil 218 | if buildnumber.nil? 219 | puts yellow "|- No build found on Hockey, proceeding with build" 220 | next 221 | end 222 | 223 | hockey_version = buildnumber["version"] 224 | hockey_build = buildnumber["build"].to_i 225 | 226 | # Compare, make sure that build is always higher and version is at least higher or equal 227 | unless (Version.new(xcode_version) >= Version.new(hockey_version)) && (xcode_build > hockey_build) 228 | valid = false 229 | warning_message = """#{key}: Xcode version #{xcode_version} (#{xcode_build}) is lower or equal than the one on Hockey #{hockey_version} (#{hockey_build}).""" 230 | message +="#{warning_message} \n" 231 | puts yellow "|- #{warning_message}" 232 | end 233 | } 234 | end 235 | 236 | # Check if we can continue 237 | unless valid 238 | message += "Can't continue with build, as version and build numbers must be higher than the ones on Hockey." 239 | addErrorMessage(message) 240 | raise red message 241 | end 242 | 243 | 244 | # All done 245 | puts green "|- All version and build numbers are correct." 246 | 247 | puts "" 248 | puts bold "Creating information required for build" 249 | 250 | build_config = Hash.new 251 | 252 | validated_targets.each_pair { |key, val| 253 | content = val['settings'] 254 | 255 | # Pass platform, xcodeproj 256 | content['xcodeproj'] = xcode_project.path.to_path 257 | content['workspace'] = project_settings['workspace'] 258 | content['platform'] = val['target'].platform_name 259 | content['configuration'] = configuration 260 | content['bundle_id'] = val['target'].build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] 261 | 262 | # Get extensions from content and remove them (will re-added if validated) 263 | extensions_bundle_ids = content['extensions-bundle-ids'] ||= Array.new 264 | content['extensions-bundle-ids'] = Hash.new 265 | 266 | # Validate extensions 267 | extensions_bundle_ids.each { |extension_id| 268 | # Fetch extension target 269 | extension_target = xcode_project.targets.select { |tar| 270 | tar.build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] == extension_id 271 | }.first 272 | 273 | # If we didn't find extesion, skip to next one 274 | if extension_target.nil? 275 | puts yellow "Skipping extension with bundle id #{extension_id} as a target with this id does not exist." 276 | next 277 | end 278 | 279 | # Bail if not an extension type (and not watch app) 280 | unless extension_target.extension_target_type? 281 | unless extension_target.sdk == "watchos" 282 | puts yellow "Skipping extension with bundle id #{extension_id} as it is not an extension target." 283 | next 284 | end 285 | end 286 | 287 | # Add validated ID to extensions hash 288 | content['extensions-bundle-ids'][extension_target.name] = extension_id 289 | } 290 | 291 | # Extract build number 292 | info_plist = val['target'].build_settings(configuration)["INFOPLIST_FILE"] 293 | info_plist_path = PROJECT_ROOT_DIR + info_plist 294 | plist = Plist.parse_xml info_plist_path 295 | xcode_version = val['target'].build_settings(configuration)["MARKETING_VERSION"] ||= plist["CFBundleShortVersionString"] 296 | xcode_build_source = val['target'].build_settings(configuration)["CURRENT_PROJECT_VERSION"] ||= plist["CFBundleVersion"] 297 | xcode_build = xcode_build_source.to_i 298 | content['xcode_version'] = "#{xcode_version}" 299 | content['xcode_build'] = "#{xcode_build}" 300 | 301 | build_config[key] = content 302 | } 303 | 304 | # Save to env 305 | system "bitrise envman add --key BUILD_CONFIG --value '#{build_config.to_json}' --no-expand" unless DEBUG_MODE 306 | system "bitrise envman add --key EXPORT_METHOD --value #{export_method} --no-expand" unless DEBUG_MODE 307 | system "bitrise envman add --key HOCKEY_UPLOAD_FLAG --value '#{hockey_upload}' --no-expand" unless DEBUG_MODE 308 | system "bitrise envman add --key TESTFLIGHT_UPLOAD_FLAG --value '#{testflight_upload}' --no-expand" unless DEBUG_MODE 309 | system "bitrise envman add --key SLACK_CHANNEL --value '#{project_settings['slack-channel']}' --no-expand " unless DEBUG_MODE 310 | system "bitrise envman add --key OBFUSCATE_CODE --value '#{opfucaste_code_for_archive}' --no-expand " unless DEBUG_MODE 311 | system "bitrise envman add --key CI_VERSION --value '#{ci_version}' --no-expand " unless DEBUG_MODE 312 | puts green "|- Succesfully generated build config." 313 | pp build_config unless not VERBOSE 314 | -------------------------------------------------------------------------------- /versions/2.0/parse_project_settings.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'yaml' 3 | require 'xcodeproj' 4 | require 'fileutils' 5 | require 'pp' 6 | require 'plist' 7 | require 'json' 8 | require 'zip' 9 | 10 | # ------- 11 | # Constants 12 | # ------- 13 | 14 | PROJECT_FILE_NAME='project.yml' 15 | TARGET_FILE='build_config.json' 16 | DEBUG_MODE=false 17 | VERBOSE=false 18 | 19 | # ------- 20 | # Helpers 21 | # ------- 22 | 23 | def colorize(text, color_code) 24 | "\e[#{color_code}m#{text}\e[0m" 25 | end 26 | def red(text); colorize(text, 31); end 27 | def green(text); colorize(text, 32); end 28 | def yellow(text); colorize(text, 33); end 29 | def bold(text); "\e[1m#{text}\e[22m" end 30 | 31 | class Version < Array 32 | def initialize s 33 | super(s.split('.').map { |e| e.to_i }) 34 | end 35 | def < x 36 | (self <=> x) < 0 37 | end 38 | def > x 39 | (self <=> x) > 0 40 | end 41 | def == x 42 | (self <=> x) == 0 43 | end 44 | def >= x 45 | (self <=> x) >= 0 46 | end 47 | end 48 | 49 | def addErrorMessage(message) 50 | File.open('error_message', 'w') { |file| file.write(message) } 51 | end 52 | 53 | # ------- 54 | # Main 55 | # ------- 56 | 57 | # Load YAML 58 | puts bold "Loading settings from #{PROJECT_FILE_NAME}" 59 | unless File.exist?(PROJECT_FILE_NAME) 60 | message = "|- Couldn't find project.yml file" 61 | addErrorMessage(message) 62 | raise red message 63 | end 64 | 65 | project_settings = YAML.load_file(PROJECT_FILE_NAME) 66 | 67 | # Load some settings 68 | xcodeproj_path = project_settings['xcodeproj'] 69 | configuration = project_settings["configuration"] 70 | PROJECT_ROOT_DIR = File.dirname(xcodeproj_path) + "/" 71 | ci_version = project_settings['ci-version'] 72 | 73 | # Load Xcode project 74 | unless File.exist?(xcodeproj_path) 75 | message = "|- Couldn't find Xcode project at: #{xcodeproj_path}" 76 | addErrorMessage(message) 77 | raise red message 78 | end 79 | 80 | xcode_project = Xcodeproj::Project.open xcodeproj_path 81 | 82 | # Validate configuration 83 | avialable_configurations = xcode_project.build_configurations.map { |x| 84 | puts "|- #{x.name}" if VERBOSE 85 | x.name 86 | } 87 | unless avialable_configurations.include? configuration 88 | message = "|- Can't find configuration #{configuration}" 89 | addErrorMessage(message) 90 | raise red message 91 | end 92 | 93 | # Notify 94 | puts green "|- Settings loaded succesfully with configuration: #{project_settings["configuration"]} and export method: #{project_settings["export-method"]}." 95 | 96 | # Load upload settings 97 | export_method = project_settings['export-method'] 98 | firebase_upload = project_settings['firebase-upload'] ? 1 : 0 99 | testflight_upload = project_settings['testflight-upload'] ? 1 : 0 100 | obfucaste_code_for_archive = project_settings['obfuscate'] ? 1 : 0 101 | 102 | puts "" 103 | puts bold "Checking upload settings" 104 | if firebase_upload == 1 105 | puts green "|- Will upload to Firebase" 106 | else 107 | puts yellow "|- Skipping Firebase upload" 108 | end 109 | if testflight_upload == 1 110 | puts green "|- Will upload to testflight" 111 | else 112 | puts yellow "|- Skipping testflight upload" 113 | end 114 | if obfucaste_code_for_archive == 1 115 | puts green "|- Will obfuscate code" 116 | else 117 | puts yellow "|- Skipping code obfuscation" 118 | end 119 | 120 | # Get available targets 121 | validated_targets = Hash.new 122 | 123 | # Validate targets 124 | puts "" 125 | puts bold "Validating target settings" 126 | project_settings["targets"].each_pair { |key, val| 127 | xcode_target = xcode_project.targets.select { |tar| tar.name == key }.first 128 | 129 | # Check for target existence 130 | if xcode_target.nil? 131 | puts yellow "|- Skipping target #{key}, as Xcode doesn't contain corresponding target." 132 | next 133 | end 134 | 135 | # Check if enabled 136 | unless val["enabled"] 137 | puts yellow "|- Skipping target #{key}, because it is disabled." 138 | next 139 | end 140 | 141 | # Validate scheme 142 | unless Xcodeproj::Project.schemes(xcodeproj_path).include? val["scheme"] 143 | puts yellow """|- Skipping target #{key}, because the specified scheme can't be found. 144 | Did you set it the scheme as shared?""" 145 | next 146 | end 147 | 148 | puts green "|- Found valid target #{key}." 149 | validated_targets[key] = { "settings" => val, "target" => xcode_target } 150 | } 151 | 152 | 153 | # Make sure we have something to build 154 | unless validated_targets.count > 0 155 | message = "|- No valid targets to build, build failed." 156 | addErrorMessage(message) 157 | raise red message 158 | end 159 | 160 | # Temp fix for riide, will make this more reusable in the future. This breaks down the 161 | # targets into groups of 6, and uses the RIIDE_PROJECT env var to determine which 162 | # of the subset to use 163 | length = 6 164 | if validated_targets.count > length 165 | start = ENV["RIIDE_PROJECT"].to_i * length 166 | start -= length 167 | validated_targets = validated_targets.select { |k, v| validated_targets.keys[start, length].include? k } 168 | end 169 | 170 | =begin 171 | 172 | 173 | puts "" 174 | puts bold "Starting Hockey versions verification" 175 | 176 | valid = true 177 | =end 178 | unless DEBUG_MODE 179 | # Get version and build numbers 180 | message = "" 181 | validated_targets.each_pair { |key, val| 182 | =begin 183 | # Find the correct configuration 184 | configs = val["target"].build_configurations 185 | index = configs.index { |x| x.name == configuration } 186 | 187 | # Get info plist 188 | info_plist = configs[index].build_settings["INFOPLIST_FILE"] 189 | info_plist_path = PROJECT_ROOT_DIR + info_plist 190 | 191 | plist = Plist.parse_xml info_plist_path 192 | xcode_version = configs[index].build_settings["MARKETING_VERSION"] ||= plist["CFBundleShortVersionString"] 193 | xcode_build_source = configs[index].build_settings["CURRENT_PROJECT_VERSION"] ||= plist["CFBundleVersion"] 194 | xcode_build = xcode_build_source.to_i 195 | 196 | puts "|- Verifying '#{key}' with version #{xcode_version} (#{xcode_build})." 197 | =end 198 | # Get hockey app id object 199 | firebase_app_id = val["settings"]["firebase-app-id"] 200 | 201 | # Figure out if hockey app id object is a hash (for configuration mapping to ids) 202 | # or a String with static hockey app id 203 | if firebase_app_id.respond_to?(:has_key?) then 204 | raise red """|- Firebase app id is missing for the current configuration, please add it or switch to static app id.""" unless firebase_app_id.has_key?(configuration) 205 | 206 | # Parse from nested dict 207 | firebase_app_id = firebase_app_id[configuration] 208 | val["settings"]["firebase-app-id"] = firebase_app_id 209 | end 210 | } 211 | end 212 | 213 | =begin 214 | # Check if hockey id is filled in correctly 215 | if hockey_app_id.empty? || !hockey_app_id.is_a?(String) then 216 | raise red """|- HockeyApp app id is missing, can't continue with build as version and build number can't be verified. 217 | All apps should have an associated HockeyApp app.""" 218 | end 219 | 220 | buildnumber = HockeyVer.parse_hockey_version hockey_app_id, ENV["HOCKEY_API_TOKEN"] 221 | 222 | # Check if build number from hockey is nil 223 | if buildnumber.nil? 224 | puts yellow "|- No build found on Hockey, proceeding with build" 225 | next 226 | end 227 | 228 | hockey_version = buildnumber["version"] 229 | hockey_build = buildnumber["build"].to_i 230 | 231 | # Compare, make sure that build is always higher and version is at least higher or equal 232 | unless (Version.new(xcode_version) >= Version.new(hockey_version)) && (xcode_build > hockey_build) 233 | valid = false 234 | warning_message = """#{key}: Xcode version #{xcode_version} (#{xcode_build}) is lower or equal than the one on Hockey #{hockey_version} (#{hockey_build}).""" 235 | message +="#{warning_message} \n" 236 | puts yellow "|- #{warning_message}" 237 | end 238 | } 239 | end 240 | 241 | # Check if we can continue 242 | unless valid 243 | message += "Can't continue with build, as version and build numbers must be higher than the ones on Hockey." 244 | addErrorMessage(message) 245 | raise red message 246 | end 247 | 248 | 249 | # All done 250 | puts green "|- All version and build numbers are correct." 251 | =end 252 | 253 | puts "" 254 | puts bold "Creating information required for build" 255 | 256 | build_config = Hash.new 257 | 258 | validated_targets.each_pair { |key, val| 259 | content = val['settings'] 260 | 261 | # Pass platform, xcodeproj 262 | content['xcodeproj'] = xcode_project.path.to_path 263 | content['workspace'] = project_settings['workspace'] 264 | content['platform'] = val['target'].platform_name 265 | content['configuration'] = configuration 266 | content['bundle_id'] = val['target'].build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] 267 | 268 | # Get extensions from content and remove them (will re-added if validated) 269 | extensions_bundle_ids = content['extensions-bundle-ids'] ||= Array.new 270 | content['extensions-bundle-ids'] = Hash.new 271 | 272 | # Validate extensions 273 | extensions_bundle_ids.each { |extension_id| 274 | # Fetch extension target 275 | extension_target = xcode_project.targets.select { |tar| 276 | tar.build_settings(configuration)['PRODUCT_BUNDLE_IDENTIFIER'] == extension_id 277 | }.first 278 | 279 | # If we didn't find extesion, skip to next one 280 | if extension_target.nil? 281 | puts yellow "Skipping extension with bundle id #{extension_id} as a target with this id does not exist." 282 | next 283 | end 284 | 285 | # Bail if not an extension type 286 | unless extension_target.extension_target_type? 287 | unless extension_target.sdk == "watchos" 288 | puts yellow "Skipping extension with bundle id #{extension_id} as it is not an extension target." 289 | next 290 | end 291 | end 292 | 293 | # Add validated ID to extensions hash 294 | content['extensions-bundle-ids'][extension_target.name] = extension_id 295 | } 296 | 297 | # Extract build number 298 | info_plist = val['target'].build_settings(configuration)["INFOPLIST_FILE"] 299 | info_plist_path = PROJECT_ROOT_DIR + info_plist 300 | plist = Plist.parse_xml info_plist_path 301 | xcode_version = val['target'].build_settings(configuration)["MARKETING_VERSION"] ||= plist["CFBundleShortVersionString"] 302 | xcode_build_source = val['target'].build_settings(configuration)["CURRENT_PROJECT_VERSION"] ||= plist["CFBundleVersion"] 303 | xcode_build = xcode_build_source.to_i 304 | content['xcode_version'] = "#{xcode_version}" 305 | content['xcode_build'] = "#{xcode_build}" 306 | 307 | build_config[key] = content 308 | } 309 | 310 | # Save to env 311 | system "bitrise envman add --key BUILD_CONFIG --value '#{build_config.to_json}' --no-expand" unless DEBUG_MODE 312 | system "bitrise envman add --key EXPORT_METHOD --value '#{export_method}' --no-expand" unless DEBUG_MODE 313 | system "bitrise envman add --key FIREBASE_UPLOAD_FLAG --value '#{firebase_upload}' --no-expand" unless DEBUG_MODE 314 | system "bitrise envman add --key TESTFLIGHT_UPLOAD_FLAG --value '#{testflight_upload}' --no-expand" unless DEBUG_MODE 315 | system "bitrise envman add --key SLACK_CHANNEL --value '#{project_settings['slack-channel']}' --no-expand " unless DEBUG_MODE 316 | system "bitrise envman add --key OBFUSCATE_CODE --value '#{obfucaste_code_for_archive}' --no-expand " unless DEBUG_MODE 317 | system "bitrise envman add --key CI_VERSION --value '#{ci_version}' --no-expand " unless DEBUG_MODE 318 | puts green "|- Succesfully generated build config." 319 | pp build_config unless not VERBOSE 320 | --------------------------------------------------------------------------------