google-serverless-exec 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9649c833b15ac827ec528c9834a0c44e1fd4f0f39c98f849fac9da49b469aee6
4
- data.tar.gz: 7d848bb54ede49bc2758d028a777a68c6c3e73704b7a0325474ffa26a6e87861
3
+ metadata.gz: 754f4dd5168b02b49ef0f4104989ecfdf256959f51aa1923bd7911c9eb3fa498
4
+ data.tar.gz: 1e79015a91772bc612166825c3b41723678a5451dc795373b29a19d3b03206fd
5
5
  SHA512:
6
- metadata.gz: 621be644a9cc61b56697d6c8b28237e40c91cbda3105e73b3422714357698ee58afcbf7001ac669ae6d26785c462627acc8c6c59119d90ed52f814256d823102
7
- data.tar.gz: '0568e46e630b6774612c7cc548e8d827eaeb975034ffefc53492c24eecb5baad3f7165d91c673fd8ef6d0644a70180e9ae268cf412517fa1aca91fe2fbe6c802'
6
+ metadata.gz: aad33d97d17a7074d4145a49de59a4bc932908452bcb8e65813295bab0307e6a1307e2dab170c9e247277a6f9039cf8ed73fe66890dcc5bf2cae545e65b98ef6
7
+ data.tar.gz: 6c5c69a97c45c5ddb28d497d23dc8089fea57e2e5f20036905ee2eaf236423e328a62405468b75d817f76b8df7dc0301668ca034e55286b4110f68d4e0577410
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
- ### v0.1.0 / 2021-08-04
3
+ ## 0.2.0 (2021-09-13)
4
4
 
5
- * Initial release
5
+ ### Features
6
+
7
+ * Install the rake task automatically in Rails apps
8
+ * Provide a way to set the project and region for cloud run
9
+
10
+ ### Bug Fixes
11
+
12
+ * Fix deployment strategy by including the entrypoint implementation
13
+ * Fix gem description and links
14
+ * Update task parameter names and documentation
15
+
16
+ ## v0.1.0 / 2021-08-04
17
+
18
+ * Initial release
@@ -0,0 +1,116 @@
1
+ # Copyright 2019 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require "webrick"
16
+ require "monitor"
17
+ require "json"
18
+
19
+ SECRET = <%= secret %>
20
+ COMMAND = Array(<%= command %>)
21
+
22
+ port = Integer ENV["PORT"]
23
+ server = ::WEBrick::HTTPServer.new Port: port
24
+
25
+ Status = ::Struct.new :out_lines, :err_lines, :exit_status, :pid, :start_time
26
+ $status = Status.new [], [], nil, nil, nil
27
+ $status.extend ::MonitorMixin
28
+
29
+ def do_start
30
+ $status.synchronize do
31
+ return unless $status.pid.nil?
32
+ end
33
+ $stdout.puts "Executing: #{COMMAND.inspect}"
34
+ $stdout.flush
35
+ rout, wout = ::IO.pipe
36
+ rerr, werr = ::IO.pipe
37
+ ::Thread.new do
38
+ rout.each_line do |line|
39
+ $status.synchronize { $status.out_lines << line }
40
+ $stdout.puts line
41
+ $stdout.flush
42
+ end
43
+ end
44
+ ::Thread.new do
45
+ rerr.each_line do |line|
46
+ $status.synchronize { $status.err_lines << line }
47
+ $stderr.puts line
48
+ $stderr.flush
49
+ end
50
+ end
51
+ start_time = Time.now.to_i
52
+ pid = ::Process.spawn *COMMAND, err: werr, out: wout
53
+ werr.close
54
+ wout.close
55
+ $status.synchronize do
56
+ $status.pid = pid
57
+ $status.start_time = start_time
58
+ end
59
+ ::Thread.new do
60
+ _pid, status = ::Process.wait2 pid
61
+ $status.synchronize do
62
+ $status.exit_status = status.exitstatus
63
+ end
64
+ end
65
+ end
66
+
67
+ def get_status outpos: 0, errpos: 0
68
+ outlines, errlines, status, start_time =
69
+ $status.synchronize do
70
+ [
71
+ $status.out_lines[outpos..-1],
72
+ $status.err_lines[errpos..-1],
73
+ $status.exit_status,
74
+ $status.start_time
75
+ ]
76
+ end
77
+ {
78
+ "outpos" => outpos + outlines.size,
79
+ "errpos" => errpos + errlines.size,
80
+ "outlines" => outlines,
81
+ "errlines" => errlines,
82
+ "status" => status,
83
+ "time" => Time.now.to_i - start_time
84
+ }
85
+ end
86
+
87
+ server.mount_proc "/_ah/start" do |req, res|
88
+ do_start
89
+ end
90
+
91
+ server.mount_proc "/#{SECRET}" do |req, res|
92
+ do_start
93
+ status = get_status outpos: req.query["outpos"].to_i,
94
+ errpos: req.query["errpos"].to_i
95
+ res.body = JSON.dump status
96
+ end
97
+
98
+ server.mount_proc "/#{SECRET}/kill" do |req, res|
99
+ unless req.request_method == "POST"
100
+ res.status = 404
101
+ return
102
+ end
103
+ $status.synchronize do
104
+ if $status.pid.nil?
105
+ res.status = 404
106
+ return
107
+ end
108
+ ::Process.kill "SIGTERM", $status.pid
109
+ end
110
+ end
111
+
112
+ begin
113
+ server.start
114
+ ensure
115
+ server.shutdown
116
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+
18
+ module Google
19
+ module Serverless
20
+ class Exec
21
+ ##
22
+ # A Railtie that automatically adds the serverless:exec rake task.
23
+ #
24
+ # This Railtie is loaded automatically if this gem is included in a
25
+ # Rails app. You may opt out by including the following line in your
26
+ # Rails configuration:
27
+ #
28
+ # config.google_serverless.define_exec_task = false
29
+ #
30
+ class Railtie < ::Rails::Railtie
31
+ config.google_serverless = ::ActiveSupport::OrderedOptions.new
32
+ config.google_serverless.define_exec_task = true
33
+
34
+ rake_tasks do |app|
35
+ require "google/serverless/exec/tasks" if app.config.google_serverless.define_exec_task
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -24,25 +24,28 @@ module Google
24
24
  module Serverless
25
25
  class Exec
26
26
  ##
27
- # # Serverless Rake Tasks.
27
+ # # Rake Task for serverless exec
28
28
  #
29
- # To make these tasks available, add the line `require "google/serverless/exec/tasks"`
30
- # to your Rakefile. If your app uses Ruby on Rails, then the serverless gem
31
- # provides a railtie that adds its tasks automatically, so you don't have
32
- # to do anything beyond adding the gem to your Gemfile.
29
+ # This module implements the `serverless:exec` rake task. To make it
30
+ # available, add the line
33
31
  #
34
- # The following tasks are defined:
32
+ # require "google/serverless/exec/tasks"
35
33
  #
36
- # ## Rake serverless:exec
34
+ # to your Rakefile. If your app uses Ruby on Rails, then the gem provides
35
+ # a railtie that adds this task automatically, so you don't have to do
36
+ # anything beyond adding the gem to your Gemfile.
37
37
  #
38
- # Executes a given command in the context of a serverless application.
39
- # See {Google::Serverless::Exec} for more information on this capability.
38
+ # ## Usage
39
+ #
40
+ # The `serverless:exec` a given command in the context of a serverless
41
+ # application. See {Google::Serverless::Exec} for more information on
42
+ # this capability.
40
43
  #
41
44
  # The command to be run may either be provided as a rake argument, or as
42
45
  # command line arguments, delimited by two dashes `--`. (The dashes are
43
46
  # needed to separate your command from rake arguments and flags.)
44
- # For example, to run a production database migration, you can run either of
45
- # the following equivalent commands:
47
+ # For example, to run a production database migration, you can run either
48
+ # of the following equivalent commands:
46
49
  #
47
50
  # bundle exec rake "serverless:exec[bundle exec bin/rails db:migrate]"
48
51
  # bundle exec rake serverless:exec -- bundle exec bin/rails db:migrate
@@ -51,95 +54,114 @@ module Google
51
54
  #
52
55
  # bundle exec rake serverless:exec --
53
56
  #
54
- # ### Parameters
57
+ # ## Parameters
55
58
  #
56
59
  # You may customize the behavior of the serverless execution through a few
57
- # enviroment variable parameters. These are set via the normal mechanism at
58
- # the end of a rake command line. For example, to set GAE_CONFIG:
60
+ # enviroment variable parameters. These are set via the normal mechanism
61
+ # at the end of a rake command line. For example, to set EXEC_APP_CONFIG:
59
62
  #
60
- # bundle exec rake serverless:exec GAE_CONFIG=myservice.yaml -- bundle exec bin/rails db:migrate
63
+ # bundle exec rake serverless:exec EXEC_APP_CONFIG=myservice.yaml -- bundle exec bin/rails db:migrate
61
64
  #
62
65
  # Be sure to set these parameters before the double dash. Any arguments
63
66
  # following the double dash are interpreted as part of the command itself.
64
67
  #
65
68
  # The following environment variable parameters are supported:
66
69
  #
67
- # #### GAE_TIMEOUT
70
+ # ### EXEC_PROJECT
71
+ #
72
+ # The ID of your Google Cloud project. If not specified, uses the current
73
+ # project from gcloud.
74
+ #
75
+ # ### EXEC_PRODUCT
76
+ #
77
+ # The product used to deploy the app. Valid values are `app_engine` or
78
+ # `cloud_run`. If omitted, the task will try to guess based on whether
79
+ # an App Engine config file (e.g. `app.yaml`) is present.
80
+ #
81
+ # ### EXEC_REGION
82
+ #
83
+ # The Google Cloud region to which the app is deployed. Required for
84
+ # Cloud Run apps.
85
+ #
86
+ # ### EXEC_STRATEGY
87
+ #
88
+ # The execution strategy to use. Valid values are `deployment` (which is
89
+ # the default for App Engine Standard apps) and `cloud_build` (which is
90
+ # the default for App Engine Flexible and Cloud Run apps).
91
+ #
92
+ # Normally you should leave the strategy set to the default. The main
93
+ # reason to change it is if your app runs on the Flexible Environment and
94
+ # talks to a database over a VPC (using a private IP address). The
95
+ # `cloud_build` strategy used by default for Flexible apps cannot connect
96
+ # to a VPC, so you should use `deployment` in this case. (But note that,
97
+ # otherwise, the `deployment` strategy is significantly slower for apps
98
+ # on the App Engine Flexible Environment.)
99
+ #
100
+ # ### EXEC_TIMEOUT
68
101
  #
69
102
  # Amount of time to wait before serverless:exec terminates the command.
70
- # Expressed as a string formatted like: "2h15m10s". Default is "10m".
103
+ # Expressed as a string formatted like: `2h15m10s`. Default is `10m`.
71
104
  #
72
- # #### GAE_PROJECT
105
+ # ### EXEC_SERVICE_NAME
73
106
  #
74
- # The ID of your Google Cloud project. If not specified, uses the current
75
- # project from gcloud.
107
+ # Name of the service to be used. If your app uses Cloud Run, this is
108
+ # required. If your app uses App Engine, normally the service name is
109
+ # obtained from the config file, but you can override it using this
110
+ # parameter.
76
111
  #
77
- # #### GAE_CONFIG
112
+ # ### EXEC_APP_CONFIG
78
113
  #
79
114
  # Path to the App Engine config file, used when your app has multiple
80
115
  # services, or the config file is otherwise not called `./app.yaml`. The
81
116
  # config file is used to determine the name of the App Engine service.
117
+ # Unused for Cloud Run apps.
82
118
  #
83
- # #### GAE_SERVICE
84
- #
85
- # Name of the service to be used. Overrides any service name specified in
86
- # your config file.
119
+ # ### EXEC_APP_VERSION
87
120
  #
88
- # #### GAE_EXEC_STRATEGY
121
+ # The version of the App Engine service, used to identify which
122
+ # application image to use to run your command. If not specified, uses
123
+ # the most recently created version, regardless of whether that version
124
+ # is actually serving traffic. Applies only to the `cloud_build` strategy
125
+ # for App Engine apps; ignored for the `deployment` strategy or if your
126
+ # app uses Cloud Run.
89
127
  #
90
- # The execution strategy to use. Valid values are "deployment" (which is the
91
- # default for App Engine Standard apps) and "cloud_build" (which is the
92
- # default for App Engine Flexible and Cloud Run apps).
128
+ # ### EXEC_BUILD_LOGS_DIR
93
129
  #
94
- # Normally you should leave the strategy set to the default. The main reason
95
- # to change it is if your app runs on the Flexible Environment and talks to
96
- # a database over a VPC (using a private IP address). The "cloud_build"
97
- # strategy used by default for Flexible apps cannot connect to a VPC, so you
98
- # should use "deployment" in this case. (But note that, otherwise, the
99
- # "deployment" strategy is significantly slower for apps on the Flexible
100
- # environment.)
130
+ # GCS bucket name of the cloud build log when GAE_STRATEGY is
131
+ # `cloud_build`. (ex. `gs://BUCKET-NAME/FOLDER-NAME`)
101
132
  #
102
- # #### GAE_VERSION
103
- #
104
- # The version of the service, used to identify which application image to
105
- # use to run your command. If not specified, uses the most recently created
106
- # version, regardless of whether that version is actually serving traffic.
107
- # Applies only to the "cloud_build" strategy. (The "deployment" strategy
108
- # deploys its own temporary version of your app.)
109
- #
110
- # #### GAE_EXEC_WRAPPER_IMAGE
133
+ # ### EXEC_WRAPPER_IMAGE
111
134
  #
112
135
  # The fully-qualified name of the wrapper image to use. (This is a Docker
113
- # image that emulates the App Engine environment in Google Cloud Build for
114
- # the "cloud_build" strategy, and applies only to that strategy.) Normally,
115
- # you should not override this unless you are testing a new wrapper.
116
- #
117
- # #### CLOUD_BUILD_GCS_LOG_DIR
136
+ # image that emulates the App Engine environment in Google Cloud Build
137
+ # for the `cloud_build` strategy, and applies only to that strategy.)
138
+ # Normally, you should not override this unless you are testing a new
139
+ # wrapper.
118
140
  #
119
- # GCS bucket name of the cloud build log when GAE_STRATEGY is "cloud_build".
120
- # (ex. "gs://BUCKET-NAME/FOLDER-NAME")
121
141
  module Tasks
122
142
  ## @private
123
- PROJECT_ENV = "GAE_PROJECT"
143
+ PROJECT_ENV = "EXEC_PROJECT"
124
144
  ## @private
125
- STRATEGY_ENV = "GAE_EXEC_STRATEGY"
145
+ STRATEGY_ENV = "EXEC_STRATEGY"
126
146
  ## @private
127
- CONFIG_ENV = "GAE_CONFIG"
147
+ CONFIG_ENV = "EXEC_APP_CONFIG"
128
148
  ## @private
129
- SERVICE_ENV = "GAE_SERVICE"
149
+ SERVICE_ENV = "EXEC_SERVICE_NAME"
130
150
  ## @private
131
- VERSION_ENV = "GAE_VERSION"
151
+ VERSION_ENV = "EXEC_APP_VERSION"
132
152
  ## @private
133
- TIMEOUT_ENV = "GAE_TIMEOUT"
153
+ TIMEOUT_ENV = "EXEC_TIMEOUT"
134
154
  ## @private
135
- WRAPPER_IMAGE_ENV = "GAE_EXEC_WRAPPER_IMAGE"
155
+ WRAPPER_IMAGE_ENV = "EXEC_WRAPPER_IMAGE"
136
156
  ## @private
137
- GCS_LOG_DIR = "CLOUD_BUILD_GCS_LOG_DIR"
157
+ LOGS_DIR_ENV = "EXEC_BUILD_LOGS_DIR"
138
158
  ## @private
139
- PRODUCT_ENV = "PRODUCT"
140
-
159
+ PRODUCT_ENV = "EXEC_PRODUCT"
160
+ ## @private
161
+ REGION_ENV = "EXEC_REGION"
162
+
141
163
  @defined = false
142
-
164
+
143
165
  class << self
144
166
  ##
145
167
  # @private
@@ -151,18 +173,18 @@ module Google
151
173
  return
152
174
  end
153
175
  @defined = true
154
-
176
+
155
177
  setup_exec_task
156
178
  end
157
-
179
+
158
180
  private
159
-
181
+
160
182
  def setup_exec_task
161
183
  ::Rake.application.last_description =
162
184
  "Execute the given command in a Google serverless application."
163
185
  ::Rake::Task.define_task "serverless:exec", [:cmd] do |_t, args|
164
- verify_gcloud_and_report_errors
165
186
  command = extract_command args[:cmd], ::ARGV
187
+ verify_gcloud_and_report_errors
166
188
  selected_product = extract_product ::ENV[PRODUCT_ENV]
167
189
  app_exec = Exec.new command,
168
190
  project: ::ENV[PROJECT_ENV],
@@ -172,13 +194,14 @@ module Google
172
194
  timeout: ::ENV[TIMEOUT_ENV],
173
195
  wrapper_image: ::ENV[WRAPPER_IMAGE_ENV],
174
196
  strategy: ::ENV[STRATEGY_ENV],
175
- gcs_log_dir: ::ENV[GCS_LOG_DIR],
197
+ gcs_log_dir: ::ENV[LOGS_DIR_ENV],
198
+ region: ::ENV[REGION_ENV],
176
199
  product: selected_product
177
200
  start_and_report_errors app_exec
178
201
  exit
179
202
  end
180
203
  end
181
-
204
+
182
205
  def extract_command cmd, argv
183
206
  if cmd
184
207
  ::Shellwords.split cmd
@@ -203,30 +226,27 @@ module Google
203
226
  end
204
227
 
205
228
  def extract_product product
206
- if product
207
- product = product.dup
208
- product.downcase!
209
-
210
- case product
211
- when "app_engine"
212
- APP_ENGINE
213
- when "cloud_run"
214
- CLOUD_RUN
215
- end
216
- else
217
- nil
229
+ return unless product
230
+
231
+ product = product.dup
232
+ product.downcase!
233
+ case product
234
+ when "app_engine"
235
+ APP_ENGINE
236
+ when "cloud_run"
237
+ CLOUD_RUN
218
238
  end
219
239
  end
220
-
240
+
221
241
  def show_usage
222
242
  puts <<~USAGE
223
243
  rake serverless:exec
224
244
  This Rake task executes a given command in the context of a serverless
225
245
  application. For more information,
226
246
  on this capability, see the Google::Serverless::Exec documentation at
227
- http://www.rubydoc.info/gems/appengine/AppEngine/Exec
247
+ http://www.rubydoc.info/gems/google-serverless-exec/Google/Serverless/Exec
228
248
  The command to be run may either be provided as a rake argument, or as
229
- command line arguments delimited by two dashes `--`. (The dashes are
249
+ command line arguments delimited by two dashes "--". (The dashes are
230
250
  needed to separate your command from rake arguments and flags.)
231
251
  For example, to run a production database migration, you can run either
232
252
  of the following equivalent commands:
@@ -237,25 +257,23 @@ module Google
237
257
  You may customize the behavior of the serverless execution through a few
238
258
  enviroment variable parameters. These are set via the normal mechanism at
239
259
  the end of a rake command line but before the double dash. For example, to
240
- set GAE_CONFIG:
241
- bundle exec rake serverless:exec GAE_CONFIG=myservice.yaml -- bundle exec bin/rails db:migrate
260
+ set EXEC_APP_CONFIG:
261
+ bundle exec rake serverless:exec EXEC_APP_CONFIG=myservice.yaml -- \\
262
+ bundle exec bin/rails db:migrate
242
263
  Be sure to set these parameters before the double dash. Any arguments
243
264
  following the double dash are interpreted as part of the command itself.
244
265
  The following environment variable parameters are supported:
245
- GAE_TIMEOUT
246
- Amount of time to wait before serverless:exec terminates the command.
247
- Expressed as a string formatted like: "2h15m10s". Default is "10m".
248
- GAE_PROJECT
266
+ EXEC_PROJECT
249
267
  The ID of your Google Cloud project. If not specified, uses the current
250
268
  project from gcloud.
251
- GAE_CONFIG
252
- Path to the App Engine config file, used when your app has multiple
253
- services, or the config file is otherwise not called `./app.yaml`. The
254
- config file is used to determine the name of the App Engine service.
255
- GAE_SERVICE
256
- Name of the service to be used. Overrides any service name specified in
257
- your config file.
258
- GAE_EXEC_STRATEGY
269
+ EXEC_PRODUCT
270
+ The product used to deploy the app. Valid values are "app_engine" or
271
+ "cloud_run". If omitted, the task will try to guess based on whether
272
+ an App Engine config file (e.g. app.yaml) is present.
273
+ EXEC_REGION
274
+ The Google Cloud region to which the app is deployed. Required for
275
+ Cloud Run apps.
276
+ EXEC_STRATEGY
259
277
  The execution strategy to use. Valid values are "deployment" (which is the
260
278
  default for App Engine Standard apps) and "cloud_build" (which is the
261
279
  default for App Engine Flexible and Cloud Run apps).
@@ -266,34 +284,37 @@ module Google
266
284
  should use "deployment" in this case. (But note that, otherwise, the
267
285
  "deployment" strategy is significantly slower for apps on the Flexible
268
286
  environment.)
269
- GAE_VERSION
270
- The version of the service, used to identify which application image to
271
- use to run your command. If not specified, uses the most recently created
272
- version, regardless of whether that version is actually serving traffic.
273
- Applies only to the "cloud_build" strategy. (The "deployment" strategy
274
- deploys its own temporary version of your app.)
275
- GAE_EXEC_WRAPPER_IMAGE
287
+ EXEC_TIMEOUT
288
+ Amount of time to wait before serverless:exec terminates the command.
289
+ Expressed as a string formatted like: "2h15m10s". Default is "10m".
290
+ EXEC_SERVICE_NAME
291
+ Name of the service to be used. If your app uses Cloud Run, this is
292
+ required. If your app uses App Engine, normally the service name is
293
+ obtained from the config file, but you can override it using this
294
+ parameter.
295
+ EXEC_APP_CONFIG
296
+ Path to the App Engine config file, used when your app has multiple
297
+ services, or the config file is otherwise not called "./app.yaml". The
298
+ config file is used to determine the name of the App Engine service.
299
+ Unused for Cloud Run apps.
300
+ EXEC_APP_VERSION
301
+ The version of the App Engine service, used to identify which
302
+ application image to use to run your command. If not specified, uses
303
+ the most recently created version, regardless of whether that version
304
+ is actually serving traffic. Applies only to the "cloud_build" strategy
305
+ for App Engine apps; ignored for the "deployment" strategy or if your
306
+ app uses Cloud Run.
307
+ EXEC_BUILD_LOGS_DIR
308
+ GCS bucket name of the cloud build log when GAE_STRATEGY is "cloud_build".
309
+ (ex. "gs://BUCKET-NAME/FOLDER-NAME")
310
+ EXEC_WRAPPER_IMAGE
276
311
  The fully-qualified name of the wrapper image to use. (This is a Docker
277
312
  image that emulates the App Engine environment in Google Cloud Build for
278
313
  the "cloud_build" strategy, and applies only to that strategy.) Normally,
279
314
  you should not override this unless you are testing a new wrapper.
280
- CLOUD_BUILD_GCS_LOG_DIR
281
- GCS bucket name of the cloud build log when GAE_STRATEGY is "cloud_build".
282
- (ex. "gs://BUCKET-NAME/FOLDER-NAME")
283
- PRODUCT
284
- The serverless product to use. Valid values are "app_engine" and "cloud_run".
285
- If not specified, autodetects the serverless product to use.
286
- This rake task is provided by the "serverless" gem. To make these tasks
287
- available, add the following line to your Rakefile:
288
- require "google/serverless/exec/tasks"
289
- If your app uses Ruby on Rails, the gem provides a railtie that adds its
290
- tasks automatically, so you don't have to do anything beyond adding the
291
- gem to your Gemfile.
292
- For more information or to report issues, visit the Github page:
293
- https://github.com/GoogleCloudPlatform/google-serverless-exec
294
315
  USAGE
295
316
  end
296
-
317
+
297
318
  def verify_gcloud_and_report_errors
298
319
  Exec::Gcloud.verify!
299
320
  rescue Exec::Gcloud::BinaryNotFound
@@ -318,42 +339,42 @@ module Google
318
339
  running `gcloud config set project <project-name>`.
319
340
  MESSAGE
320
341
  end
321
-
342
+
322
343
  def start_and_report_errors app_exec
323
344
  app_exec.start
324
345
  rescue Exec::ConfigFileNotFound => e
325
346
  report_error <<~MESSAGE
326
347
  Could not determine which service should run this command because the App
327
348
  Engine config file "#{e.config_path}" was not found.
328
- Specify the config file using the GAE_CONFIG argument. e.g.
329
- bundle exec rake serverless:exec GAE_CONFIG=myapp.yaml -- myscript.sh
330
- Alternately, you may specify a service name directly with GAE_SERVICE. e.g.
331
- bundle exec rake serverless:exec GAE_SERVICE=myservice -- myscript.sh
349
+ Specify the config file using the EXEC_APP_CONFIG argument. e.g.
350
+ bundle exec rake serverless:exec EXEC_APP_CONFIG=myapp.yaml -- myscript.sh
351
+ Alternately, specify a service name directly with EXEC_SERVICE_NAME. e.g.
352
+ bundle exec rake serverless:exec EXEC_SERVICE_NAME=myservice -- myscript.sh
332
353
  MESSAGE
333
354
  rescue Exec::BadConfigFileFormat => e
334
355
  report_error <<~MESSAGE
335
356
  Could not determine which service should run this command because the App
336
357
  Engine config file "#{e.config_path}" was malformed.
337
358
  It must be a valid YAML file.
338
- Specify the config file using the GAE_CONFIG argument. e.g.
339
- bundle exec rake serverless:exec GAE_CONFIG=myapp.yaml -- myscript.sh
340
- Alternately, you may specify a service name directly with GAE_SERVICE. e.g.
341
- bundle exec rake serverless:exec GAE_SERVICE=myservice -- myscript.sh
359
+ Specify the config file using the EXEC_APP_CONFIG argument. e.g.
360
+ bundle exec rake serverless:exec EXEC_APP_CONFIG=myapp.yaml -- myscript.sh
361
+ Alternately, specify a service name directly with EXEC_SERVICE_NAME. e.g.
362
+ bundle exec rake serverless:exec EXEC_SERVICE_NAME=myservice -- myscript.sh
342
363
  MESSAGE
343
364
  rescue Exec::NoSuchVersion => e
344
365
  if e.version
345
366
  report_error <<~MESSAGE
346
367
  Could not find version "#{e.version}" of service "#{e.service}".
347
368
  Please double-check the version exists. To use the most recent version by
348
- default, omit the GAE_VERSION argument.
369
+ default, omit the EXEC_APP_VERSION argument.
349
370
  MESSAGE
350
371
  else
351
372
  report_error <<~MESSAGE
352
373
  Could not find any versions of service "#{e.service}".
353
374
  Please double-check that you have deployed this service. If you want to run
354
- a command against a different service, you may provide a GAE_CONFIG argument
355
- pointing to your App Engine config file, or a GAE_SERVICE argument to specify
356
- a service directly.
375
+ a command against a different service, you may provide a EXEC_APP_CONFIG
376
+ argument pointing to your App Engine config file, or a EXEC_SERVICE_NAME
377
+ argument to specify a service directly.
357
378
  MESSAGE
358
379
  end
359
380
  rescue Exec::NoDefaultProject
@@ -361,15 +382,15 @@ module Google
361
382
  Could not get the default project from gcloud.
362
383
  Please either set the current project using
363
384
  gcloud config set project my-project-id
364
- or specify the project by setting the GAE_PROJECT argument. e.g.
365
- bundle exec rake serverless:exec GAE_PROJECT=my-project-id -- myscript.sh
385
+ or specify the project by setting the EXEC_PROJECT argument. e.g.
386
+ bundle exec rake serverless:exec EXEC_PROJECT=my-project-id -- myscript.sh
366
387
  MESSAGE
367
388
  rescue Exec::UsageError => e
368
389
  report_error e.message
369
390
  end
370
-
391
+
371
392
  def report_error str
372
- ::STDERR.puts str
393
+ warn str
373
394
  exit 1
374
395
  end
375
396
  end
@@ -18,7 +18,7 @@ module Google
18
18
  module Serverless
19
19
  class Exec
20
20
  # The current version of this gem, as a string.
21
- VERSION = "0.1.0"
21
+ VERSION = "0.2.0"
22
22
  end
23
23
  end
24
24
  end
@@ -202,7 +202,7 @@ module Google
202
202
  # used. (Note that this most recently deployed version may not be the same
203
203
  # version that is currently receiving traffic: for example, if you deployed
204
204
  # with `--no-promote`.) To use a different version, set the `version`
205
- # parameter in the {Google::Serverless::Exec} constructor
205
+ # parameter in the {Google::Serverless::Exec} constructor
206
206
  # (or the corresponding `GAE_VERSION` parameter in the Rake task).
207
207
  #
208
208
  # ### Providing credentials
@@ -253,13 +253,13 @@ module Google
253
253
 
254
254
  APP_ENGINE = :app_engine
255
255
  CLOUD_RUN = :cloud_run
256
-
256
+
257
257
  ##
258
258
  # Base class for exec-related usage errors.
259
259
  #
260
260
  class UsageError < ::StandardError
261
261
  end
262
-
262
+
263
263
  ##
264
264
  # Unsupported strategy
265
265
  #
@@ -273,7 +273,7 @@ module Google
273
273
  attr_reader :strategy
274
274
  attr_reader :app_env
275
275
  end
276
-
276
+
277
277
  ##
278
278
  # Exception raised when a parameter is malformed.
279
279
  #
@@ -286,7 +286,7 @@ module Google
286
286
  attr_reader :param_name
287
287
  attr_reader :value
288
288
  end
289
-
289
+
290
290
  ##
291
291
  # Exception raised when gcloud has no default project.
292
292
  #
@@ -295,7 +295,7 @@ module Google
295
295
  super "No default project set."
296
296
  end
297
297
  end
298
-
298
+
299
299
  ##
300
300
  # Exception raised when the App Engine config file could not be found.
301
301
  #
@@ -306,7 +306,7 @@ module Google
306
306
  end
307
307
  attr_reader :config_path
308
308
  end
309
-
309
+
310
310
  ##
311
311
  # Exception raised when the App Engine config file could not be parsed.
312
312
  #
@@ -317,7 +317,7 @@ module Google
317
317
  end
318
318
  attr_reader :config_path
319
319
  end
320
-
320
+
321
321
  ##
322
322
  # Exception raised when the given version could not be found, or no
323
323
  # versions at all could be found for the given service.
@@ -335,20 +335,20 @@ module Google
335
335
  attr_reader :service
336
336
  attr_reader :version
337
337
  end
338
-
338
+
339
339
  class << self
340
340
  ## @return [String] Default command timeout.
341
341
  attr_accessor :default_timeout
342
-
342
+
343
343
  ## @return [String] Default service name if the config doesn't specify.
344
344
  attr_accessor :default_service
345
-
345
+
346
346
  ## @return [String] Path to default config file.
347
347
  attr_accessor :default_config_path
348
-
348
+
349
349
  ## @return [String] Docker image that implements the app engine wrapper.
350
350
  attr_accessor :default_wrapper_image
351
-
351
+
352
352
  ##
353
353
  # Create an execution for a rake task.
354
354
  #
@@ -397,7 +397,7 @@ module Google
397
397
  strategy: strategy, gcs_log_dir: gcs_log_dir, product: product
398
398
  end
399
399
  end
400
-
400
+
401
401
  ##
402
402
  # Create an execution for the given command.
403
403
  #
@@ -427,10 +427,20 @@ module Google
427
427
  # @param product [Symbol] The serverless product. If omitted, defaults to the
428
428
  # value returns by {Google::Serverless::Exec#default_product}.
429
429
  # Allowed values are {APP_ENGINE} and {CLOUD_RUN}.
430
+ # @param region [String] The region for the cloud run service. Required
431
+ # if the product is cloud run.
430
432
  #
431
433
  def initialize command,
432
- project: nil, service: nil, config_path: nil, version: nil,
433
- timeout: nil, wrapper_image: nil, strategy: nil, gcs_log_dir: nil, product: nil
434
+ project: nil,
435
+ service: nil,
436
+ config_path: nil,
437
+ version: nil,
438
+ timeout: nil,
439
+ wrapper_image: nil,
440
+ strategy: nil,
441
+ gcs_log_dir: nil,
442
+ product: nil,
443
+ region: nil
434
444
  @command = command
435
445
  @service = service
436
446
  @config_path = config_path
@@ -441,40 +451,41 @@ module Google
441
451
  @strategy = strategy
442
452
  @gcs_log_dir = gcs_log_dir
443
453
  @product = product
444
-
454
+ @region = region
455
+
445
456
  yield self if block_given?
446
457
  end
447
-
458
+
448
459
  ##
449
460
  # @return [String] The project ID.
450
461
  # @return [nil] if the default gcloud project should be used.
451
462
  #
452
463
  attr_accessor :project
453
-
464
+
454
465
  ##
455
466
  # @return [String] The service name.
456
467
  # @return [nil] if the service should be obtained from the app config.
457
468
  #
458
469
  attr_accessor :service
459
-
470
+
460
471
  ##
461
472
  # @return [String] Path to the config file.
462
473
  # @return [nil] if the default of `./app.yaml` should be used.
463
474
  #
464
475
  attr_accessor :config_path
465
-
476
+
466
477
  ##
467
478
  # @return [String] Service version of the image to use.
468
479
  # @return [nil] if the most recent should be used.
469
480
  #
470
481
  attr_accessor :version
471
-
482
+
472
483
  ##
473
484
  # @return [String] The command timeout, in `1h23m45s` format.
474
485
  # @return [nil] if the default of `10m` should be used.
475
486
  #
476
487
  attr_accessor :timeout
477
-
488
+
478
489
  ##
479
490
  # The command to run.
480
491
  #
@@ -483,13 +494,13 @@ module Google
483
494
  # directly without a shell.
484
495
  #
485
496
  attr_accessor :command
486
-
497
+
487
498
  ##
488
499
  # @return [String] Custom wrapper image to use.
489
500
  # @return [nil] if the default should be used.
490
501
  #
491
502
  attr_accessor :wrapper_image
492
-
503
+
493
504
  ##
494
505
  # @return [String] The execution strategy to use. Allowed values are
495
506
  # `"deployment"` and `"cloud_build"`.
@@ -503,11 +514,16 @@ module Google
503
514
  # Allowed values are {APP_ENGINE} and {CLOUD_RUN}
504
515
  #
505
516
  attr_accessor :product
506
-
517
+
518
+ ##
519
+ # @return [String] The region for the cloud run service
520
+ #
521
+ attr_accessor :region
522
+
507
523
  ##
508
524
  # Executes the command synchronously. Streams the logs back to standard out
509
525
  # and does not return until the command has completed or timed out.
510
-
526
+
511
527
  def start
512
528
  resolve_parameters
513
529
  case @product
@@ -532,9 +548,9 @@ module Google
532
548
  app_info = version_info_cloud_run @service
533
549
  start_build_strategy app_info
534
550
  end
535
-
551
+
536
552
  private
537
-
553
+
538
554
  ##
539
555
  # @private
540
556
  # Resolves and canonicalizes all the parameters.
@@ -553,7 +569,7 @@ module Google
553
569
  end
554
570
  self
555
571
  end
556
-
572
+
557
573
  def resolve_strategy app_env
558
574
  @strategy = @strategy.to_s.downcase
559
575
  if @strategy.empty?
@@ -565,7 +581,7 @@ module Google
565
581
  end
566
582
  @strategy
567
583
  end
568
-
584
+
569
585
  def service_from_config
570
586
  return nil if !@config_path && @service
571
587
  @config_path ||= Exec.default_config_path
@@ -575,7 +591,7 @@ module Google
575
591
  rescue ::StandardError
576
592
  raise BadConfigFileFormat, @config_path
577
593
  end
578
-
594
+
579
595
  def default_project
580
596
  result = Exec::Gcloud.execute \
581
597
  ["config", "get-value", "project"],
@@ -588,7 +604,7 @@ module Google
588
604
  def default_product
589
605
  File.file?("app.yaml") ? APP_ENGINE : CLOUD_RUN
590
606
  end
591
-
607
+
592
608
  def parse_timeout timeout_str
593
609
  matched = timeout_str =~ /^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s?)?$/
594
610
  raise BadParameter.new "timeout", timeout_str unless matched
@@ -597,7 +613,7 @@ module Google
597
613
  seconds = ::Regexp.last_match(3).to_i
598
614
  hours * 3600 + minutes * 60 + seconds
599
615
  end
600
-
616
+
601
617
  ##
602
618
  # @private
603
619
  # Returns the name of the most recently created version of the given
@@ -621,7 +637,7 @@ module Google
621
637
  raise NoSuchVersion, service unless result
622
638
  result
623
639
  end
624
-
640
+
625
641
  ##
626
642
  # @private
627
643
  # Returns full information on the given version of the given service.
@@ -652,16 +668,19 @@ module Google
652
668
 
653
669
  def version_info_cloud_run service
654
670
  service ||= "default"
671
+ raise BadParameter.new("region", "(value missing)") unless region
655
672
  result = Exec::Gcloud.execute \
656
673
  [
657
674
  "run", "services", "describe", service,
675
+ "--project", @project,
676
+ "--region", region,
658
677
  "--format", "json"
659
678
  ],
660
- capture: true, assert: false
679
+ capture: true, assert: false, echo: true
661
680
  result.strip!
662
681
  ::JSON.parse result
663
682
  end
664
-
683
+
665
684
  ##
666
685
  # @private
667
686
  # Performs exec on a GAE standard app.
@@ -686,7 +705,7 @@ module Google
686
705
  delete_temp_version temp_version
687
706
  end
688
707
  end
689
-
708
+
690
709
  def describe_deployment_strategy
691
710
  puts "\nUsing the `deployment` strategy for serverless:exec"
692
711
  puts "(i.e. deploying a temporary version of your app)"
@@ -694,15 +713,14 @@ module Google
694
713
  puts "SERVICE: #{@service}"
695
714
  puts "TIMEOUT: #{@timeout}"
696
715
  end
697
-
716
+
698
717
  def create_secret
699
718
  ::SecureRandom.alphanumeric 20
700
719
  end
701
-
720
+
702
721
  def copy_entrypoint secret
703
- entrypoint_template =
704
- ::File.join(::File.dirname(::File.dirname(__dir__)),
705
- "data", "exec_standard_entrypoint.rb.erb")
722
+ base_dir = ::File.dirname ::File.dirname ::File.dirname __dir__
723
+ entrypoint_template = ::File.join base_dir, "data", "exec_standard_entrypoint.rb.erb"
706
724
  entrypoint_file = "appengine_exec_entrypoint_#{@timestamp_suffix}.rb"
707
725
  erb = ::ERB.new ::File.read entrypoint_template
708
726
  data = {
@@ -714,7 +732,7 @@ module Google
714
732
  end
715
733
  entrypoint_file
716
734
  end
717
-
735
+
718
736
  def copy_app_yaml app_info, entrypoint_file
719
737
  yaml_data = {
720
738
  "runtime" => app_info["runtime"],
@@ -734,7 +752,7 @@ module Google
734
752
  end
735
753
  app_yaml_file
736
754
  end
737
-
755
+
738
756
  def complete_flex_app_yaml yaml_data, app_info
739
757
  yaml_data["env"] = "flex"
740
758
  orig_path = (app_info["betaSettings"] || {})["module_yaml_path"]
@@ -746,11 +764,11 @@ module Google
746
764
  yaml_data[key] = orig_yaml[key] if orig_yaml[key]
747
765
  end
748
766
  end
749
-
767
+
750
768
  def complete_standard_app_yaml yaml_data, app_info
751
769
  yaml_data["instance_class"] = app_info["instanceClass"].sub(/^F/, "B")
752
770
  end
753
-
771
+
754
772
  def deploy_temp_app app_yaml_file
755
773
  temp_version = "appengine-exec-#{@timestamp_suffix}"
756
774
  Exec::Gcloud.execute [
@@ -761,7 +779,7 @@ module Google
761
779
  ]
762
780
  temp_version
763
781
  end
764
-
782
+
765
783
  def track_status temp_version, secret
766
784
  host = "#{temp_version}.#{@service}.#{@project}.appspot.com"
767
785
  ::Net::HTTP.start host do |http|
@@ -791,7 +809,7 @@ module Google
791
809
  end
792
810
  end
793
811
  end
794
-
812
+
795
813
  def delete_temp_version temp_version
796
814
  Exec::Gcloud.execute [
797
815
  "app", "versions", "delete", temp_version,
@@ -800,7 +818,7 @@ module Google
800
818
  "--quiet"
801
819
  ]
802
820
  end
803
-
821
+
804
822
  ##
805
823
  # @private
806
824
  # Performs exec on a GAE flexible and Cloud Run apps.
@@ -820,9 +838,9 @@ module Google
820
838
  cloud_sql_instances = metadata_annotations["run.googleapis.com/cloudsql-instances"] || []
821
839
  image = metadata_annotations["client.knative.dev/user-image"]
822
840
  end
823
-
841
+
824
842
  describe_build_strategy
825
-
843
+
826
844
  config = build_config command, image, env_variables, cloud_sql_instances
827
845
  file = ::Tempfile.new ["cloudbuild_", ".json"]
828
846
  begin
@@ -841,7 +859,7 @@ module Google
841
859
  file.close!
842
860
  end
843
861
  end
844
-
862
+
845
863
  ##
846
864
  # @private
847
865
  # Workaround for https://github.com/GoogleCloudPlatform/appengine-ruby/issues/33
@@ -866,7 +884,7 @@ module Google
866
884
  build_info = ::JSON.parse(result).first
867
885
  build_info["images"].first
868
886
  end
869
-
887
+
870
888
  def describe_build_strategy
871
889
  puts "\nUsing the `cloud_build` strategy for serverless:exec"
872
890
  puts "(i.e. running your app image in Cloud Build)"
@@ -876,7 +894,7 @@ module Google
876
894
  puts "TIMEOUT: #{@timeout}"
877
895
  puts ""
878
896
  end
879
-
897
+
880
898
  ##
881
899
  # @private
882
900
  # Builds a cloudbuild config as a data structure.
@@ -901,7 +919,7 @@ module Google
901
919
  end
902
920
  args << "--"
903
921
  args += command
904
-
922
+
905
923
  {
906
924
  "steps" => [
907
925
  "name" => @wrapper_image,
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Google LLC
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require "google/serverless/exec"
18
+ require "google/serverless/exec/railtie" if defined? ::Rails
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-serverless-exec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Azuma
@@ -9,22 +9,8 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-08-05 00:00:00.000000000 Z
12
+ date: 2021-09-13 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: bundler
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - "~>"
19
- - !ruby/object:Gem::Version
20
- version: '2.0'
21
- type: :development
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - "~>"
26
- - !ruby/object:Gem::Version
27
- version: '2.0'
28
14
  - !ruby/object:Gem::Dependency
29
15
  name: google-style
30
16
  requirement: !ruby/object:Gem::Requirement
@@ -87,14 +73,14 @@ dependencies:
87
73
  requirements:
88
74
  - - "~>"
89
75
  - !ruby/object:Gem::Version
90
- version: '12.0'
76
+ version: '13.0'
91
77
  type: :development
92
78
  prerelease: false
93
79
  version_requirements: !ruby/object:Gem::Requirement
94
80
  requirements:
95
81
  - - "~>"
96
82
  - !ruby/object:Gem::Version
97
- version: '12.0'
83
+ version: '13.0'
98
84
  - !ruby/object:Gem::Dependency
99
85
  name: rdoc
100
86
  requirement: !ruby/object:Gem::Requirement
@@ -123,20 +109,6 @@ dependencies:
123
109
  - - "~>"
124
110
  - !ruby/object:Gem::Version
125
111
  version: '3.4'
126
- - !ruby/object:Gem::Dependency
127
- name: toys
128
- requirement: !ruby/object:Gem::Requirement
129
- requirements:
130
- - - "~>"
131
- - !ruby/object:Gem::Version
132
- version: '0.11'
133
- type: :development
134
- prerelease: false
135
- version_requirements: !ruby/object:Gem::Requirement
136
- requirements:
137
- - - "~>"
138
- - !ruby/object:Gem::Version
139
- version: '0.11'
140
112
  - !ruby/object:Gem::Dependency
141
113
  name: yard
142
114
  requirement: !ruby/object:Gem::Requirement
@@ -151,12 +123,9 @@ dependencies:
151
123
  - - "~>"
152
124
  - !ruby/object:Gem::Version
153
125
  version: '0.9'
154
- description: " The google-serverless-exec gem is a set of classes, plugins, and tools
155
- for integration with Google Serverless compute. It provides access to the runtime
156
- environments, including logging to the Google Cloud Console and interrogation of
157
- hosting properties. It also provides Rake tasks for managing your serverless applications,
158
- for example to run production maintenance commands such as database migrations.
159
- This gem is NOT required to deploy your Ruby application to Google Serverless compute."
126
+ description: The google-serverless-exec gem provides a way to safely run production
127
+ maintenance tasks, such as database migrations, for your serverless applications
128
+ deployed to Google App Engine or Google Cloud Run.
160
129
  email:
161
130
  - dazuma@gmail.com
162
131
  - trambui09098@gmail.com
@@ -169,14 +138,21 @@ files:
169
138
  - CONTRIBUTING.md
170
139
  - LICENSE
171
140
  - README.md
141
+ - data/exec_standard_entrypoint.rb.erb
142
+ - lib/google-serverless-exec.rb
172
143
  - lib/google/serverless/exec.rb
173
144
  - lib/google/serverless/exec/gcloud.rb
145
+ - lib/google/serverless/exec/railtie.rb
174
146
  - lib/google/serverless/exec/tasks.rb
175
147
  - lib/google/serverless/exec/version.rb
176
148
  homepage: https://github.com/GoogleCloudPlatform/serverless-exec-ruby
177
149
  licenses:
178
150
  - Apache-2.0
179
- metadata: {}
151
+ metadata:
152
+ changelog_uri: https://www.rubydoc.info/gems/google-serverless-exec/0.2.0/file/CHANGELOG.md
153
+ source_code_uri: https://github.com/GoogleCloudPlatform/serverless-exec-ruby
154
+ bug_tracker_uri: https://github.com/GoogleCloudPlatform/serverless-exec-ruby/issues
155
+ documentation_uri: https://www.rubydoc.info/gems/google-serverless-exec/0.2.0
180
156
  post_install_message:
181
157
  rdoc_options: []
182
158
  require_paths:
@@ -185,15 +161,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
185
161
  requirements:
186
162
  - - ">="
187
163
  - !ruby/object:Gem::Version
188
- version: 2.4.0
164
+ version: 2.5.0
189
165
  required_rubygems_version: !ruby/object:Gem::Requirement
190
166
  requirements:
191
167
  - - ">="
192
168
  - !ruby/object:Gem::Version
193
169
  version: '0'
194
170
  requirements: []
195
- rubygems_version: 3.1.6
171
+ rubygems_version: 3.2.17
196
172
  signing_key:
197
173
  specification_version: 4
198
- summary: Google Cloud integration tools
174
+ summary: Execute production tasks for Google Serverless apps
199
175
  test_files: []