Hello community, here is the log from the commit of package rubygem-activestorage-6.0 for openSUSE:Factory checked in at 2019-11-13 13:25:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-activestorage-6.0 (Old) and /work/SRC/openSUSE:Factory/.rubygem-activestorage-6.0.new.2990 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-activestorage-6.0" Wed Nov 13 13:25:16 2019 rev:2 rq:747687 version:6.0.1 Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-activestorage-6.0/rubygem-activestorage-6.0.changes 2019-08-19 21:40:50.328296938 +0200 +++ /work/SRC/openSUSE:Factory/.rubygem-activestorage-6.0.new.2990/rubygem-activestorage-6.0.changes 2019-11-13 13:25:19.843510405 +0100 @@ -1,0 +2,15 @@ +Tue Nov 12 13:34:30 UTC 2019 - Manuel Schnitzer <mschnit...@suse.com> + +- updated to version 6.0.1 + + * `ActiveStorage::AnalyzeJob`s are discarded on `ActiveRecord::RecordNotFound` errors. + + *George Claghorn* + + * Blobs are recorded in the database before being uploaded to the service. + This fixes that generated blob keys could silently collide, leading to + data loss. + + *Julik Tarkhanov* + +------------------------------------------------------------------- Old: ---- activestorage-6.0.0.gem New: ---- activestorage-6.0.1.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-activestorage-6.0.spec ++++++ --- /var/tmp/diff_new_pack.D16n6P/_old 2019-11-13 13:25:20.435511022 +0100 +++ /var/tmp/diff_new_pack.D16n6P/_new 2019-11-13 13:25:20.439511025 +0100 @@ -12,7 +12,7 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # @@ -24,7 +24,7 @@ # Name: rubygem-activestorage-6.0 -Version: 6.0.0 +Version: 6.0.1 Release: 0 %define mod_name activestorage %define mod_full_name %{mod_name}-%{version} @@ -36,9 +36,9 @@ %endif # /MANUAL BuildRoot: %{_tmppath}/%{name}-%{version}-build -BuildRequires: ruby-macros >= 5 BuildRequires: %{ruby >= 2.5.0} BuildRequires: %{rubygem gem2rpm} +BuildRequires: ruby-macros >= 5 Url: https://rubyonrails.org Source: https://rubygems.org/gems/%{mod_full_name}.gem Source1: gem2rpm.yml ++++++ activestorage-6.0.0.gem -> activestorage-6.0.1.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/CHANGELOG.md new/CHANGELOG.md --- old/CHANGELOG.md 2019-08-16 19:59:07.000000000 +0200 +++ new/CHANGELOG.md 2019-11-05 15:37:50.000000000 +0100 @@ -1,3 +1,16 @@ +## Rails 6.0.1 (November 5, 2019) ## + +* `ActiveStorage::AnalyzeJob`s are discarded on `ActiveRecord::RecordNotFound` errors. + + *George Claghorn* + +* Blobs are recorded in the database before being uploaded to the service. + This fixes that generated blob keys could silently collide, leading to + data loss. + + *Julik Tarkhanov* + + ## Rails 6.0.0 (August 16, 2019) ## * No changes. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/app/jobs/active_storage/analyze_job.rb new/app/jobs/active_storage/analyze_job.rb --- old/app/jobs/active_storage/analyze_job.rb 2019-08-16 19:59:07.000000000 +0200 +++ new/app/jobs/active_storage/analyze_job.rb 2019-11-05 15:37:50.000000000 +0100 @@ -4,6 +4,7 @@ class ActiveStorage::AnalyzeJob < ActiveStorage::BaseJob queue_as { ActiveStorage.queues[:analysis] } + discard_on ActiveRecord::RecordNotFound retry_on ActiveStorage::IntegrityError, attempts: 10, wait: :exponentially_longer def perform(blob) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/app/models/active_storage/blob.rb new/app/models/active_storage/blob.rb --- old/app/models/active_storage/blob.rb 2019-08-16 19:59:07.000000000 +0200 +++ new/app/models/active_storage/blob.rb 2019-11-05 15:37:50.000000000 +0100 @@ -5,8 +5,9 @@ # A blob is a record that contains the metadata about a file and a key for where that file resides on the service. # Blobs can be created in two ways: # -# 1. Subsequent to the file being uploaded server-side to the service via <tt>create_after_upload!</tt>. -# 2. Ahead of the file being directly uploaded client-side to the service via <tt>create_before_direct_upload!</tt>. +# 1. Ahead of the file being uploaded server-side to the service, via <tt>create_and_upload!</tt>. A rewindable +# <tt>io</tt> with the file contents must be available at the server for this operation. +# 2. Ahead of the file being directly uploaded client-side to the service, via <tt>create_before_direct_upload!</tt>. # # The first option doesn't require any client-side JavaScript integration, and can be used by any other back-end # service that deals with files. The second option is faster, since you're not using your own server as a staging @@ -63,14 +64,23 @@ end end - # Returns a saved blob instance after the +io+ has been uploaded to the service. Note, the blob is first built, - # then the +io+ is uploaded, then the blob is saved. This is done this way to avoid uploading (which may take - # time), while having an open database transaction. + def create_after_unfurling!(io:, filename:, content_type: nil, metadata: nil, identify: true, record: nil) #:nodoc: + build_after_unfurling(io: io, filename: filename, content_type: content_type, metadata: metadata, identify: identify).tap(&:save!) + end + + # Creates a new blob instance and then uploads the contents of the given <tt>io</tt> to the + # service. The blob instance is saved before the upload begins to avoid clobbering another due + # to key collisions. + # # When providing a content type, pass <tt>identify: false</tt> to bypass automatic content type inference. - def create_after_upload!(io:, filename:, content_type: nil, metadata: nil, identify: true) - build_after_upload(io: io, filename: filename, content_type: content_type, metadata: metadata, identify: identify).tap(&:save!) + def create_and_upload!(io:, filename:, content_type: nil, metadata: nil, identify: true, record: nil) + create_after_unfurling!(io: io, filename: filename, content_type: content_type, metadata: metadata, identify: identify).tap do |blob| + blob.upload_without_unfurling(io) + end end + alias_method :create_after_upload!, :create_and_upload! + # Returns a saved blob _without_ uploading a file to the service. This blob will point to a key where there is # no file yet. It's intended to be used together with a client-side upload, which will first create the blob # in order to produce the signed URL for uploading. This signed URL points to the key generated by the blob. @@ -165,8 +175,9 @@ # and store that in +byte_size+ on the blob record. The content type is automatically extracted from the +io+ unless # you specify a +content_type+ and pass +identify+ as false. # - # Normally, you do not have to call this method directly at all. Use the factory class methods of +build_after_upload+ - # and +create_after_upload!+. + # Normally, you do not have to call this method directly at all. Use the +create_and_upload!+ class method instead. + # If you do use this method directly, make sure you are using it on a persisted Blob as otherwise another blob's + # data might get overwritten on the service. def upload(io, identify: true) unfurl io, identify: identify upload_without_unfurling io Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_storage/attached/model.rb new/lib/active_storage/attached/model.rb --- old/lib/active_storage/attached/model.rb 2019-08-16 19:59:07.000000000 +0200 +++ new/lib/active_storage/attached/model.rb 2019-11-05 15:37:50.000000000 +0100 @@ -95,13 +95,13 @@ def #{name}=(attachables) if ActiveStorage.replace_on_assign_to_many attachment_changes["#{name}"] = - if attachables.nil? || Array(attachables).none? + if Array(attachables).none? ActiveStorage::Attached::Changes::DeleteMany.new("#{name}", self) else ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, attachables) end else - if !attachables.nil? || Array(attachables).any? + if Array(attachables).any? attachment_changes["#{name}"] = ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, #{name}.blobs + attachables) end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/active_storage/gem_version.rb new/lib/active_storage/gem_version.rb --- old/lib/active_storage/gem_version.rb 2019-08-16 19:59:07.000000000 +0200 +++ new/lib/active_storage/gem_version.rb 2019-11-05 15:37:50.000000000 +0100 @@ -9,7 +9,7 @@ module VERSION MAJOR = 6 MINOR = 0 - TINY = 0 + TINY = 1 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2019-08-16 19:59:07.000000000 +0200 +++ new/metadata 2019-11-05 15:37:50.000000000 +0100 @@ -1,14 +1,14 @@ --- !ruby/object:Gem::Specification name: activestorage version: !ruby/object:Gem::Version - version: 6.0.0 + version: 6.0.1 platform: ruby authors: - David Heinemeier Hansson autorequire: bindir: bin cert_chain: [] -date: 2019-08-16 00:00:00.000000000 Z +date: 2019-11-05 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: actionpack @@ -16,42 +16,42 @@ requirements: - - '=' - !ruby/object:Gem::Version - version: 6.0.0 + version: 6.0.1 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '=' - !ruby/object:Gem::Version - version: 6.0.0 + version: 6.0.1 - !ruby/object:Gem::Dependency name: activejob requirement: !ruby/object:Gem::Requirement requirements: - - '=' - !ruby/object:Gem::Version - version: 6.0.0 + version: 6.0.1 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '=' - !ruby/object:Gem::Version - version: 6.0.0 + version: 6.0.1 - !ruby/object:Gem::Dependency name: activerecord requirement: !ruby/object:Gem::Requirement requirements: - - '=' - !ruby/object:Gem::Version - version: 6.0.0 + version: 6.0.1 type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - '=' - !ruby/object:Gem::Version - version: 6.0.0 + version: 6.0.1 - !ruby/object:Gem::Dependency name: marcel requirement: !ruby/object:Gem::Requirement @@ -150,8 +150,11 @@ licenses: - MIT metadata: - source_code_uri: https://github.com/rails/rails/tree/v6.0.0/activestorage - changelog_uri: https://github.com/rails/rails/blob/v6.0.0/activestorage/CHANGELOG.md + bug_tracker_uri: https://github.com/rails/rails/issues + changelog_uri: https://github.com/rails/rails/blob/v6.0.1/activestorage/CHANGELOG.md + documentation_uri: https://api.rubyonrails.org/v6.0.1/ + mailing_list_uri: https://groups.google.com/forum/#!forum/rubyonrails-talk + source_code_uri: https://github.com/rails/rails/tree/v6.0.1/activestorage post_install_message: rdoc_options: [] require_paths: @@ -167,7 +170,7 @@ - !ruby/object:Gem::Version version: '0' requirements: [] -rubygems_version: 3.0.1 +rubygems_version: 3.0.3 signing_key: specification_version: 4 summary: Local and cloud file storage framework.