Class: Fastlane::Actions::UploadToS3Action

Inherits:
Action
  • Object
show all
Defined in:
lib/fastlane/plugin/wpmreleasetoolkit/actions/common/upload_to_s3.rb

Class Method Summary collapse

Class Method Details

.authorsObject



73
74
75
# File 'lib/fastlane/plugin/wpmreleasetoolkit/actions/common/upload_to_s3.rb', line 73

def self.authors
  ['Automattic']
end

.available_optionsObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/fastlane/plugin/wpmreleasetoolkit/actions/common/upload_to_s3.rb', line 85

def self.available_options
  [
    FastlaneCore::ConfigItem.new(
      key: :bucket,
      description: 'The bucket that will store the file',
      optional: false,
      type: String,
      verify_block: proc { |bucket| UI.user_error!('You must provide a valid bucket name') if bucket.empty? }
    ),
    FastlaneCore::ConfigItem.new(
      key: :key,
      description: 'The path to the file within the bucket. If `nil`, will default to the `file\'s basename',
      optional: true,
      type: String,
      verify_block: proc { |key|
        next if key.is_a?(String) && !key.empty?

        UI.user_error!('The provided key must not be empty. Use nil instead if you want to default to the file basename')
      }
    ),
    FastlaneCore::ConfigItem.new(
      key: :file,
      description: 'The path to the local file on disk',
      optional: false,
      type: String,
      verify_block: proc { |f| UI.user_error!("Path `#{f}` does not exist.") unless File.file?(f) }
    ),
    FastlaneCore::ConfigItem.new(
      key: :auto_prefix,
      description: 'Generate a derived prefix based on the filename that makes it harder to guess the URL of the uploaded object',
      optional: true,
      default_value: true,
      type: Boolean
    ),
    FastlaneCore::ConfigItem.new(
      key: :skip_if_exists,
      description: 'If the file already exists in the S3 bucket, skip the upload (and report it in the logs), instead of failing with `user_error!`',
      deprecated: 'Use if_exists instead',
      conflicting_options: [:if_exists],
      conflict_block: proc do |option|
        UI.user_error!("You cannot set both :#{option.key} and :skip_if_exists. Please only use :if_exists.")
      end,
      optional: true,
      # This option is deprecated but we stil set a default value to inform that the default behavior is for the action to fail when printing the action docs.
      # See also https://github.com/wordpress-mobile/release-toolkit/pull/500#discussion_r1239642179
      default_value: false,
      type: Boolean
    ),
    FastlaneCore::ConfigItem.new(
      key: :if_exists,
      description: 'What do to if the file file already exists in the S3 bucket. Possible values :skip, :replace, :fail. When set, overrides the deprecated skip_if_exists option',
      conflicting_options: [:skip_if_exists],
      conflict_block: proc do |option|
        UI.user_error!("You cannot set both :#{option.key} and :if_exists. Please only use :if_exists.")
      end,
      optional: true,
      type: Symbol,
      # We cannot set a default value and have backward compatibility with skip_if_exists at the same time.
      # (Short of duplicating the default value knowledge in the action implementation)
      #
      # We have a test for the default behavior which should hopefully remind us to uncomment this line once well remove skip_if_exists.
      # default_value: :fail,
      verify_block: proc do |value|
        UI.user_error!('`if_exist` must be one of :skip, :replace, :fail') unless i[skip replace fail].include?(value)
      end
    ),
  ]
end

.descriptionObject



69
70
71
# File 'lib/fastlane/plugin/wpmreleasetoolkit/actions/common/upload_to_s3.rb', line 69

def self.description
  'Uploads a given file to S3'
end

.detailsObject



81
82
83
# File 'lib/fastlane/plugin/wpmreleasetoolkit/actions/common/upload_to_s3.rb', line 81

def self.details
  'Uploads a file to S3, and makes a pre-signed URL available in the lane context'
end

.file_is_already_uploaded?(bucket, key) ⇒ Boolean

Returns:

  • (Boolean)


59
60
61
62
63
64
65
66
67
# File 'lib/fastlane/plugin/wpmreleasetoolkit/actions/common/upload_to_s3.rb', line 59

def self.file_is_already_uploaded?(bucket, key)
  response = Aws::S3::Client.new.head_object(
    bucket: bucket,
    key: key
  )
  response[:content_length].positive?
rescue Aws::S3::Errors::NotFound
  false
end

.is_supported?(platform) ⇒ Boolean

Returns:

  • (Boolean)


154
155
156
# File 'lib/fastlane/plugin/wpmreleasetoolkit/actions/common/upload_to_s3.rb', line 154

def self.is_supported?(platform)
  true
end

.return_valueObject



77
78
79
# File 'lib/fastlane/plugin/wpmreleasetoolkit/actions/common/upload_to_s3.rb', line 77

def self.return_value
  'Returns the object\'s derived S3 key'
end

.run(params) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/fastlane/plugin/wpmreleasetoolkit/actions/common/upload_to_s3.rb', line 11

def self.run(params)
  file_path = params[:file]
  file_name = File.basename(file_path)

  bucket = params[:bucket]
  key = params[:key] || file_name

  if params[:auto_prefix] == true
    file_name_hash = Digest::SHA1.hexdigest(file_name)
    key = [file_name_hash, key].join('/')
  end

  if file_is_already_uploaded?(bucket, key)
    message = "File already exists in S3 bucket #{bucket} at #{key}"

    # skip_if_exists is deprecated but we want to keep backward compatibility.
    params[:if_exists] ||= params[:skip_if_exists] ? :skip : :fail

    case params[:if_exists]
    when :fail
      UI.user_error!(message)
    when :replace
      UI.important("#{message}. Will replace with the given one.")
    when :skip
      UI.important("#{message}. Skipping upload.")
      return key
    end
  end

  UI.message("Uploading #{file_path} to: #{key}")

  File.open(file_path, 'rb') do |file|
    Aws::S3::Client.new.put_object(
      body: file,
      bucket: bucket,
      key: key
    )
  rescue Aws::S3::Errors::ServiceError => e
    UI.crash!("Unable to upload file to S3: #{e.message}")
  end

  UI.success('Upload Complete')

  Actions.lane_context[SharedValues::S3_UPLOADED_FILE_PATH] = key

  key
end