fastlane-plugin-sq_ci_tools 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 257dbacc216995731d4d95ff7c652929ccbaad9d2b9839350c573b33e8297943
4
- data.tar.gz: bd197f1d9b0fd417db3f12be458069c3e166b59fbd258e8de8511352d1db7aaf
3
+ metadata.gz: 6e1adc4a553c8e2e11eb9794b3e80987739ec8efeb886cf205b94d6d063bd59e
4
+ data.tar.gz: 66b62a5450752ccb2933888a2724521bdd1b9d9304c74e13179980cbf271b7d6
5
5
  SHA512:
6
- metadata.gz: 01d9e207812753d9e793bdabf40ec927f0916ced2a1c50d130e7d30550c9a592f4441d76ded229c90ddba9a044e56140fbf363b8ccc204619948555f4b9bcf3f
7
- data.tar.gz: ffc06b9fa4328c43cdb5678c5acfaa49c3b024dc3bfb49df1dd628801439d8a74960791ccccebe6eee785844898807af40bd8a28e7f54bc696ea0bab297d2b91
6
+ metadata.gz: 438ca196d7ecf7d2e7cb889960de3ce1c39e807e3d7379530746b0aba67e1bb2dc1f580b14ec73d32006a5fc980da0fb623242d8ffe751e53a7cdc13ecb729ba
7
+ data.tar.gz: cd0905c34af297ba0b4311c6e4cd15905dd3749e0d2cdc1d79838b3aae3549f208bb3d42b29db90b619751493c7c85b29b61e28ada1d3a2e9fde71697976f567
@@ -9,13 +9,14 @@ module Fastlane
9
9
  class SqCiToolsBuildIosApplicationAction < Action
10
10
  def self.run(params)
11
11
 
12
+ timeout = params["timeout"]
12
13
  project_path = params[:project_path]
13
14
  workspace_path = params[:workspace_path]
14
15
  derived_data_path = params[:derived_data_path]
15
16
 
16
17
  ENV['FASTLANE_XCODEBUILD_SETTINGS_RETRIES'] = "10"
17
- ENV['FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT'] = "300"
18
- ENV['FASTLANE_XCODE_LIST_TIMEOUT'] = "300"
18
+ ENV['FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT'] = timeout
19
+ ENV['FASTLANE_XCODE_LIST_TIMEOUT'] = timeout
19
20
 
20
21
  if !workspace_path.nil? && workspace_path != ''
21
22
  ENV['GYM_WORKSPACE'] = workspace_path
@@ -64,7 +65,8 @@ module Fastlane
64
65
  ] +
65
66
  Options::CodeSigning.options +
66
67
  Options::Keychain.options +
67
- Options::IosApp.options
68
+ Options::IosApp.options +
69
+ Options::Shared.options
68
70
  end
69
71
 
70
72
  def self.return_value
@@ -0,0 +1,96 @@
1
+ require 'fastlane/action'
2
+ require_relative '../helper/sq_ci_ru_store_helper'
3
+
4
+ module Fastlane
5
+ module Actions
6
+
7
+ module SharedValues
8
+ SQ_CI_RU_STORE_DRAFT_ID = :SQ_CI_RU_STORE_DRAFT_ID
9
+ end
10
+
11
+ class SqCiToolsRuStoreFindOrCreateDraftIdAction < Action
12
+ def self.run(params)
13
+ token = params[:token]
14
+ package_name = params[:package_name]
15
+ changelog_path = params[:changelog_path]
16
+ publish_type = params[:publish_type]
17
+ publish_date_time = params[:publish_date_time]
18
+ timeout = params[:timeout]
19
+
20
+ draft_id = Helper::RuStoreHelper.get_draft_id(
21
+ token: token,
22
+ package_name: package_name,
23
+ timeout: timeout
24
+ )
25
+
26
+ if draft_id.nil?
27
+ draft_id = Helper::RuStoreHelper.create_draft(
28
+ token: token,
29
+ package_name: package_name,
30
+ changelog_path: changelog_path,
31
+ publish_type: publish_type,
32
+ publish_date_time: publish_date_time,
33
+ timeout: timeout
34
+ )
35
+ end
36
+
37
+ lane_context[SharedValues::SQ_CI_RU_STORE_DRAFT_ID] = draft_id
38
+ return draft_id
39
+ end
40
+
41
+ def self.description
42
+ 'Find or create draft id for passed application in RuStore'
43
+ end
44
+
45
+ def self.details
46
+ ''
47
+ end
48
+
49
+ def self.available_options
50
+ [
51
+ FastlaneCore::ConfigItem.new(
52
+ key: :changelog_path,
53
+ env_name: 'SQ_CI_RU_STORE_CHANGELOG_PATH',
54
+ description: 'Path to .txt-file with version\'s changelog',
55
+ optional: false,
56
+ type: String
57
+ ),
58
+ FastlaneCore::ConfigItem.new(
59
+ key: :publish_type,
60
+ env_name: 'SQ_CI_RU_STORE_PUBLISH_TYPE',
61
+ description: 'Version\'s publish type. Available values: MANUAL, INSTANTLY, DELAYED',
62
+ optional: true,
63
+ type: String,
64
+ default_value: 'INSTANTLY'
65
+ ),
66
+ FastlaneCore::ConfigItem.new(
67
+ key: :publish_date_time,
68
+ env_name: 'SQ_CI_RU_STORE_PUBLISH_DATE_TIME',
69
+ description: 'Version\'s publish datetime in format yyyy-MM-dd\'T\'HH:mm:ssXXX. Required for DELAYED publish type',
70
+ optional: true,
71
+ type: String,
72
+ default_value: ''
73
+ )
74
+ ] +
75
+ Options::RuStore.options +
76
+ Options::Shared.options
77
+ end
78
+
79
+ def self.return_type
80
+ :integer
81
+ end
82
+
83
+ def self.return_value
84
+ 'Draft identifier'
85
+ end
86
+
87
+ def self.authors
88
+ ['Semen Kologrivov']
89
+ end
90
+
91
+ def self.is_supported?(_)
92
+ true
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,69 @@
1
+ require 'fastlane/action'
2
+ require_relative '../helper/sq_ci_ru_store_helper'
3
+
4
+ module Fastlane
5
+ module Actions
6
+ module SharedValues
7
+ SQ_CI_RU_STORE_TOKEN = :SQ_CI_RU_STORE_TOKEN
8
+ end
9
+
10
+ class SqCiToolsRuStoreGetTokenAction < Action
11
+ def self.run(params)
12
+ key_id = params[:key_id]
13
+ private_key = params[:private_key]
14
+ timeout = params[:timeout]
15
+ token = Helper::RuStoreHelper.get_token(
16
+ key_id: key_id,
17
+ private_key: private_key,
18
+ timeout: timeout
19
+ )
20
+
21
+ lane_context[SharedValues::SQ_CI_RU_STORE_TOKEN] = token
22
+ return token
23
+ end
24
+
25
+ def self.description
26
+ 'Fetch token for RuStore API'
27
+ end
28
+
29
+ def self.details
30
+ ''
31
+ end
32
+
33
+ def self.available_options
34
+ [
35
+ FastlaneCore::ConfigItem.new(
36
+ key: :key_id,
37
+ env_name: 'SQ_CI_RU_STORE_KEY_ID',
38
+ description: 'Identifier of RuStore\'s API key',
39
+ optional: false,
40
+ type: String
41
+ ),
42
+ FastlaneCore::ConfigItem.new(
43
+ key: :private_key,
44
+ env_name: 'SQ_CI_RU_STORE_PRIVATE_KEY',
45
+ description: 'Private key for RuStore\'s API key',
46
+ optional: false,
47
+ type: String
48
+ )
49
+ ] + Options::Shared.options
50
+ end
51
+
52
+ def self.return_type
53
+ :string
54
+ end
55
+
56
+ def self.return_value
57
+ 'RuStore API Token'
58
+ end
59
+
60
+ def self.authors
61
+ ['Semen Kologrivov']
62
+ end
63
+
64
+ def self.is_supported?(_)
65
+ true
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,54 @@
1
+ require 'fastlane/action'
2
+ require_relative '../helper/sq_ci_ru_store_helper'
3
+
4
+ module Fastlane
5
+ module Actions
6
+
7
+ class SqCiToolsRuStoreSendToReviewAction < Action
8
+ def self.run(params)
9
+ token = params[:token]
10
+ package_name = params[:package_name]
11
+ draft_id = params[:draft_id]
12
+ timeout = params[:timeout]
13
+
14
+ Helper::RuStoreHelper.send_to_review(
15
+ token: token,
16
+ package_name: package_name,
17
+ draft_id: draft_id,
18
+ timeout: timeout
19
+ )
20
+ end
21
+
22
+ def self.description
23
+ 'Send app draft to RuStore\'s review'
24
+ end
25
+
26
+ def self.details
27
+ ''
28
+ end
29
+
30
+ def self.available_options
31
+ [
32
+ FastlaneCore::ConfigItem.new(
33
+ key: :draft_id,
34
+ description: 'Identifier of RuStore app draft',
35
+ optional: false,
36
+ type: String,
37
+ default_value: Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::SQ_CI_RU_STORE_DRAFT_ID],
38
+ default_value_dynamic: true
39
+ )
40
+ ] +
41
+ Options::RuStore.options +
42
+ Options::Shared.options
43
+ end
44
+
45
+ def self.authors
46
+ ['Semen Kologrivov']
47
+ end
48
+
49
+ def self.is_supported?(_)
50
+ true
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,62 @@
1
+ require 'fastlane/action'
2
+ require_relative '../helper/sq_ci_ru_store_helper'
3
+
4
+ module Fastlane
5
+ module Actions
6
+
7
+ class SqCiToolsRuStoreUploadAabAction < Action
8
+ def self.run(params)
9
+ token = params[:token]
10
+ package_name = params[:package_name]
11
+ aab_path = params[:aab_path]
12
+ draft_id = params[:draft_id]
13
+ timeout = params[:timeout]
14
+
15
+ Helper::RuStoreHelper.upload_aab(
16
+ token: token,
17
+ package_name: package_name,
18
+ aab_path: aab_path,
19
+ draft_id: draft_id,
20
+ timeout: timeout
21
+ )
22
+ end
23
+
24
+ def self.description
25
+ 'Upload aab to RuStore\'s app draft'
26
+ end
27
+
28
+ def self.details
29
+ ''
30
+ end
31
+
32
+ def self.available_options
33
+ [
34
+ FastlaneCore::ConfigItem.new(
35
+ key: :aab_path,
36
+ description: 'Path to .aab-file',
37
+ optional: false,
38
+ type: String
39
+ ),
40
+ FastlaneCore::ConfigItem.new(
41
+ key: :draft_id,
42
+ description: 'Identifier of RuStore app draft',
43
+ optional: false,
44
+ type: String,
45
+ default_value: Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::SQ_CI_RU_STORE_DRAFT_ID],
46
+ default_value_dynamic: true,
47
+ )
48
+ ] +
49
+ Options::RuStore.options +
50
+ Options::Shared.options
51
+ end
52
+
53
+ def self.authors
54
+ ['Semen Kologrivov']
55
+ end
56
+
57
+ def self.is_supported?(_)
58
+ true
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,151 @@
1
+ require 'digest'
2
+ require 'json'
3
+
4
+ module Fastlane
5
+ UI = FastlaneCore::UI unless Fastlane.const_defined?(:UI)
6
+
7
+ module Helper
8
+ class RuStoreHelper
9
+
10
+ def self.get_token(key_id:, private_key:, timeout:)
11
+ timestamp = DateTime.now.iso8601(3)
12
+ signature = rsa_sign(timestamp, key_id, private_key)
13
+
14
+ http = self.get_http(timeout: timeout)
15
+
16
+ request = Net::HTTP::Post.new("/public/auth/")
17
+ self.fill_headers(
18
+ request: request
19
+ )
20
+
21
+ request.body = {
22
+ keyId: key_id,
23
+ timestamp: timestamp,
24
+ signature: signature
25
+ }.to_json
26
+ response = http.request(request)
27
+
28
+ if response.kind_of? Net::HTTPSuccess
29
+ json_body = JSON.parse(response.body)
30
+ return json_body["body"]["jwe"]
31
+ else
32
+ UI.user_error!("Unable to get RuStore token: #{response.message}, #{response.body}")
33
+ end
34
+ end
35
+
36
+ def self.get_draft_id(token:, package_name:, timeout:)
37
+ http = self.get_http(timeout: timeout)
38
+
39
+ query_params = URI.encode_www_form({
40
+ versionStatuses: "DRAFT"
41
+ })
42
+
43
+ request = Net::HTTP::Get.new("/public/v1/application/#{package_name}/version?#{query_params}")
44
+ self.fill_headers(
45
+ request: request,
46
+ token: token
47
+ )
48
+
49
+ response = http.request(request)
50
+
51
+ if response.kind_of? Net::HTTPSuccess
52
+ json_body = JSON.parse(response.body)
53
+ versions = json_body["body"]["content"]
54
+ return versions.empty? ? nil : versions[0]["versionId"]
55
+ else
56
+ UI.user_error!("Unable to get RuStore application draft: #{response.message}, #{response.body}")
57
+ end
58
+ end
59
+
60
+ def self.create_draft(
61
+ token:,
62
+ package_name:,
63
+ changelog_path:,
64
+ publish_type:, publish_date_time:,
65
+ timeout:
66
+ )
67
+ http = self.get_http(timeout: timeout)
68
+
69
+ request = Net::HTTP::Post.new("/public/v1/application/#{package_name}/version")
70
+ self.fill_headers(
71
+ request: request,
72
+ token: token
73
+ )
74
+
75
+ changelog = ''
76
+ unless changelog_path.nil?
77
+ changelog_data = File.read(changelog_path)
78
+ if changelog_data.length > 5000
79
+ UI.user_error!("Файл 'Что нового?' содержит более 5000 символов")
80
+ return
81
+ else
82
+ changelog = changelog_data
83
+ end
84
+ end
85
+
86
+ request.body = {
87
+ whatsNew: changelog,
88
+ publishType: publish_type,
89
+ publishDateTime: publish_date_time
90
+ }.to_json
91
+
92
+ response = http.request(request)
93
+
94
+ if response.kind_of? Net::HTTPSuccess
95
+ json_body = JSON.parse(response.body)
96
+ return json_body["body"]
97
+ else
98
+ UI.user_error!("Unable to create RuStore application draft: #{response.message}, #{response.body}")
99
+ end
100
+ end
101
+
102
+ def self.upload_aab(token:, package_name:, draft_id:, aab_path:, timeout:)
103
+ http = self.get_http(timeout: timeout)
104
+ request = Net::HTTP::Post.new("/public/v1/application/#{package_name}/version/#{draft_id}/aab")
105
+
106
+ request.add_field('Public-Token', token)
107
+ request.set_form([['file', File.open(aab_path)]], 'multipart/form-data')
108
+
109
+ response = http.request(request)
110
+ unless response.kind_of? Net::HTTPSuccess
111
+ UI.user_error!("Unable to upload aab to RuStore application draft: #{response.message}, #{response.body}")
112
+ end
113
+ end
114
+
115
+ def self.send_to_review(token:, package_name:, draft_id:, timeout:)
116
+ http = self.get_http(timeout: timeout)
117
+ request = Net::HTTP::Post.new("/public/v1/application/#{package_name}/version/#{draft_id}/commit")
118
+ self.fill_headers(
119
+ request: request,
120
+ token: token
121
+ )
122
+
123
+ response = http.request(request)
124
+ unless response.kind_of? Net::HTTPSuccess
125
+ UI.user_error!("Unable send to review RuStore application draft: #{response.message}, #{response.body}")
126
+ end
127
+ end
128
+
129
+ def self.get_http(timeout:)
130
+ uri = URI.parse("https://public-api.rustore.ru")
131
+ http = Net::HTTP.new(uri.host, uri.port)
132
+ http.use_ssl = true
133
+ http.read_timeout = timeout
134
+ http.set_debug_output($stdout)
135
+
136
+ http
137
+ end
138
+
139
+ def self.fill_headers(request:, token: "", content_type: 'application/json')
140
+ request.add_field('Content-Type', content_type)
141
+ request.add_field('Public-Token', token)
142
+ end
143
+
144
+ def self.rsa_sign(timestamp, key_id, private_key)
145
+ key = OpenSSL::PKey::RSA.new("-----BEGIN RSA PRIVATE KEY-----\n#{private_key}\n-----END RSA PRIVATE KEY-----")
146
+ signature = key.sign(OpenSSL::Digest.new('SHA512'), key_id + timestamp)
147
+ Base64.encode64(signature)
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,34 @@
1
+ require 'fastlane/action'
2
+ require 'fastlane_core/ui/ui'
3
+ require 'fastlane_core/configuration/config_item'
4
+
5
+ module Fastlane
6
+ UI = FastlaneCore::UI unless Fastlane.const_defined?(:UI)
7
+
8
+ module Options
9
+ class RuStore
10
+ def self.options
11
+ [
12
+ FastlaneCore::ConfigItem.new(
13
+ key: :token,
14
+ env_name: 'SQ_CI_RU_STORE_TOKEN',
15
+ description: 'Token for RuStore\'s API',
16
+ optional: false,
17
+ type: String,
18
+ default_value: Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::SQ_CI_RU_STORE_TOKEN],
19
+ default_value_dynamic: true,
20
+ ),
21
+ FastlaneCore::ConfigItem.new(
22
+ key: :package_name,
23
+ env_name: 'SQ_CI_RU_STORE_PACKAGE_NAME',
24
+ description: 'Package name of RuStore application',
25
+ optional: false,
26
+ type: String,
27
+ default_value: CredentialsManager::AppfileConfig.try_fetch_value(:package_name),
28
+ default_value_dynamic: true,
29
+ )
30
+ ]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module SqCiTools
3
- VERSION = "1.1.1".freeze
3
+ VERSION = "1.2.0".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-sq_ci_tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Semen Kologrivov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-15 00:00:00.000000000 Z
11
+ date: 2026-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -167,6 +167,10 @@ files:
167
167
  - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_get_team_identifier_action.rb
168
168
  - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_notify_action.rb
169
169
  - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_prepare_keychain_action.rb
170
+ - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_ru_store_find_or_create_draft_id_action.rb
171
+ - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_ru_store_get_token_action.rb
172
+ - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_ru_store_send_to_review_action.rb
173
+ - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_ru_store_upload_aab_action.rb
170
174
  - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_send_max_message_action.rb
171
175
  - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_send_telegram_message_action.rb
172
176
  - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_set_version_code_action.rb
@@ -178,6 +182,7 @@ files:
178
182
  - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_yandex_tracker_find_issues_action.rb
179
183
  - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_yandex_tracker_transit_issue_action.rb
180
184
  - lib/fastlane/plugin/sq_ci_tools/actions/sq_ci_tools_yandex_tracker_update_issue_action.rb
185
+ - lib/fastlane/plugin/sq_ci_tools/helper/sq_ci_ru_store_helper.rb
181
186
  - lib/fastlane/plugin/sq_ci_tools/helper/sq_ci_tools_helper.rb
182
187
  - lib/fastlane/plugin/sq_ci_tools/helper/sq_ci_tools_yandex_api_helper.rb
183
188
  - lib/fastlane/plugin/sq_ci_tools/helper/sq_ci_tools_yandex_tracker_helper.rb
@@ -187,6 +192,7 @@ files:
187
192
  - lib/fastlane/plugin/sq_ci_tools/options/ios_app.rb
188
193
  - lib/fastlane/plugin/sq_ci_tools/options/keychain.rb
189
194
  - lib/fastlane/plugin/sq_ci_tools/options/max.rb
195
+ - lib/fastlane/plugin/sq_ci_tools/options/ru_store.rb
190
196
  - lib/fastlane/plugin/sq_ci_tools/options/s3.rb
191
197
  - lib/fastlane/plugin/sq_ci_tools/options/shared.rb
192
198
  - lib/fastlane/plugin/sq_ci_tools/options/telegram.rb