google-cloud-storage 1.59.0 → 1.60.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: 6a5e8e41dae5b34405a89c08fcd7f69b05cf5a062c976a2bc2f2cd7bdbfbbc91
4
- data.tar.gz: 5464e7f858f731504b9986103b184ba7de27ecb0b5ef049000c5f3231ef558d3
3
+ metadata.gz: 925378eecd9da2c4ab58069c24c0b4ef3b3b8a210484d5262b4339b2b8c9764b
4
+ data.tar.gz: 0b771cf975054dc8f01e129ed7c244907df82d6e62b8e75a43dbed4ef926a979
5
5
  SHA512:
6
- metadata.gz: de418f7fd18cb8b404d9c74d11ef980c71ed0250e8776bd81ca60d3c7f4f672d475f6a90c2250f85d3a00227203e63005fee7d0a52cbc8ef772db390f8695274
7
- data.tar.gz: cfdd5a84b8bb02e721434c6c137e856386aeab2d7909c238e4fc28af82a3e4ac974708e8dad582e45349572acebd5538e9c992b1041215780c236ea833154709
6
+ metadata.gz: 54cf73c127fb464fc4829b32d3aaa246b55a81ee56f2930362819827ed39d7d273e6100bcea9089ed1d7fac090a032b4e61ed62652a363cb0a1d7efdc933c191
7
+ data.tar.gz: 50a4568bd351558f59a2c8ac119aab5385618f16489f458d6e29d8e802204f262782ec1c957b8efa8fbaf6c4c1862abcd8899d4a055b5b4d68860550107bc1aa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Release History
2
2
 
3
+ ### 1.60.0 (2026-05-11)
4
+
5
+ #### Features
6
+
7
+ * add support for object context ([#32902](https://github.com/googleapis/google-cloud-ruby/issues/32902))
8
+ * setting default checksum ([#33331](https://github.com/googleapis/google-cloud-ruby/issues/33331))
9
+ * Support bucket encryption config ([#33452](https://github.com/googleapis/google-cloud-ruby/issues/33452))
10
+
3
11
  ### 1.59.0 (2026-03-19)
4
12
 
5
13
  #### Features
@@ -716,6 +716,171 @@ module Google
716
716
  default_kms_key_name: new_default_kms_key
717
717
  patch_gapi! :encryption
718
718
  end
719
+ ##
720
+ # The bucket's encryption configuration for customer-managed encryption keys.
721
+ # This configuration defines the
722
+ # default encryption behavior for the bucket and its files, and it can be used to enforce encryption requirements for the bucket.
723
+ # For more information, see [Bucket encryption](https://docs.cloud.google.com/storage/docs/encryption/).
724
+ # @return [Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig, nil] The bucket's encryption configuration, or `nil` if no encryption configuration has been set.
725
+ # @example
726
+ # require "google/cloud/storage"
727
+ # #
728
+ # storage = Google::Cloud::Storage.new
729
+ # bucket = storage.bucket "my-bucket"
730
+ # bucket.customer_managed_encryption_enforcement_config
731
+ # ==> #<Google::Apis::StorageV1::Bucket::Encryption::CustomerManagedEncryptionEnforcementConfig:0x00007f3b1c102e90 @restriction_mode="NotRestricted">
732
+ # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted"
733
+
734
+ def customer_managed_encryption_enforcement_config
735
+ @gapi.encryption&.customer_managed_encryption_enforcement_config
736
+ end
737
+ ##
738
+ # Sets the customer-managed encryption enforcement configuration for the bucket.
739
+ #
740
+ # @param new_customer_managed_encryption_enforcement_config [Hash, nil]
741
+ # The configuration hash for encryption enforcement.
742
+ # * `:restriction_mode` (String) - Can be "NotRestricted" or "FullyRestricted".
743
+ # Pass `nil` to clear the current configuration.
744
+ #
745
+ # @example Enforcing Customer-Managed Encryption
746
+ # require "google/cloud/storage"
747
+ #
748
+ # storage = Google::Cloud::Storage.new
749
+ # bucket = storage.bucket "my-bucket"
750
+ #
751
+ # # Set restriction mode to FullyRestricted
752
+ # restricted_config = { restriction_mode: "FullyRestricted" }
753
+ # bucket.customer_managed_encryption_enforcement_config = restricted_config
754
+ #
755
+ # @example Setting via Request Object (Google API Client)
756
+ # require "google/apis/storage_v1"
757
+ #
758
+ # enforcement_config = { restriction_mode: "FullyRestricted" }
759
+ #
760
+ # request_obj = Google::Apis::StorageV1::Bucket::Encryption.new(
761
+ # customer_managed_encryption_enforcement_config: enforcement_config
762
+ # )
763
+ # bucket.customer_managed_encryption_enforcement_config = request_obj
764
+ #
765
+ # @return [Hash, Google::Apis::StorageV1::Bucket::Encryption] The updated configuration.
766
+ # @raise [Google::Cloud::Error] If the update fails due to permissions or invalid arguments.
767
+ def customer_managed_encryption_enforcement_config= new_customer_managed_encryption_enforcement_config
768
+ @gapi.encryption ||= API::Bucket::Encryption.new
769
+ @gapi.encryption.customer_managed_encryption_enforcement_config =
770
+ new_customer_managed_encryption_enforcement_config || {}
771
+ patch_gapi! :encryption
772
+ end
773
+
774
+ ##
775
+ # The bucket's encryption configuration for customer-supplied encryption keys.
776
+ # For more information, see [Bucket encryption](https://docs.cloud.google.com/storage/docs/encryption/).
777
+ # @return [Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig, nil]
778
+ # The bucket's encryption configuration, or `nil` if no encryption configuration has been set.
779
+ # @example
780
+ # require "google/cloud/storage"
781
+ #
782
+ # storage = Google::Cloud::Storage.new
783
+ # bucket = storage.bucket "my-bucket"
784
+ #
785
+ # bucket.customer_supplied_encryption_enforcement_config
786
+ # ==> #<Google::Apis::StorageV1::Bucket::Encryption::CustomerSuppliedEncryptionEnforcementConfig:0x00007f3b1c102e90 @restriction_mode="NotRestricted">
787
+ # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted".
788
+
789
+ def customer_supplied_encryption_enforcement_config
790
+ @gapi.encryption&.customer_supplied_encryption_enforcement_config
791
+ end
792
+
793
+ ##
794
+ # Sets the bucket's encryption configuration for customer-supplied encryption that will be used to protect files.
795
+ # @param new_customer_supplied_encryption_enforcement_config [Hash, nil]
796
+ # The configuration hash for encryption enforcement.
797
+ # * `:restriction_mode` (String) - Can be "NotRestricted" or "FullyRestricted".
798
+ # Pass `nil` to clear the current configuration.
799
+ # @example
800
+ # require "google/cloud/storage"
801
+ #
802
+ # storage = Google::Cloud::Storage.new
803
+ # bucket = storage.bucket "my-bucket"
804
+ # restricted_config = { restriction_mode: "FullyRestricted" }
805
+ # bucket.customer_supplied_encryption_enforcement_config = restricted_config
806
+ #
807
+ # @example Setting via Request Object (Google API Client)
808
+ # require "google/apis/storage_v1"
809
+ #
810
+ # enforcement_config = { restriction_mode: "FullyRestricted" }
811
+ #
812
+ # request_obj = Google::Apis::StorageV1::Bucket::Encryption.new(
813
+ # customer_supplied_encryption_enforcement_config: enforcement_config
814
+ # )
815
+ # bucket.customer_supplied_encryption_enforcement_config = request_obj
816
+ #
817
+ # @return [Hash, Google::Apis::StorageV1::Bucket::Encryption] The updated configuration.
818
+ # @raise [Google::Cloud::Error] If the update fails due to permissions or invalid arguments.
819
+
820
+ def customer_supplied_encryption_enforcement_config= new_customer_supplied_encryption_enforcement_config
821
+ @gapi.encryption ||= API::Bucket::Encryption.new
822
+ @gapi.encryption.customer_supplied_encryption_enforcement_config =
823
+ new_customer_supplied_encryption_enforcement_config || {}
824
+ patch_gapi! :encryption
825
+ end
826
+
827
+ ##
828
+ # The bucket's encryption configuration for google-managed encryption keys.
829
+ # This configuration defines the
830
+ # default encryption behavior for the bucket and its files, and it can be used to enforce encryption
831
+ # requirements for the bucket.
832
+ # For more information, see [Bucket encryption](https://docs.cloud.google.com/storage/docs/encryption/).
833
+ # @return [Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig, nil]
834
+ # The bucket's encryption configuration, or `nil` if no encryption configuration has been set.
835
+ # @example
836
+ # require "google/cloud/storage"
837
+ #
838
+ # storage = Google::Cloud::Storage.new
839
+ # bucket = storage.bucket "my-bucket"
840
+ # bucket.google_managed_encryption_enforcement_config
841
+ # ==> #<Google::Apis::StorageV1::Bucket::Encryption::GoogleManagedEncryptionEnforcementConfig:0x00007f3b1c102e90 @restriction_mode="NotRestricted">
842
+ # The value for `restriction_mode` can be either "NotRestricted" or "FullyRestricted".
843
+
844
+ def google_managed_encryption_enforcement_config
845
+ @gapi.encryption&.google_managed_encryption_enforcement_config
846
+ end
847
+
848
+ ##
849
+ # Sets the google-managed encryption enforcement configuration for the bucket.
850
+ #
851
+ # @param new_google_managed_encryption_enforcement_config [Hash, nil]
852
+ # The configuration hash for encryption enforcement.
853
+ # * `:restriction_mode` (String) - Can be "NotRestricted" or "FullyRestricted".
854
+ # Pass `nil` to clear the current configuration.
855
+ #
856
+ # @example Enforcing Customer-Managed Encryption
857
+ # require "google/cloud/storage"
858
+ #
859
+ # storage = Google::Cloud::Storage.new
860
+ # bucket = storage.bucket "my-bucket"
861
+ # # Set restriction mode to FullyRestricted
862
+ # restricted_config = { restriction_mode: "FullyRestricted" }
863
+ # bucket.google_managed_encryption_enforcement_config = restricted_config
864
+ #
865
+ # @example Setting via Request Object (Google API Client)
866
+ # require "google/apis/storage_v1"
867
+ #
868
+ # enforcement_config = { restriction_mode: "FullyRestricted" }
869
+ #
870
+ # request_obj = Google::Apis::StorageV1::Bucket::Encryption.new(
871
+ # google_managed_encryption_enforcement_config: enforcement_config
872
+ # )
873
+ # bucket.google_managed_encryption_enforcement_config = request_obj
874
+ #
875
+ # @return [Hash, Google::Apis::StorageV1::Bucket::Encryption] The updated configuration.
876
+ # @raise [Google::Cloud::Error] If the update fails due to permissions or invalid arguments.
877
+
878
+ def google_managed_encryption_enforcement_config= new_google_managed_encryption_enforcement_config
879
+ @gapi.encryption ||= API::Bucket::Encryption.new
880
+ @gapi.encryption.google_managed_encryption_enforcement_config =
881
+ new_google_managed_encryption_enforcement_config || {}
882
+ patch_gapi! :encryption
883
+ end
719
884
 
720
885
  ##
721
886
  # The period of time (in seconds) that files in the bucket must be
@@ -1373,6 +1538,7 @@ module Google
1373
1538
  updater.check_for_changed_labels!
1374
1539
  updater.check_for_mutable_cors!
1375
1540
  updater.check_for_mutable_lifecycle!
1541
+ updater.check_for_encryption_enforcement_config!
1376
1542
  return if updater.updates.empty?
1377
1543
  update_gapi! updater.updates,
1378
1544
  if_metageneration_match: if_metageneration_match,
@@ -1439,7 +1605,23 @@ module Google
1439
1605
  # Only applicable if delimiter is set to '/'.
1440
1606
  # @param [Boolean] soft_deleted If true, only soft-deleted object
1441
1607
  # versions will be listed. The default is false.
1608
+ # @param [String] filter An optional string for filtering listed objects.
1609
+ # Supported fields: contexts
1610
+ # If delimiter is set, the returned prefixes are exempt from this filter
1611
+ # List any object that has a context with the specified key attached
1612
+ # filter = "contexts.\"KEY\":*";
1613
+ #
1614
+ # List any object that has a context with the specified key attached and value attached
1615
+ # filter = "contexts.\"keyA\"=\"valueA\""
1616
+ #
1617
+ # List any object that does not have a context with the specified key attached
1618
+ # filter = "-contexts.\"KEY\":*";
1619
+ #
1620
+ # List any object that has a context with the specified key and value attached
1621
+ # filter = "contexts.\"KEY\"=\"VALUE\"";
1442
1622
  #
1623
+ # List any object that does not have a context with the specified key and value attached
1624
+ # filter = "-contexts.\"KEY\"=\"VALUE\"";
1443
1625
  # @return [Array<Google::Cloud::Storage::File>] (See
1444
1626
  # {Google::Cloud::Storage::File::List})
1445
1627
  #
@@ -1465,9 +1647,18 @@ module Google
1465
1647
  # puts file.name
1466
1648
  # end
1467
1649
  #
1650
+ # @example Filter files by context:
1651
+ # require "google/cloud/storage"
1652
+ # storage = Google::Cloud::Storage.new
1653
+ # bucket = storage.bucket "my-bucket"
1654
+ # files = bucket.files filter: "contexts.\"myKey\"=\"myValue\""
1655
+ # files.each do |file|
1656
+ # puts file.name
1657
+ # end
1658
+ #
1468
1659
  def files prefix: nil, delimiter: nil, token: nil, max: nil,
1469
1660
  versions: nil, match_glob: nil, include_folders_as_prefixes: nil,
1470
- soft_deleted: nil
1661
+ soft_deleted: nil, filter: nil
1471
1662
  ensure_service!
1472
1663
  gapi = service.list_files name, prefix: prefix, delimiter: delimiter,
1473
1664
  token: token, max: max,
@@ -1475,13 +1666,15 @@ module Google
1475
1666
  user_project: user_project,
1476
1667
  match_glob: match_glob,
1477
1668
  include_folders_as_prefixes: include_folders_as_prefixes,
1478
- soft_deleted: soft_deleted
1669
+ soft_deleted: soft_deleted,
1670
+ filter: filter
1479
1671
  File::List.from_gapi gapi, service, name, prefix, delimiter, max,
1480
1672
  versions,
1481
1673
  user_project: user_project,
1482
1674
  match_glob: match_glob,
1483
1675
  include_folders_as_prefixes: include_folders_as_prefixes,
1484
- soft_deleted: soft_deleted
1676
+ soft_deleted: soft_deleted,
1677
+ filter: filter
1485
1678
  end
1486
1679
  alias find_files files
1487
1680
 
@@ -1628,7 +1821,7 @@ module Google
1628
1821
  # changed to a time in the future. If custom_time must be unset, you
1629
1822
  # must either perform a rewrite operation, or upload the data again
1630
1823
  # and create a new file.
1631
- # @param [Symbol, nil] checksum The type of checksum for the client to
1824
+ # @param [Symbol, nil, Boolean] checksum The type of checksum for the client to
1632
1825
  # automatically calculate and send with the create request to verify
1633
1826
  # the integrity of the object. If provided, Cloud Storage will only
1634
1827
  # create the file if the value calculated by the client matches the
@@ -1636,11 +1829,12 @@ module Google
1636
1829
  #
1637
1830
  # Acceptable values are:
1638
1831
  #
1832
+ # * `true` [Boolean] - Calculate and provide a checksum using the CRC32c hash.
1833
+ # * `false` [Boolean] - Do not calculate or provide a checksum.
1639
1834
  # * `md5` - Calculate and provide a checksum using the MD5 hash.
1640
1835
  # * `crc32c` - Calculate and provide a checksum using the CRC32c hash.
1641
1836
  # * `all` - Calculate and provide checksums for all available verifications.
1642
- #
1643
- # Optional. The default is `nil`. Do not provide if also providing a
1837
+ # Optional. The default is `crc32c`. Do not provide if also providing a
1644
1838
  # corresponding `crc32c` or `md5` argument. See
1645
1839
  # [Validation](https://cloud.google.com/storage/docs/hashes-etags)
1646
1840
  # for more information.
@@ -1805,6 +1999,11 @@ module Google
1805
1999
  path ||= file.path if file.respond_to? :path
1806
2000
  path ||= file if file.is_a? String
1807
2001
  raise ArgumentError, "must provide path" if path.nil?
2002
+ # If no checksum type or specific value is provided, the default will be set to crc32c.
2003
+ # If the checksum is set to false, it will be disabled.
2004
+ if [checksum, crc32c, md5].all?(&:nil?) || checksum == true
2005
+ checksum = :crc32c
2006
+ end
1808
2007
  crc32c = crc32c_for file, checksum, crc32c
1809
2008
  md5 = md5_for file, checksum, md5
1810
2009
 
@@ -3386,6 +3585,26 @@ module Google
3386
3585
  patch_gapi! :lifecycle
3387
3586
  end
3388
3587
 
3588
+ def check_for_encryption_enforcement_config!
3589
+ return unless @gapi.encryption
3590
+
3591
+ [
3592
+ :google_managed_encryption_enforcement_config,
3593
+ :customer_managed_encryption_enforcement_config,
3594
+ :customer_supplied_encryption_enforcement_config
3595
+ ].each do |attr|
3596
+ config = @gapi.encryption.send(attr)
3597
+ next unless config
3598
+ unless config.respond_to?(:to_h)
3599
+ raise ArgumentError, "Encryption config for #{attr} must be a Hash or valid Config object"
3600
+ end
3601
+ clean_config = config.to_h
3602
+ clean_config.delete :effective_time
3603
+ clean_config.delete "effective_time"
3604
+ @gapi.encryption.send "#{attr}=", clean_config
3605
+ end
3606
+ end
3607
+
3389
3608
  protected
3390
3609
 
3391
3610
  ##
@@ -167,7 +167,7 @@ module Google
167
167
  delimiter = nil, max = nil, versions = nil,
168
168
  user_project: nil, match_glob: nil,
169
169
  include_folders_as_prefixes: nil,
170
- soft_deleted: nil
170
+ soft_deleted: nil, filter: nil
171
171
  files = new(Array(gapi_list.items).map do |gapi_object|
172
172
  File.from_gapi gapi_object, service, user_project: user_project
173
173
  end)
@@ -183,6 +183,7 @@ module Google
183
183
  files.instance_variable_set :@match_glob, match_glob
184
184
  files.instance_variable_set :@include_folders_as_prefixes, include_folders_as_prefixes
185
185
  files.instance_variable_set :@soft_deleted, soft_deleted
186
+ files.instance_variable_set :@filter, filter
186
187
  files
187
188
  end
188
189
 
@@ -49,29 +49,47 @@ module Google
49
49
  gcloud_file.crc32c == crc32c_for(local_file)
50
50
  end
51
51
 
52
+ # Calculates MD5 digest using either file path or open stream.
52
53
  def self.md5_for local_file
53
- if local_file.respond_to? :to_path
54
- ::File.open Pathname(local_file).to_path, "rb" do |f|
55
- ::Digest::MD5.file(f).base64digest
56
- end
57
- else # StringIO
58
- local_file.rewind
59
- md5 = ::Digest::MD5.base64digest local_file.read
60
- local_file.rewind
61
- md5
62
- end
54
+ _digest_for local_file, ::Digest::MD5
63
55
  end
64
56
 
57
+ # Calculates CRC32c digest using either file path or open stream.
65
58
  def self.crc32c_for local_file
66
- if local_file.respond_to? :to_path
59
+ _digest_for local_file, ::Digest::CRC32c
60
+ end
61
+
62
+ # @private
63
+ # Computes a base64-encoded digest for a local file or IO stream.
64
+ #
65
+ # This method handles two types of inputs for `local_file`:
66
+ # 1. A file path (String or Pathname): It efficiently streams the file
67
+ # to compute the digest without loading the entire file into memory.
68
+ # 2. An IO-like stream (e.g., File, StringIO): It reads the stream's
69
+ # content to compute the digest. The stream is rewound before and after
70
+ # reading to ensure its position is not permanently changed.
71
+ #
72
+ # @param local_file [String, Pathname, IO] The local file path or IO
73
+ # stream for which to compute the digest.
74
+ # @param digest_class [Class] The digest class to use for the
75
+ # calculation (e.g., `Digest::MD5`). It must respond to `.file` and
76
+ # `.base64digest`.
77
+ #
78
+ # @return [String] The base64-encoded digest of the file's content.
79
+ #
80
+ def self._digest_for local_file, digest_class
81
+
82
+ if local_file.respond_to?(:to_path) || local_file.is_a?(String)
83
+ # Case 1: Input is a file path (String, Pathname, or object that responds to :to_path).
67
84
  ::File.open Pathname(local_file).to_path, "rb" do |f|
68
- ::Digest::CRC32c.file(f).base64digest
85
+ digest_class.file(f).base64digest
69
86
  end
70
- else # StringIO
87
+ else
88
+ # Case 2: Input is an open stream (File or StringIO).
71
89
  local_file.rewind
72
- crc32c = ::Digest::CRC32c.base64digest local_file.read
90
+ digest = digest_class.base64digest local_file.read
73
91
  local_file.rewind
74
- crc32c
92
+ digest
75
93
  end
76
94
  end
77
95
  end
@@ -370,6 +370,45 @@ module Google
370
370
  update_gapi! :content_type
371
371
  end
372
372
 
373
+ ##
374
+ # User-defined object contexts. Each object context is a key-
375
+ # payload pair, where the key provides the identification and the payload holds
376
+ # the associated value and additional metadata.
377
+ # Object contexts are used to provide additional information about an object
378
+ # @return [Google::Apis::StorageV1::Object::Contexts, nil] The object contexts, or `nil` if there are none.
379
+
380
+ def contexts
381
+ @gapi.contexts
382
+ end
383
+
384
+ ##
385
+ # Sets the object context.
386
+ # To pass generation and/or metageneration preconditions, call this
387
+ # method within a block passed to {#update}.
388
+ # @param [Google::Apis::StorageV1::Object::Contexts] contexts The object contexts to set.
389
+ # @see https://docs.cloud.google.com/storage/docs/use-object-contexts#attach-modify-contexts Object Contexts documentation
390
+ # @example
391
+ # require "google/cloud/storage"
392
+ # storage = Google::Cloud::Storage.new
393
+ # bucket = storage.bucket "my-bucket"
394
+ # file = bucket.file "path/to/my-file.ext"
395
+ # payload = Google::Apis::StorageV1::ObjectCustomContextPayload.new(
396
+ # value: "your-custom-context-value"
397
+ # )
398
+ # custom_hash = {
399
+ # "your-custom-context-key" => payload
400
+ # }
401
+ # contexts = Google::Apis::StorageV1::Object::Contexts.new(
402
+ # custom: custom_hash
403
+ # )
404
+ # file.update do |file|
405
+ # file.contexts = contexts
406
+ # end
407
+ def contexts= contexts
408
+ @gapi.contexts = contexts
409
+ update_gapi! :contexts
410
+ end
411
+
373
412
  ##
374
413
  # A custom time specified by the user for the file, or `nil`.
375
414
  #
@@ -372,7 +372,7 @@ module Google
372
372
  def list_files bucket_name, delimiter: nil, max: nil, token: nil,
373
373
  prefix: nil, versions: nil, user_project: nil,
374
374
  match_glob: nil, include_folders_as_prefixes: nil,
375
- soft_deleted: nil, options: {}
375
+ soft_deleted: nil, filter: nil, options: {}
376
376
  execute do
377
377
  service.list_objects \
378
378
  bucket_name, delimiter: delimiter, max_results: max,
@@ -382,6 +382,7 @@ module Google
382
382
  match_glob: match_glob,
383
383
  include_folders_as_prefixes: include_folders_as_prefixes,
384
384
  soft_deleted: soft_deleted,
385
+ filter: filter,
385
386
  options: options
386
387
  end
387
388
  end
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Storage
19
- VERSION = "1.59.0".freeze
19
+ VERSION = "1.60.0".freeze
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-storage
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.59.0
4
+ version: 1.60.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore