puppet_forge 4.0.0 → 4.1.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: a0e379f885f305dfc82f87bfea6ae668d6467595f0083355cbe95c63e9864019
4
- data.tar.gz: 1cf23ce28776267459e01bedfed935750650378542b54e1ec3155efb9b67ba60
3
+ metadata.gz: bf36457b8298a66e2b7af77d53a0bf476b4881c2dd29de7b1e8a49a523400f53
4
+ data.tar.gz: e5926f236dbe38b61bf3e1b9e96677ef352db5afabb9de836d40d1be136830f5
5
5
  SHA512:
6
- metadata.gz: b32e4f0758fe84f28339cc8a3f57dad01a21abc26a490e7d1b8ac1a4ecdc6e52b961e4c24f0f4a5b476c4fc1ed849bfb42594314a120f6198c06261036702457
7
- data.tar.gz: 044a092e9f8e15f078043281bac236c8694c037a1f71bb34a4d0e392379811e88ac9981afa6d75661cc5483a7a3966af26def433fe2eeb370c9f2d80499fbcba
6
+ metadata.gz: d604d660f74c37ea1bdeeb048d94edf557b1037d46bc6e83963f1d8b9d1652ceb66d3aafb3b498c470ffc1083c7d2fbb5d22a410b3ae2e91e12b7381f2ee9c26
7
+ data.tar.gz: fbf2a345b0c6b538a7a0424965d13aa1ab54f9e064273fe983176b60516a1076b1f3bd7b8edca3bed5272b0380de1fb6448d81dde147d31f3961c99ea49fde26
data/CHANGELOG.md CHANGED
@@ -3,6 +3,11 @@
3
3
  Starting with v2.0.0, all notable changes to this project will be documented in this file.
4
4
  This project adheres to [Semantic Versioning](http://semver.org/).
5
5
 
6
+ ## v4.1.0 - 2023-02-21
7
+
8
+ * Add upload method functionality.
9
+ * Allows the user to search by an array of endorsements.
10
+
6
11
  ## v4.0.0 - 2022-11-30
7
12
 
8
13
  * Breaking: The `puppet_forge` gem now requires at least Ruby 2.6.0
data/README.md CHANGED
@@ -136,7 +136,23 @@ release.verify(Pathname(release_tarball))
136
136
  # @raise RuntimeError if it fails to extract the contents of the release tarball
137
137
  PuppetForge::Unpacker.unpack(release_tarball, dest_dir, tmp_dir)
138
138
  ```
139
+ ### Uploading a module release
139
140
 
141
+ You can upload new module versions to the forge by following the steps below.
142
+
143
+ > Note: This API requires authorization. See [Authorization](#authorization) for more information.
144
+
145
+ ```ruby
146
+ release_tarball = 'pkg/puppetlabs-apache-1.6.0.tar.gz'
147
+
148
+ # Upload a module tarball to the Puppet Forge
149
+ # Returns an instance of V3::Release class and the response from the forge upload
150
+ # @raise PuppetForge::ReleaseForbidden if a 403 response is recieved from the server
151
+ # @raise PuppetForge::ReleaseBadContent if the module to upload is not valid
152
+ # @raise Faraday::ClientError if any errors encountered in the upload
153
+ # @raise PuppetForge::FileNotFound if the given tarball cannot be found
154
+ release, response = PuppetForge::V3::Release.upload(release_tarball)
155
+ ```
140
156
 
141
157
  ### Paginated Collections
142
158
 
@@ -28,16 +28,32 @@ Could not install package
28
28
  end
29
29
  end
30
30
 
31
+
32
+ class ErrorWithDetail < PuppetForge::Error
33
+ def self.from_response(response)
34
+ body = JSON.parse(response[:body])
35
+
36
+ message = body['message']
37
+ if body.key?('errors') && !body['errors']&.empty?
38
+ message << "\nThe following errors were returned from the server:\n - #{body['errors'].join("\n - ")}"
39
+ end
40
+
41
+ new(message)
42
+ end
43
+ end
44
+
45
+ class FileNotFound < PuppetForge::Error
46
+ end
47
+
31
48
  class ModuleNotFound < PuppetForge::Error
32
49
  end
33
50
 
34
51
  class ReleaseNotFound < PuppetForge::Error
35
52
  end
36
53
 
37
- class ReleaseForbidden < PuppetForge::Error
38
- def self.from_response(response)
39
- body = JSON.parse(response[:body])
40
- new(body["message"])
41
- end
54
+ class ReleaseForbidden < PuppetForge::ErrorWithDetail
55
+ end
56
+
57
+ class ReleaseBadContent < PuppetForge::ErrorWithDetail
42
58
  end
43
59
  end
@@ -66,6 +66,9 @@ module PuppetForge
66
66
  uri_path = "v3/#{resource}/#{item}"
67
67
  end
68
68
 
69
+ # The API expects a space separated string. This allows the user to invoke it with a more natural feeling array.
70
+ params['endorsements'] = params['endorsements'].join(' ') if params['endorsements'].is_a? Array
71
+
69
72
  PuppetForge::V3::Base.conn.get uri_path, params
70
73
  end
71
74
 
@@ -2,6 +2,7 @@ require 'puppet_forge/v3/base'
2
2
  require 'puppet_forge/v3/module'
3
3
 
4
4
  require 'digest'
5
+ require 'base64'
5
6
 
6
7
  module PuppetForge
7
8
  module V3
@@ -38,6 +39,38 @@ module PuppetForge
38
39
  end
39
40
  end
40
41
 
42
+ # Uploads the tarbarll to the forge
43
+ #
44
+ # @param path [Pathname] tarball file path
45
+ # @return resp
46
+ def self.upload(path)
47
+ # We want to make sure that the file exists before trying to upload it
48
+ raise PuppetForge::FileNotFound, "The file '#{path}' does not exist." unless File.file?(path)
49
+
50
+ file = File.open(path, 'rb')
51
+ encoded_string = Base64.encode64(file.read)
52
+ data = { file: encoded_string }
53
+
54
+ resp = conn.post do |req|
55
+ req.url '/v3/releases'
56
+ req.headers['Content-Type'] = 'application/json'
57
+ req.body = data.to_json
58
+ end
59
+
60
+ [self, resp]
61
+ rescue Faraday::ClientError => e
62
+ if e.response
63
+ case e.response[:status]
64
+ when 403
65
+ raise PuppetForge::ReleaseForbidden.from_response(e.response)
66
+ when 400
67
+ raise PuppetForge::ReleaseBadContent.from_response(e.response)
68
+ end
69
+ end
70
+
71
+ raise e
72
+ end
73
+
41
74
  # Verify that a downloaded module matches the best available checksum in the metadata for this release,
42
75
  # validates SHA-256 checksum if available, otherwise validates MD5 checksum
43
76
  #
@@ -1,3 +1,3 @@
1
1
  module PuppetForge
2
- VERSION = '4.0.0' # Library version
2
+ VERSION = '4.1.0' # Library version
3
3
  end
@@ -218,5 +218,43 @@ describe PuppetForge::V3::Release do
218
218
  expect(release.created_at).to_not be nil
219
219
  end
220
220
  end
221
+
222
+ describe '#upload' do
223
+ let(:tarball) { "#{PROJECT_ROOT}/spec/tmp/module.tgz" }
224
+ let(:file_object) { double('file', read: 'file contents') }
225
+
226
+ let(:release) { PuppetForge::V3::Release.upload(tarball) }
227
+ let(:mock_conn) { instance_double('PuppetForge::V3::Connection', url_prefix: PuppetForge.host) }
228
+
229
+ context 'when there is no auth token provided' do
230
+ it 'raises PuppetForge::ReleaseForbidden' do
231
+ allow(File).to receive(:file?).and_return(true)
232
+ allow(File).to receive(:open).and_return(file_object)
233
+ allow(described_class).to receive(:conn).and_return(mock_conn)
234
+
235
+ response = { status: 403, body: { 'message' => 'Forbidden' }.to_json }
236
+ expect(mock_conn).to receive(:post).and_raise(Faraday::ClientError.new('Forbidden', response))
237
+ expect { release }.to raise_error(PuppetForge::ReleaseForbidden)
238
+ end
239
+ end
240
+
241
+ context 'when the module is not valid' do
242
+ it 'raises PuppetForge::ReleaseBadRequest' do
243
+ allow(File).to receive(:file?).and_return(true)
244
+ allow(File).to receive(:open).and_return(file_object)
245
+ allow(described_class).to receive(:conn).and_return(mock_conn)
246
+
247
+ response = { status: 400, body: { message: 'Bad Content' }.to_json }
248
+ expect(mock_conn).to receive(:post).and_raise(Faraday::ClientError.new('400', response))
249
+ expect { release }.to raise_error(PuppetForge::ReleaseBadContent)
250
+ end
251
+ end
252
+
253
+ context 'when the tarball does not exist' do
254
+ it 'raises PuppetForge::FileNotFound' do
255
+ expect { PuppetForge::V3::Release.upload(tarball) }.to raise_error(PuppetForge::FileNotFound)
256
+ end
257
+ end
258
+ end
221
259
  end
222
260
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet_forge
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet Labs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-01 00:00:00.000000000 Z
11
+ date: 2023-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -266,7 +266,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
266
266
  - !ruby/object:Gem::Version
267
267
  version: '0'
268
268
  requirements: []
269
- rubygems_version: 3.1.6
269
+ rubygems_version: 3.3.7
270
270
  signing_key:
271
271
  specification_version: 4
272
272
  summary: Access the Puppet Forge API from Ruby for resource information and to download