From 60c4788536ee9f5227f05228953f5b6f4e1063e8 Mon Sep 17 00:00:00 2001 From: Mark Bumiller Date: Tue, 15 Sep 2026 07:06:57 -0400 Subject: [PATCH] fix: Return response from multipart copy_to/copy_from instead of nil fixes https://github.com/aws/aws-sdk-ruby/issues/3420 --- gems/aws-sdk-s3/CHANGELOG.md | 2 ++ .../lib/aws-sdk-s3/object_multipart_copier.rb | 1 + .../spec/object/multipart_copy_spec.rb | 15 +++++++++++++++ .../spec/object_multipart_copier_spec.rb | 18 ++++++++++++++++++ 4 files changed, 36 insertions(+) diff --git a/gems/aws-sdk-s3/CHANGELOG.md b/gems/aws-sdk-s3/CHANGELOG.md index 124631b0279..cf76c88c9ee 100644 --- a/gems/aws-sdk-s3/CHANGELOG.md +++ b/gems/aws-sdk-s3/CHANGELOG.md @@ -1,6 +1,8 @@ Unreleased Changes ------------------ +* Issue - Return the copy response from multipart `copy_to`/`copy_from` instead of `nil` on success. + 1.232.0 (2026-09-11) ------------------ diff --git a/gems/aws-sdk-s3/lib/aws-sdk-s3/object_multipart_copier.rb b/gems/aws-sdk-s3/lib/aws-sdk-s3/object_multipart_copier.rb index 60d40816306..3c2d6785f17 100644 --- a/gems/aws-sdk-s3/lib/aws-sdk-s3/object_multipart_copier.rb +++ b/gems/aws-sdk-s3/lib/aws-sdk-s3/object_multipart_copier.rb @@ -68,6 +68,7 @@ def copy(options = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength put_tags(tag_set, resp, options) if tag_set put_annotations(annotations, resp, options) if annotations&.any? + resp end private diff --git a/gems/aws-sdk-s3/spec/object/multipart_copy_spec.rb b/gems/aws-sdk-s3/spec/object/multipart_copy_spec.rb index 2925cb90f6d..a2440fa216f 100644 --- a/gems/aws-sdk-s3/spec/object/multipart_copy_spec.rb +++ b/gems/aws-sdk-s3/spec/object/multipart_copy_spec.rb @@ -69,6 +69,21 @@ def request_params(operation_name) it 'raises an error on invalid targets' do expect { object.copy_to(:target) }.to raise_error(ArgumentError) end + + it 'does not return nil when a single-shot copy succeeds' do + resp = object.copy_to('target-bucket/target-key') + + expect(resp).not_to be_nil + end + + it 'does not return nil when a multipart copy succeeds' do + client.stub_responses(:head_object, client.stub_data(:head_object, content_length: 50 * 1024 * 1024)) + client.stub_responses(:create_multipart_upload, upload_id: 'upload-id') + + resp = object.copy_to('target-bucket/target-key', multipart_copy: true) + + expect(resp).not_to be_nil + end end describe '#copy_from' do diff --git a/gems/aws-sdk-s3/spec/object_multipart_copier_spec.rb b/gems/aws-sdk-s3/spec/object_multipart_copier_spec.rb index 2367828bf42..6423a44f705 100644 --- a/gems/aws-sdk-s3/spec/object_multipart_copier_spec.rb +++ b/gems/aws-sdk-s3/spec/object_multipart_copier_spec.rb @@ -31,6 +31,12 @@ module S3 copier.copy(base_options) end + it 'returns the complete multipart upload response' do + resp = copier.copy(base_options) + + expect(resp).not_to be_nil + end + it 'respects min_part_size' do small_copier = ObjectMultipartCopier.new(client: client, min_part_size: 10 * 1024 * 1024) @@ -80,6 +86,12 @@ module S3 copier.copy(base_options.merge(tags_directive: 'COPY')) end + it 'returns the copy response after applying tags' do + resp = copier.copy(base_options.merge(tags_directive: 'COPY')) + + expect(resp).not_to be_nil + end + it 'overrides user-supplied tags' do expect(client).to receive(:create_multipart_upload) .with(hash_not_including(:tagging)) @@ -227,6 +239,12 @@ module S3 copier.copy(base_options.merge(annotations_directive: 'COPY')) end + it 'returns the copy response after applying annotations' do + resp = copier.copy(base_options.merge(annotations_directive: 'COPY')) + + expect(resp).not_to be_nil + end + it 'raises on partial failure when applying annotations' do client.stub_responses(:put_object_annotation, [{}, 'ServiceError'])