fastlane-plugin-translate_gpt_release_notes 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: acf57fd59e42c6a303f3351aa8b77e3b0218f1cdee9182651c93b60d88919cf5
4
+ data.tar.gz: cf64458515ae18c2f4df33cd10eb6105aa258bb3e5a3b72c653397e3de4a5325
5
+ SHA512:
6
+ metadata.gz: 8db4147388d59f649f8eddfdec8fbe099e06243aab5e90f07c8a4b6a860955cb386f09a9151272b8a66863fa179cc632eb321eb909b3b4bb65a87a8db4a1767f
7
+ data.tar.gz: e1a8558527d3feefdad58fac9e6d165335d1c8e32b8802022da8a25e4be025b5197b8361424bb9a61693ec0a251ee4526e82706240bd9d1258d3b5b47fa30520
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Anton Karliner <anton@karliner.pro>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,109 @@
1
+ ![logo](images/logo.png)
2
+
3
+ # translate-gpt-release-notes plugin
4
+
5
+ ## Getting Started
6
+
7
+ This project is a [fastlane](https://github.com/fastlane/fastlane) plugin. To get started with `fastlane-plugin-translate_gpt`, add it to your project by running:
8
+
9
+ ```bash
10
+ fastlane add_plugin translate_gpt_release_notes
11
+ ```
12
+
13
+ ## About translate-gpt-release-notes
14
+
15
+ `translate-gpt-release-notes` is a fastlane plugin that allows you to translate release notes or changelogs for iOS and Android apps using OpenAI GPT API. Based on [translate-gpt by ftp27](https://github.com/ftp27/fastlane-plugin-translate_gpt).
16
+
17
+
18
+ ## How it works:
19
+
20
+ `translate-gpt-release-notes` takes the changelog file for master locale (default: en-US), detects other locales based on fastlane metadata folder structure, translates changelog to all other languages with OpenAI API and creates localized .txt changelong files in respective folders
21
+
22
+ ## Example
23
+
24
+ The following example demonstrates how to use `translate-gpt-release-notes` in a `Fastfile`
25
+
26
+ ```ruby
27
+ lane :translate_release_notes do
28
+ translate_gpt_release_notes(
29
+ master_locale: 'en-US',
30
+ platform: 'ios',
31
+ context: 'This is an app about cute kittens'
32
+ # other parameters...
33
+ )
34
+ end
35
+ ```
36
+
37
+ ## Options
38
+
39
+ The following options are available for `translate-gpt-release-notes`:
40
+
41
+ | Key | Description | Environment Variable |
42
+ | --- | --- | --- |
43
+ | `api_token` | The API key for your OpenAI GPT account. | `GPT_API_KEY` |
44
+ | `model_name` | Name of the ChatGPT model to use (default: gpt-4-1106-preview) | `GPT_MODEL_NAME` |
45
+ | `temperature` | What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. Defaults to 0.5 | `GPT_TEMPERATURE` |
46
+ | `request_timeout` | Timeout for the request in seconds. Defaults to 30 seconds | `GPT_REQUEST_TIMEOUT` |
47
+ | `master_locale` | Master language/locale for the source texts | `MASTER_LOCALE` |
48
+ | `context` | Context for translation to improve accuracy | `GPT_CONTEXT` |
49
+ | `platform` | Platform for which to translate (ios or android, defaults to ios).| `PLATFORM` |
50
+
51
+ ## Authentication
52
+
53
+ `translate-gpt-release-notes` supports multiple authentication methods for the OpenAI GPT API:
54
+
55
+ ### API Key
56
+
57
+ You can provide your API key directly as an option to `translate-gpt`:
58
+
59
+ ```ruby
60
+ translate_gpt_release_notes(
61
+ api_token: 'YOUR_API_KEY',
62
+ master_locale: 'en-US',
63
+ platform: 'ios',
64
+ context: 'This is an app about cute kittens'
65
+
66
+ )
67
+ ```
68
+
69
+ ### Environment Variable
70
+
71
+ Alternatively, you can set the `GPT_API_KEY` environment variable with your API key:
72
+
73
+ ```bash
74
+ export GPT_API_KEY='YOUR_API_KEY'
75
+ ```
76
+
77
+ And then call `translate-gp-release-notes` without specifying an API key:
78
+
79
+ ```ruby
80
+ translate_gpt_release_notes(
81
+ master_locale: 'en-US',
82
+ platform: 'ios',
83
+ context: 'This is an app about cute kittens'
84
+ )
85
+ ```
86
+ ## Important notes:
87
+
88
+ 1. Android has a limit of 500 symbols for changelogs and sometimes translations can exceed this number, which leads to Google API errors when submitting the app. Plugin **tries** to handle this, however errors happen. Reducing the length of master_locale changelog usually helps. iOS has a limit of 4000 symbols, which is plenty.
89
+ 2. OpenAI API usage cost money, keep it in mind.
90
+
91
+ ## Issues and Feedback
92
+
93
+ If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide. For any other issues and feedback about this plugin, please submit it to this repository.
94
+
95
+ ## Using _fastlane_ Plugins
96
+
97
+ For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/).
98
+
99
+ ## About _fastlane_
100
+
101
+ _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).
102
+
103
+ ## Contributing
104
+
105
+ If you'd like to contribute to this plugin, please fork the repository and make your changes. When you're ready, submit a pull request explaining your changes.
106
+
107
+ ## License
108
+
109
+ This action is released under the [MIT License](LICENSE).
@@ -0,0 +1,156 @@
1
+ require 'fastlane/action'
2
+ require 'openai'
3
+ require_relative '../helper/translate_gpt_release_notes_helper'
4
+
5
+ module Fastlane
6
+ module Actions
7
+ class TranslateGptReleaseNotesAction < Action
8
+ def self.run(params)
9
+ # Determine if iOS or Android based on the platform
10
+ is_ios = params[:platform] == 'ios'
11
+ base_directory = is_ios ? 'fastlane/metadata' : 'fastlane/metadata/android'
12
+
13
+ # Check if the base directory exists before proceeding
14
+ unless Dir.exist?(base_directory)
15
+ UI.error("Directory does not exist: #{base_directory}")
16
+ return
17
+ end
18
+
19
+ locales = list_locales(base_directory)
20
+ master_texts = fetch_master_texts(base_directory, params[:master_locale], is_ios)
21
+
22
+ helper = Helper::TranslateGptReleaseNotesHelper.new(params)
23
+ translated_texts = locales.each_with_object({}) do |locale, translations|
24
+ next if locale == params[:master_locale] # Skip master locale
25
+ translations[locale] = helper.translate_text(master_texts, locale, params[:platform])
26
+ end
27
+
28
+ update_translated_texts(base_directory, translated_texts, is_ios, params)
29
+ end
30
+
31
+ def self.list_locales(base_directory)
32
+ Dir.children(base_directory).select { |entry| File.directory?(File.join(base_directory, entry)) }
33
+ end
34
+
35
+ def self.fetch_master_texts(base_directory, master_locale, is_ios)
36
+ master_path = is_ios ? File.join(base_directory, master_locale) : File.join(base_directory, master_locale, 'changelogs')
37
+
38
+ # Check if the master path exists
39
+ unless Dir.exist?(master_path)
40
+ UI.error("Master path does not exist: #{master_path}")
41
+ return nil
42
+ end
43
+
44
+ filename = is_ios ? 'release_notes.txt' : highest_numbered_file(master_path)
45
+
46
+ # Check if the file exists before reading
47
+ file_path = File.join(master_path, filename)
48
+ unless File.exist?(file_path)
49
+ UI.error("File does not exist: #{file_path}")
50
+ return nil
51
+ end
52
+
53
+ File.read(file_path)
54
+ end
55
+
56
+ def self.highest_numbered_file(directory)
57
+ Dir[File.join(directory, '*.txt')].max_by { |f| File.basename(f, '.txt').to_i }.split('/').last
58
+ end
59
+
60
+ def self.update_translated_texts(base_directory, translated_texts, is_ios, params)
61
+ translated_texts.each do |locale, text|
62
+ next if locale == params[:master_locale] # Skip master locale
63
+
64
+ target_path = is_ios ? File.join(base_directory, locale) : File.join(base_directory, locale, 'changelogs')
65
+
66
+ # Ensure target path exists or create it
67
+ FileUtils.mkdir_p(target_path) unless Dir.exist?(target_path)
68
+
69
+ filename = is_ios ? 'release_notes.txt' : highest_numbered_file(File.join(base_directory, params[:master_locale], 'changelogs'))
70
+
71
+ # Write the translated text to the file
72
+ File.write(File.join(target_path, filename), text)
73
+ end
74
+ end
75
+
76
+
77
+ def self.description
78
+ "Translate release notes or changelogs for iOS and Android apps using OpenAI's GPT API"
79
+ end
80
+
81
+ def self.available_options
82
+ [
83
+ FastlaneCore::ConfigItem.new(
84
+ key: :api_token,
85
+ env_name: "GPT_API_KEY",
86
+ description: "API token for ChatGPT",
87
+ sensitive: true,
88
+ code_gen_sensitive: true,
89
+ default_value: ""
90
+ ),
91
+ FastlaneCore::ConfigItem.new(
92
+ key: :model_name,
93
+ env_name: "GPT_MODEL_NAME",
94
+ description: "Name of the ChatGPT model to use",
95
+ default_value: "gpt-4-1106-preview"
96
+ ),
97
+ FastlaneCore::ConfigItem.new(
98
+ key: :request_timeout,
99
+ env_name: "GPT_REQUEST_TIMEOUT",
100
+ description: "Timeout for the request in seconds",
101
+ type: Integer,
102
+ default_value: 30
103
+ ),
104
+ FastlaneCore::ConfigItem.new(
105
+ key: :temperature,
106
+ env_name: "GPT_TEMPERATURE",
107
+ description: "What sampling temperature to use, between 0 and 2",
108
+ type: Float,
109
+ optional: true,
110
+ default_value: 0.5
111
+ ),
112
+ FastlaneCore::ConfigItem.new(
113
+ key: :master_locale,
114
+ env_name: "MASTER_LOCALE",
115
+ description: "Master language/locale for the source texts",
116
+ type: String,
117
+ default_value: "en-US"
118
+ ),
119
+ FastlaneCore::ConfigItem.new(
120
+ key: :platform,
121
+ env_name: "PLATFORM",
122
+ description: "Platform for which to translate (ios or android)",
123
+ is_string: true,
124
+ default_value: 'ios'
125
+ ),
126
+ FastlaneCore::ConfigItem.new(
127
+ key: :context,
128
+ env_name: "GPT_CONTEXT",
129
+ description: "Context for translation to improve accuracy",
130
+ optional: true,
131
+ type: String
132
+ )
133
+ ]
134
+ end
135
+
136
+ def self.output
137
+ [
138
+ ['LOCALES_TRANSLATED', 'List of locales to which translations were applied'],
139
+ ['MASTER_LOCALE', 'The master language/locale used as the source for translations']
140
+ ]
141
+ end
142
+
143
+ def self.return_value
144
+ nil
145
+ end
146
+
147
+ def self.authors
148
+ ["antonkarliner"]
149
+ end
150
+
151
+ def self.is_supported?(platform)
152
+ [:ios, :android].include?(platform)
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,102 @@
1
+ require 'fastlane_core/ui/ui'
2
+ require 'openai'
3
+ require 'json'
4
+
5
+ module Fastlane
6
+ UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
7
+
8
+ module Helper
9
+ class TranslateGptReleaseNotesHelper
10
+ def initialize(params)
11
+ @params = params
12
+ @client = OpenAI::Client.new(
13
+ access_token: params[:api_token],
14
+ request_timeout: params[:request_timeout]
15
+ )
16
+ end
17
+
18
+ # Request a translation from the GPT API
19
+ def translate_text(text, target_locale, platform)
20
+ source_locale = @params[:master_locale]
21
+ prompt = "Translate this text from #{source_locale} to #{target_locale}:\n#{text}"
22
+
23
+
24
+ # Add condition for Android platform
25
+ if platform == 'android'
26
+ prompt += "\n\nNote: The length of the translated text should be 500 symbols maximum. Rephrase a little if needed."
27
+ end
28
+
29
+ # Context handling
30
+ if @params[:context] && !@params[:context].empty?
31
+ prompt = "Context: #{@params[:context]}\n" + prompt
32
+ end
33
+
34
+ # Updated API call with max_tokens
35
+ response = @client.chat(
36
+ parameters: {
37
+ model: @params[:model_name] || 'gpt-4-1106-preview',
38
+ messages: [{ role: "user", content: prompt }],
39
+ temperature: @params[:temperature] || 0.5
40
+ }
41
+ )
42
+
43
+
44
+ error = response.dig("error", "message")
45
+ if error
46
+ UI.error "Error translating text: #{error}"
47
+ return nil
48
+ else
49
+ translated_text = response.dig("choices", 0, "message", "content").strip
50
+ UI.message "Translated text: #{translated_text}"
51
+ return translated_text
52
+ end
53
+ end
54
+
55
+ # Sleep for a specified number of seconds, displaying a progress bar
56
+ def wait(seconds = @params[:request_timeout])
57
+ sleep_time = 0
58
+ while sleep_time < seconds
59
+ percent_complete = (sleep_time.to_f / seconds.to_f) * 100.0
60
+ progress_bar_width = 20
61
+ completed_width = (progress_bar_width * percent_complete / 100.0).round
62
+ remaining_width = progress_bar_width - completed_width
63
+ print "\rTimeout ["
64
+ print Colorizer::code(:green)
65
+ print "=" * completed_width
66
+ print " " * remaining_width
67
+ print Colorizer::code(:reset)
68
+ print "]"
69
+ print " %.2f%%" % percent_complete
70
+ $stdout.flush
71
+ sleep(1)
72
+ sleep_time += 1
73
+ end
74
+ print "\r"
75
+ $stdout.flush
76
+ end
77
+ end
78
+
79
+ # Helper class for bash colors
80
+ class Colorizer
81
+ COLORS = {
82
+ black: 30,
83
+ red: 31,
84
+ green: 32,
85
+ yellow: 33,
86
+ blue: 34,
87
+ magenta: 35,
88
+ cyan: 36,
89
+ white: 37,
90
+ reset: 0,
91
+ }
92
+
93
+ def self.colorize(text, color)
94
+ color_code = COLORS[color.to_sym]
95
+ "\e[#{color_code}m#{text}\e[0m"
96
+ end
97
+ def self.code(color)
98
+ "\e[#{COLORS[color.to_sym]}m"
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,5 @@
1
+ module Fastlane
2
+ module TranslateGptReleaseNotes
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,16 @@
1
+ require 'fastlane/plugin/translate_gpt_release_notes/version'
2
+
3
+ module Fastlane
4
+ module TranslateGptReleaseNotes
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::TranslateGptReleaseNotes.all_classes.each do |current|
15
+ require current
16
+ end
metadata ADDED
@@ -0,0 +1,220 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fastlane-plugin-translate_gpt_release_notes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Anton Karliner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-11-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ruby-openai
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: loco_strings
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: fastlane
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 2.212.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 2.212.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec_junit_formatter
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '='
130
+ - !ruby/object:Gem::Version
131
+ version: 1.12.1
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '='
137
+ - !ruby/object:Gem::Version
138
+ version: 1.12.1
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop-performance
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rubocop-require_tools
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: simplecov
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ description:
182
+ email: anton@karliner.pro
183
+ executables: []
184
+ extensions: []
185
+ extra_rdoc_files: []
186
+ files:
187
+ - LICENSE
188
+ - README.md
189
+ - lib/fastlane/plugin/translate_gpt_release_notes.rb
190
+ - lib/fastlane/plugin/translate_gpt_release_notes/actions/translate_gpt_release_notes_action.rb
191
+ - lib/fastlane/plugin/translate_gpt_release_notes/helper/translate_gpt_release_notes_helper.rb
192
+ - lib/fastlane/plugin/translate_gpt_release_notes/version.rb
193
+ homepage: https://github.com/antonkarliner/fastlane-plugin-translate_gpt_release_notes
194
+ licenses:
195
+ - MIT
196
+ metadata:
197
+ homepage_uri: https://github.com/antonkarliner/fastlane-plugin-translate_gpt_release_notes
198
+ source_code_uri: https://github.com/antonkarliner/fastlane-plugin-translate_gpt_release_notes
199
+ github_repo: https://github.com/antonkarliner/fastlane-plugin-translate_gpt_release_notes
200
+ post_install_message:
201
+ rdoc_options: []
202
+ require_paths:
203
+ - lib
204
+ required_ruby_version: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '2.6'
209
+ required_rubygems_version: !ruby/object:Gem::Requirement
210
+ requirements:
211
+ - - ">="
212
+ - !ruby/object:Gem::Version
213
+ version: '0'
214
+ requirements: []
215
+ rubygems_version: 3.4.10
216
+ signing_key:
217
+ specification_version: 4
218
+ summary: Translate release notes or changelogs for iOS and Android apps using OpenAI
219
+ GPT API
220
+ test_files: []