├── .gitignore ├── .rspec ├── .rubocop.yml ├── .travis.yml ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── circle.yml ├── fastlane-plugin-pgyer.gemspec ├── fastlane ├── Fastfile └── Pluginfile ├── lib └── fastlane │ └── plugin │ ├── pgyer.rb │ └── pgyer │ ├── actions │ └── pgyer_action.rb │ ├── helper │ └── pgyer_helper.rb │ └── version.rb └── spec ├── pgyer_action_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | Gemfile.lock 3 | 4 | ## Documentation cache and generated files: 5 | /.yardoc/ 6 | /_yardoc/ 7 | /doc/ 8 | /rdoc/ 9 | fastlane/README.md 10 | fastlane/report.xml 11 | .vscode 12 | coverage 13 | pgyer-fastlane-uploaded-app-info.json 14 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | --color 3 | --format d 4 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | # kind_of? is a good way to check a type 2 | Style/ClassCheck: 3 | EnforcedStyle: kind_of? 4 | 5 | # .length == 0 is also good, we don't always want .zero? 6 | Style/NumericPredicate: 7 | Enabled: false 8 | 9 | # this would cause errors with long lanes 10 | Metrics/BlockLength: 11 | Enabled: false 12 | 13 | # this is a bit buggy 14 | Metrics/ModuleLength: 15 | Enabled: false 16 | 17 | # certificate_1 is an okay variable name 18 | Style/VariableNumber: 19 | Enabled: false 20 | 21 | # This is used a lot across the fastlane code base for config files 22 | Style/MethodMissing: 23 | Enabled: false 24 | 25 | # 26 | # File.chmod(0777, f) 27 | # 28 | # is easier to read than 29 | # 30 | # File.chmod(0o777, f) 31 | # 32 | Style/NumericLiteralPrefix: 33 | Enabled: false 34 | 35 | # 36 | # command = (!clean_expired.nil? || !clean_pattern.nil?) ? CLEANUP : LIST 37 | # 38 | # is easier to read than 39 | # 40 | # command = !clean_expired.nil? || !clean_pattern.nil? ? CLEANUP : LIST 41 | # 42 | Style/TernaryParentheses: 43 | Enabled: false 44 | 45 | # sometimes it is usefull to have those empty methods 46 | Style/EmptyMethod: 47 | Enabled: false 48 | 49 | # It's better to be more explicit about the type 50 | Style/BracesAroundHashParameters: 51 | Enabled: false 52 | 53 | # specs sometimes have useless assignments, which is fine 54 | Lint/UselessAssignment: 55 | Exclude: 56 | - '**/spec/**/*' 57 | 58 | # We could potentially enable the 2 below: 59 | Style/IndentHash: 60 | Enabled: false 61 | 62 | Style/AlignHash: 63 | Enabled: false 64 | 65 | # HoundCI doesn't like this rule 66 | Style/DotPosition: 67 | Enabled: false 68 | 69 | # We allow !! as it's an easy way to convert ot boolean 70 | Style/DoubleNegation: 71 | Enabled: false 72 | 73 | # Sometimes we allow a rescue block that doesn't contain code 74 | Lint/HandleExceptions: 75 | Enabled: false 76 | 77 | # Cop supports --auto-correct. 78 | Lint/UnusedBlockArgument: 79 | Enabled: false 80 | 81 | # Needed for $verbose 82 | Style/GlobalVars: 83 | Enabled: false 84 | 85 | # We want to allow class Fastlane::Class 86 | Style/ClassAndModuleChildren: 87 | Enabled: false 88 | 89 | # $? Exit 90 | Style/SpecialGlobalVars: 91 | Enabled: false 92 | 93 | Metrics/AbcSize: 94 | Enabled: false 95 | 96 | Metrics/MethodLength: 97 | Enabled: false 98 | 99 | Metrics/CyclomaticComplexity: 100 | Enabled: false 101 | 102 | # The %w might be confusing for new users 103 | Style/WordArray: 104 | MinSize: 19 105 | 106 | # raise and fail are both okay 107 | Style/SignalException: 108 | Enabled: false 109 | 110 | # Better too much 'return' than one missing 111 | Style/RedundantReturn: 112 | Enabled: false 113 | 114 | # Having if in the same line might not always be good 115 | Style/IfUnlessModifier: 116 | Enabled: false 117 | 118 | # and and or is okay 119 | Style/AndOr: 120 | Enabled: false 121 | 122 | # Configuration parameters: CountComments. 123 | Metrics/ClassLength: 124 | Max: 320 125 | 126 | 127 | # Configuration parameters: AllowURI, URISchemes. 128 | Metrics/LineLength: 129 | Max: 370 130 | 131 | # Configuration parameters: CountKeywordArgs. 132 | Metrics/ParameterLists: 133 | Max: 17 134 | 135 | Metrics/PerceivedComplexity: 136 | Max: 18 137 | 138 | # Sometimes it's easier to read without guards 139 | Style/GuardClause: 140 | Enabled: false 141 | 142 | # We allow both " and ' 143 | Style/StringLiterals: 144 | Enabled: false 145 | 146 | # something = if something_else 147 | # that's confusing 148 | Style/ConditionalAssignment: 149 | Enabled: false 150 | 151 | # Better to have too much self than missing a self 152 | Style/RedundantSelf: 153 | Enabled: false 154 | 155 | # e.g. 156 | # def self.is_supported?(platform) 157 | # we may never use `platform` 158 | Lint/UnusedMethodArgument: 159 | Enabled: false 160 | 161 | # the let(:key) { ... } 162 | Lint/ParenthesesAsGroupedExpression: 163 | Exclude: 164 | - '**/spec/**/*' 165 | 166 | # This would reject is_ in front of methods 167 | # We use `is_supported?` everywhere already 168 | Style/PredicateName: 169 | Enabled: false 170 | 171 | # We allow the $ 172 | Style/PerlBackrefs: 173 | Enabled: false 174 | 175 | # Disable '+ should be surrounded with a single space' for xcodebuild_spec.rb 176 | Style/SpaceAroundOperators: 177 | Exclude: 178 | - '**/spec/actions_specs/xcodebuild_spec.rb' 179 | 180 | AllCops: 181 | Include: 182 | - '**/fastlane/Fastfile' 183 | Exclude: 184 | - '**/lib/assets/custom_action_template.rb' 185 | - './vendor/**/*' 186 | 187 | # We're not there yet 188 | Style/Documentation: 189 | Enabled: false 190 | 191 | # Added after upgrade to 0.38.0 192 | Style/MutableConstant: 193 | Enabled: false 194 | 195 | # length > 0 is good 196 | Style/ZeroLengthPredicate: 197 | Enabled: false 198 | 199 | # Adds complexity 200 | Style/IfInsideElse: 201 | Enabled: false 202 | 203 | # Sometimes we just want to 'collect' 204 | Style/CollectionMethods: 205 | Enabled: false 206 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # os: osx # enable this if you need macOS support 2 | language: ruby 3 | rvm: 4 | - 2.2.4 5 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | 5 | plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') 6 | eval(File.read(plugins_path), binding) if File.exist?(plugins_path) 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 rexshi 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pgyer plugin 2 | 3 | [![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](https://rubygems.org/gems/fastlane-plugin-pgyer) 4 | ## Important Notifications 5 | 6 | - Since pgyer has migrated the API domain name, Please update the plugin to the latest version (>= 0.2.6) to avoid uploading failures. 7 | 8 | ## Getting Started 9 | 10 | This project is a [fastlane](https://github.com/fastlane/fastlane) plugin. To get started with `fastlane-plugin-pgyer`, add it to your project by running: 11 | 12 | ```bash 13 | fastlane add_plugin pgyer 14 | ``` 15 | 16 | ## About pgyer 17 | 18 | This pluginin allow you distribute app automatically to [pgyer beta testing service](https://www.pgyer.com) in fastlane workflow. 19 | 20 | ## How to update pgyer plugin to the latest version 21 | 22 | **Due to the adjustment of the API interface, please ensure that the plugin version is at least `0.2.4`** 23 | 24 | Plan A: update all plguins (Recommended) 25 | 26 | 27 | ```bash 28 | fastlane update_plugins 29 | ``` 30 | 31 | Plan B: update pgyer plugin only 32 | 33 | modify `fastlane/Pluginfile`, update the following line: 34 | 35 | ```ruby 36 | gem 'fastlane-plugin-pgyer', ">= 0.2.4" # ensure plugin version >= 0.2.4 37 | ``` 38 | 39 | and run `bundle install` at the root of your fastlane project to update gemfile.lock 40 | 41 | ## Plugin avaliable options 42 | 43 | please visit [https://github.com/shishirui/fastlane-plugin-pgyer/blob/master/lib/fastlane/plugin/pgyer/actions/pgyer_action.rb#L135-L205](https://github.com/shishirui/fastlane-plugin-pgyer/blob/master/lib/fastlane/plugin/pgyer/actions/pgyer_action.rb#L135-L205) to know the options. 44 | 45 | 46 | ## Example 47 | 48 | Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin. Try it by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane test`. 49 | 50 | Just specify the `api_key` associated with your pgyer account. 51 | 52 | ``` 53 | lane :beta do 54 | gym 55 | pgyer(api_key: "7f15xxxxxxxxxxxxxxxxxx141") 56 | end 57 | ``` 58 | 59 | You can also set a password to protect the App from being downloaded publicly: 60 | 61 | ``` 62 | lane :beta do 63 | gym 64 | pgyer(api_key: "7f15xxxxxxxxxxxxxxxxxx141", password: "123456", install_type: "2") 65 | end 66 | ``` 67 | 68 | Set a version update description for App: 69 | 70 | ``` 71 | lane :beta do 72 | gym 73 | pgyer(api_key: "7f15xxxxxxxxxxxxxxxxxx141", update_description: "update by fastlane") 74 | end 75 | ``` 76 | 77 | 78 | If the upload is successful, you will get information about the app after it is uploaded, which is returned from the API interface app/buildinfo . You can pass it to other plugins, or export it to the terminal for use by other scripts: 79 | 80 | ```ruby 81 | lane :beta do 82 | gym 83 | answer = pgyer(api_key: "xxxxxx") 84 | puts answer 85 | # terminal outputs like this if uploaded successfully 86 | # {"buildKey"=>"xxxx", "buildType"=>"2", "buildIsFirst"=>"0", "buildIsLastest"=>"1", "buildFileKey"=>"xxx.apk", "buildFileName"=>"", "buildFileSize"=>"111111", "buildName"=>"testApk", "buildVersion"=>"0.11.0", "buildVersionNo"=>"13", "buildBuildVersion"=>"10", "buildIdentifier"=>"com.pgyer.testapk", "buildIcon"=>"xxxx", "buildDescription"=>"", "buildUpdateDescription"=>"", "buildScreenshots"=>"", "buildShortcutUrl"=>"xxxxxxx", "buildCreated"=>"2023-04-04 11:33:24", "buildUpdated"=>"2023-04-04 11:33:24", "buildQRCodeURL"=>"https://www.pgyer.com/app/qrcodeHistory/xxxxxx", "fastlaneAddedWholeVisitUrl"=>"https://www.pgyer.com/xxxxxx"} 87 | puts "url = #{answer["fastlaneAddedWholeVisitUrl"]}" 88 | 89 | # terminal outputs like this if uploaded successfully 90 | # url = https://www.pgyer.com/xxxxxx 91 | 92 | # More information please visit https://www.pgyer.com/doc/view/api#fastUploadApp to check API "https://www.pgyer.com/apiv2/app/buildInfo" 93 | 94 | end 95 | ``` 96 | 97 | 98 | 99 | 100 | And more params 101 | 102 | ``` 103 | 104 | password: Set password to protect app. 105 | 106 | update_description: Set update description for app. 107 | 108 | install_type: Set install type for app (1=public, 2=password, 3=invite), Please set as a string. 109 | 110 | install_date: Set install type for app (1=Set valid time, 2=Long-term effective, other=Do not modify the last setting), Please set as a string. 111 | 112 | install_start_date: The value is a string of characters, for example, 2018-01-01. 113 | 114 | install_end_date: The value is a string of characters, such as 2018-12-31. 115 | 116 | channel: Need to update the specified channel of the download short link, can specify only one channel, string type, such as: ABCD. Specifies channel uploads. If you do not have one, do not use this parameter. 117 | 118 | user_download_file_name: The name of the file downloaded by the user, the string type, such as: test.apk. 119 | 120 | save_uploaded_info_json: (true or false, default to false) Whether to save the information returned by the API interface to a json file. 121 | 122 | 123 | 124 | ``` 125 | ## Run tests for this plugin 126 | 127 | To run both the tests, and code style validation, run 128 | 129 | ``` 130 | rake 131 | ``` 132 | 133 | To automatically fix many of the styling issues, use 134 | ``` 135 | rubocop -a 136 | ``` 137 | 138 | ## Issues and Feedback 139 | 140 | For any other issues and feedback about this plugin, please submit it to this repository. 141 | 142 | ## Troubleshooting 143 | 144 | If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide. 145 | 146 | ## Using `fastlane` Plugins 147 | 148 | For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/). 149 | 150 | ## About `fastlane` 151 | 152 | `fastlane` is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools). 153 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | 3 | require 'rspec/core/rake_task' 4 | RSpec::Core::RakeTask.new 5 | 6 | require 'rubocop/rake_task' 7 | RuboCop::RakeTask.new(:rubocop) 8 | 9 | task default: [:spec, :rubocop] 10 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | test: 2 | override: 3 | - bundle exec rake 4 | machine: 5 | ruby: 6 | version: 2.2.4 7 | # Enable xcode below if you need macOS 8 | # xcode: 9 | # version: "7.3" 10 | -------------------------------------------------------------------------------- /fastlane-plugin-pgyer.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path("../lib", __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require "fastlane/plugin/pgyer/version" 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "fastlane-plugin-pgyer" 8 | spec.version = Fastlane::Pgyer::VERSION 9 | spec.author = "rexshi" 10 | spec.email = "rexshi@pgyer.com" 11 | 12 | spec.summary = "distribute app to pgyer beta testing service" 13 | spec.homepage = "https://github.com/shishirui/fastlane-plugin-pgyer" 14 | spec.license = "MIT" 15 | 16 | spec.files = Dir["lib/**/*"] + %w(README.md LICENSE) 17 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 18 | spec.require_paths = ["lib"] 19 | 20 | spec.required_ruby_version = ">= 2.6" 21 | 22 | # Don't add a dependency to fastlane or fastlane_re 23 | # since this would cause a circular dependency 24 | 25 | # spec.add_dependency 'your-dependency', '~> 1.0.0' 26 | 27 | spec.add_development_dependency("bundler") 28 | spec.add_development_dependency("fastlane", ">= 2.208.0") 29 | spec.add_development_dependency("pry") 30 | spec.add_development_dependency("rake") 31 | spec.add_development_dependency("rspec") 32 | spec.add_development_dependency("rspec_junit_formatter") 33 | spec.add_development_dependency("rubocop", "1.12.1") 34 | spec.add_development_dependency("rubocop-performance") 35 | spec.add_development_dependency("rubocop-require_tools") 36 | spec.add_development_dependency("simplecov") 37 | end 38 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | lane :test do 2 | pgyer 3 | end 4 | -------------------------------------------------------------------------------- /fastlane/Pluginfile: -------------------------------------------------------------------------------- 1 | # Autogenerated by fastlane 2 | -------------------------------------------------------------------------------- /lib/fastlane/plugin/pgyer.rb: -------------------------------------------------------------------------------- 1 | require 'fastlane/plugin/pgyer/version' 2 | 3 | module Fastlane 4 | module Pgyer 5 | # Return all .rb files inside the "actions" and "helper" directory 6 | def self.all_classes 7 | Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))] 8 | end 9 | end 10 | end 11 | 12 | # By default we want to import all available actions and helpers 13 | # A plugin can contain any number of actions and plugins 14 | Fastlane::Pgyer.all_classes.each do |current| 15 | require current 16 | end 17 | -------------------------------------------------------------------------------- /lib/fastlane/plugin/pgyer/actions/pgyer_action.rb: -------------------------------------------------------------------------------- 1 | require "faraday" 2 | require "faraday_middleware" 3 | 4 | module Fastlane 5 | module Actions 6 | class PgyerAction < Action 7 | def self.run(params) 8 | UI.message("The pgyer plugin is working.") 9 | 10 | api_key = params[:api_key] 11 | 12 | build_file = [ 13 | params[:ipa], 14 | params[:apk], 15 | ].detect { |e| !e.to_s.empty? } 16 | 17 | if build_file.nil? 18 | UI.user_error!("You have to provide a build file") 19 | end 20 | 21 | type = params[:ipa].nil? ? "android" : "ios" 22 | 23 | UI.message "build_file: #{build_file}, type: #{type}" 24 | 25 | install_type = params[:install_type] 26 | if install_type.nil? 27 | install_type = "1" 28 | end 29 | 30 | password = params[:password] 31 | if password.nil? 32 | password = "" 33 | end 34 | 35 | request_params = { 36 | "_api_key" => api_key, 37 | "buildType" => type, 38 | "buildInstallType" => install_type, 39 | "buildPassword" => password, 40 | } 41 | request_params["oversea"] = params[:oversea] unless params[:oversea].nil? 42 | 43 | update_description = params[:update_description] 44 | 45 | if update_description != nil 46 | request_params["buildUpdateDescription"] = update_description 47 | end 48 | 49 | install_date = params[:install_date] 50 | 51 | if install_date != nil 52 | if install_date == "1" 53 | request_params["buildInstallDate"] = install_date 54 | install_start_date = params[:install_start_date] 55 | request_params["buildInstallStartDate"] = install_start_date 56 | install_end_date = params[:install_end_date] 57 | request_params["buildInstallEndDate"] = install_end_date 58 | elsif install_date == "2" 59 | request_params["buildInstallDate"] = install_date 60 | end 61 | end 62 | 63 | channel = params[:channel] 64 | if channel != nil 65 | request_params["buildChannelShortcut"] = channel 66 | end 67 | 68 | # start upload 69 | conn_options = { 70 | request: { 71 | timeout: 1000, 72 | open_timeout: 300, 73 | }, 74 | } 75 | 76 | api_host = "https://www.pgyer.com/apiv2/app" 77 | 78 | pgyer_client = Faraday.new(nil, conn_options) do |c| 79 | c.request :multipart 80 | c.request :url_encoded 81 | c.response :json, content_type: /\bjson$/ 82 | c.adapter :net_http 83 | end 84 | 85 | response = pgyer_client.post "#{api_host}/getCOSToken", request_params 86 | 87 | info = response.body 88 | 89 | if info["code"] != 0 90 | UI.user_error!("Get token is failed, info: #{info}") 91 | end 92 | 93 | key = info["data"]["key"] 94 | 95 | endpoint = info["data"]["endpoint"] 96 | 97 | request_params = info["data"]["params"] 98 | 99 | if key.nil? || endpoint.nil? || request_params.nil? 100 | UI.user_error!("Get token is failed") 101 | end 102 | content_type = type == "android" ? "application/vnd.android.package-archive" : "application/octet-stream" 103 | 104 | if !params[:user_download_file_name].nil? 105 | request_params["x-cos-meta-file-name"] = params[:user_download_file_name] 106 | end 107 | request_params["file"] = Faraday::UploadIO.new(build_file, content_type) 108 | 109 | UI.message "Start upload #{build_file} to pgyer..." 110 | 111 | UI.message "Upload endpoint: #{endpoint}" 112 | 113 | UI.message "Upload request_params: #{request_params}" 114 | 115 | 116 | 117 | response = pgyer_client.post endpoint, request_params 118 | 119 | if response.status != 204 120 | UI.user_error!("PGYER Plugin Upload Error: #{response.body}") 121 | end 122 | 123 | answer = self.checkPublishStatus(pgyer_client, api_host, api_key, key) 124 | 125 | if params[:save_uploaded_info_json] 126 | File.open("pgyer-fastlane-uploaded-app-info.json", "w") do |f| 127 | f.write(answer.to_json) 128 | end 129 | end 130 | answer 131 | end 132 | 133 | def self.description 134 | "distribute app to pgyer beta testing service" 135 | end 136 | 137 | def self.authors 138 | ["rexshi"] 139 | end 140 | 141 | def self.return_value 142 | # If your method provides a return value, you can describe here what it does 143 | end 144 | 145 | def self.details 146 | # Optional: 147 | "distribute app to pgyer beta testing service" 148 | end 149 | 150 | def self.available_options 151 | [ 152 | FastlaneCore::ConfigItem.new(key: :api_key, 153 | env_name: "PGYER_API_KEY", 154 | description: "api_key in your pgyer account", 155 | optional: false, 156 | type: String), 157 | FastlaneCore::ConfigItem.new(key: :apk, 158 | env_name: "PGYER_APK", 159 | description: "Path to your APK file", 160 | default_value: Actions.lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH], 161 | optional: true, 162 | verify_block: proc do |value| 163 | UI.user_error!("Couldn't find apk file at path '#{value}'") unless File.exist?(value) 164 | end, 165 | conflicting_options: [:ipa], 166 | conflict_block: proc do |value| 167 | UI.user_error!("You can't use 'apk' and '#{value.key}' options in one run") 168 | end), 169 | FastlaneCore::ConfigItem.new(key: :ipa, 170 | env_name: "PGYER_IPA", 171 | description: "Path to your IPA file. Optional if you use the _gym_ or _xcodebuild_ action. For Mac zip the .app. For Android provide path to .apk file", 172 | default_value: Actions.lane_context[SharedValues::IPA_OUTPUT_PATH], 173 | optional: true, 174 | verify_block: proc do |value| 175 | UI.user_error!("Couldn't find ipa file at path '#{value}'") unless File.exist?(value) 176 | end, 177 | conflicting_options: [:apk], 178 | conflict_block: proc do |value| 179 | UI.user_error!("You can't use 'ipa' and '#{value.key}' options in one run") 180 | end), 181 | FastlaneCore::ConfigItem.new(key: :password, 182 | env_name: "PGYER_PASSWORD", 183 | description: "Set password to protect app", 184 | optional: true, 185 | type: String), 186 | 187 | FastlaneCore::ConfigItem.new(key: :user_download_file_name, 188 | env_name: "USER_DOWNLOAD_FILE_NAME", 189 | description: "Rename the file name that user downloaded from pgyer", 190 | optional: true, 191 | type: String), 192 | 193 | FastlaneCore::ConfigItem.new(key: :update_description, 194 | env_name: "PGYER_UPDATE_DESCRIPTION", 195 | description: "Set update description for app", 196 | optional: true, 197 | type: String), 198 | 199 | FastlaneCore::ConfigItem.new(key: :save_uploaded_info_json, 200 | env_name: "PGYER_SAVE_UPLOADED_INFO_JSON", 201 | description: "Save uploaded info json to file named pgyer-fastlane-uploaded-app-info.json", 202 | optional: true, 203 | default_value: false, 204 | type: Boolean), 205 | 206 | FastlaneCore::ConfigItem.new(key: :install_type, 207 | env_name: "PGYER_INSTALL_TYPE", 208 | description: "Set install type for app (1=public, 2=password, 3=invite). Please set as a string", 209 | optional: true, 210 | type: String), 211 | FastlaneCore::ConfigItem.new(key: :install_date, 212 | env_name: "PGYER_INSTALL_DATE", 213 | description: "Set install type for app (1=Set valid time, 2=Long-term effective, other=Do not modify the last setting). Please set as a string", 214 | optional: true, 215 | type: String), 216 | FastlaneCore::ConfigItem.new(key: :install_start_date, 217 | env_name: "PGYER_INSTALL_START_DATE", 218 | description: "The value is a string of characters, for example, 2018-01-01", 219 | optional: true, 220 | type: String), 221 | 222 | FastlaneCore::ConfigItem.new(key: :install_end_date, 223 | env_name: "PGYER_INSTALL_END_DATE", 224 | description: "The value is a string of characters, such as 2018-12-31", 225 | optional: true, 226 | type: String), 227 | 228 | FastlaneCore::ConfigItem.new(key: :oversea, 229 | env_name: "PGYER_OVERSEA", 230 | description: "Whether to use overseas acceleration. 1 for overseas accelerated upload, 0 for domestic accelerated upload, not filled in for automatic judgment based on IP", 231 | optional: true, 232 | type: Numeric), 233 | FastlaneCore::ConfigItem.new(key: :channel, 234 | env_name: "PGYER_SPECIFIED_CHANNEL", 235 | description: "Need to update the specified channel of the download short link, can specify only one channel, string type, such as: ABCD", 236 | optional: true, 237 | type: String), 238 | ] 239 | end 240 | 241 | def self.is_supported?(platform) 242 | # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example) 243 | # See: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Platforms.md 244 | # 245 | [:ios, :mac, :android].include?(platform) 246 | true 247 | end 248 | 249 | private 250 | 251 | def self.checkPublishStatus(client, api_host, api_key, buildKey) 252 | url ="#{api_host}/buildInfo" 253 | UI.message "checkPublishStatus url: #{url}" 254 | response = client.post "#{api_host}/buildInfo", { :_api_key => api_key, :buildKey => buildKey } 255 | info = response.body 256 | code = info["code"] 257 | if code == 0 258 | UI.success "Upload success. BuildInfo is #{info["data"]}." 259 | shortUrl = info["data"]["buildShortcutUrl"] 260 | if shortUrl.nil? || shortUrl == "" 261 | shortUrl = info["data"]["buildKey"] 262 | end 263 | info["data"]["fastlaneAddedWholeVisitUrl"] = "https://www.pgyer.com/#{shortUrl}" 264 | UI.success "Upload success. Visit this URL to see: #{info["data"]["fastlaneAddedWholeVisitUrl"]}" 265 | return info["data"] 266 | elsif code == 1246 || code == 1247 267 | sleep 3 268 | self.checkPublishStatus(client, api_host, api_key, buildKey) 269 | else 270 | UI.user_error!("PGYER Plugin Published Error: #{info} buildKey: #{buildKey}") 271 | end 272 | end 273 | end 274 | end 275 | end 276 | -------------------------------------------------------------------------------- /lib/fastlane/plugin/pgyer/helper/pgyer_helper.rb: -------------------------------------------------------------------------------- 1 | require "fastlane_core/ui/ui" 2 | 3 | module Fastlane 4 | UI = FastlaneCore::UI unless Fastlane.const_defined?("UI") 5 | 6 | module Helper 7 | class PgyerHelper 8 | # class methods that you define here become available in your action 9 | # as `Helper::PgyerHelper.your_method` 10 | # 11 | def self.show_message 12 | UI.message("Hello from the pgyer plugin helper!") 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/fastlane/plugin/pgyer/version.rb: -------------------------------------------------------------------------------- 1 | module Fastlane 2 | module Pgyer 3 | VERSION = "0.2.9" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/pgyer_action_spec.rb: -------------------------------------------------------------------------------- 1 | describe Fastlane::Actions::PgyerAction do 2 | describe '#run' do 3 | it 'prints a message' do 4 | expect(Fastlane::UI).to receive(:message).with("The pgyer plugin is working!") 5 | 6 | Fastlane::Actions::PgyerAction.run(nil) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require "simplecov" 2 | 3 | # SimpleCov.minimum_coverage 95 4 | SimpleCov.start 5 | 6 | # This module is only used to check the environment is currently a testing env 7 | module SpecHelper 8 | end 9 | 10 | require "fastlane" # to import the Action super class 11 | require "fastlane/plugin/pgyer" # import the actual plugin 12 | 13 | Fastlane.load_actions # load other actions (in case your plugin calls other actions or shared values) 14 | --------------------------------------------------------------------------------