puppet_forge 3.2.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: 14fb262a13e9382bc404ebf162e70c8fa48ccd73f33f53113e75524da106bed9
4
- data.tar.gz: 0316cbac8bd7c7d3dc18d792a0dfc25a4cca095fce0974a5f54a50e546ef1c92
3
+ metadata.gz: bf36457b8298a66e2b7af77d53a0bf476b4881c2dd29de7b1e8a49a523400f53
4
+ data.tar.gz: e5926f236dbe38b61bf3e1b9e96677ef352db5afabb9de836d40d1be136830f5
5
5
  SHA512:
6
- metadata.gz: f909a3a4b8bf942f104f1a9f5a798edeb8a29e03adaaa24dbd4170efd97f2e09c23ef44b3b88ad406d32d5d10aba98d382d21ce10e1db115ee5c87d8cd01e30f
7
- data.tar.gz: 2da931edf4e563a6e0962d834c9e3db3dec6ff33fd9a172f5d50a12066863b336fae173c8ad860d6c85f6df1ef02da4e1e0fc61e0a3182e92552ac988db3ce7b
6
+ metadata.gz: d604d660f74c37ea1bdeeb048d94edf557b1037d46bc6e83963f1d8b9d1652ceb66d3aafb3b498c470ffc1083c7d2fbb5d22a410b3ae2e91e12b7381f2ee9c26
7
+ data.tar.gz: fbf2a345b0c6b538a7a0424965d13aa1ab54f9e064273fe983176b60516a1076b1f3bd7b8edca3bed5272b0380de1fb6448d81dde147d31f3961c99ea49fde26
@@ -14,7 +14,11 @@ jobs:
14
14
  runs-on: ubuntu-latest
15
15
  strategy:
16
16
  matrix:
17
- ruby: [2.7, 2.6, 2.5]
17
+ ruby:
18
+ - '3.1'
19
+ - '3.0'
20
+ - '2.7'
21
+ - '2.6'
18
22
 
19
23
  steps:
20
24
  - uses: actions/checkout@v1
@@ -22,9 +26,7 @@ jobs:
22
26
  uses: ruby/setup-ruby@v1
23
27
  with:
24
28
  ruby-version: ${{ matrix.ruby }}
29
+ bundler-cache: true
25
30
 
26
31
  - name: Build and test with Rspec
27
- run: |
28
- gem install bundler
29
- bundle install --jobs 4 --retry 3
30
- bundle exec rspec
32
+ run: bundle exec rspec
@@ -0,0 +1,24 @@
1
+ name: snyk_merge
2
+ on:
3
+ workflow_dispatch:
4
+ push:
5
+ branches:
6
+ - main
7
+ jobs:
8
+ security:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@master
12
+ - name: setup ruby
13
+ uses: ruby/setup-ruby@v1
14
+ with:
15
+ ruby-version: 2.7
16
+ - name: create lock
17
+ run: bundle lock
18
+ - name: Run Snyk to check for vulnerabilities
19
+ uses: snyk/actions/ruby@master
20
+ env:
21
+ SNYK_TOKEN: ${{ secrets.SNYK_FORGE_KEY }}
22
+ with:
23
+ command: monitor
24
+ args: --org=puppet-forge
data/CHANGELOG.md CHANGED
@@ -3,6 +3,16 @@
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
+
11
+ ## v4.0.0 - 2022-11-30
12
+
13
+ * Breaking: The `puppet_forge` gem now requires at least Ruby 2.6.0
14
+ * Update `faraday` gem to 2.x series
15
+
6
16
  ## v3.2.0 - 2021-11-09
7
17
 
8
18
  * Allow requests to follow redirects
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
 
@@ -22,4 +22,4 @@ module PuppetForge
22
22
  end
23
23
  end
24
24
 
25
- Faraday::Middleware.register_middleware(:connection_failure => lambda { PuppetForge::Connection::ConnectionFailure })
25
+ Faraday::Middleware.register_middleware(:connection_failure => PuppetForge::Connection::ConnectionFailure)
@@ -1,7 +1,7 @@
1
1
  require 'puppet_forge/connection/connection_failure'
2
2
 
3
3
  require 'faraday'
4
- require 'faraday_middleware'
4
+ require 'faraday/follow_redirects'
5
5
 
6
6
  module PuppetForge
7
7
  # Provide a common mixin for adding a HTTP connection to classes.
@@ -115,7 +115,7 @@ module PuppetForge
115
115
  end
116
116
 
117
117
  Faraday.new(url, options) do |builder|
118
- builder.use FaradayMiddleware::FollowRedirects
118
+ builder.use Faraday::FollowRedirects::Middleware
119
119
  builder.response(:json, :content_type => /\bjson$/, :parser_options => { :symbolize_names => true })
120
120
  builder.response(:raise_error)
121
121
  builder.use(:connection_failure)
@@ -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 = '3.2.0' # Library version
2
+ VERSION = '4.1.0' # Library version
3
3
  end
data/puppet_forge.gemspec CHANGED
@@ -18,10 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.required_ruby_version = '>= 2.4.0'
21
+ spec.required_ruby_version = '>= 2.6.0'
22
22
 
23
- spec.add_runtime_dependency "faraday", "~> 1.3"
24
- spec.add_runtime_dependency "faraday_middleware", "~> 1.0"
23
+ spec.add_runtime_dependency "faraday", "~> 2.0"
24
+ spec.add_runtime_dependency "faraday-follow_redirects", "~> 0.3.0"
25
25
  spec.add_dependency "semantic_puppet", "~> 1.0"
26
26
  spec.add_dependency "minitar"
27
27
 
@@ -31,8 +31,5 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "cane"
32
32
  spec.add_development_dependency "yard"
33
33
  spec.add_development_dependency "redcarpet"
34
-
35
- # Install the right pry debugging combo depending on ruby version.
36
- spec.add_development_dependency "pry-debugger" if RUBY_VERSION <= '1.9.3'
37
- spec.add_development_dependency "pry-byebug" if RUBY_VERSION >= '2.0.0'
34
+ spec.add_development_dependency "pry-byebug"
38
35
  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: 3.2.0
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet Labs
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-09 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
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: faraday_middleware
28
+ name: faraday-follow_redirects
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.0'
33
+ version: 0.3.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.0'
40
+ version: 0.3.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: semantic_puppet
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -173,6 +173,7 @@ extensions: []
173
173
  extra_rdoc_files: []
174
174
  files:
175
175
  - ".github/workflows/ruby-rspec.yml"
176
+ - ".github/workflows/snyk_merge.yml"
176
177
  - ".gitignore"
177
178
  - CHANGELOG.md
178
179
  - CODEOWNERS
@@ -250,7 +251,7 @@ homepage: https://github.com/puppetlabs/forge-ruby
250
251
  licenses:
251
252
  - Apache-2.0
252
253
  metadata: {}
253
- post_install_message:
254
+ post_install_message:
254
255
  rdoc_options: []
255
256
  require_paths:
256
257
  - lib
@@ -258,15 +259,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
258
259
  requirements:
259
260
  - - ">="
260
261
  - !ruby/object:Gem::Version
261
- version: 2.4.0
262
+ version: 2.6.0
262
263
  required_rubygems_version: !ruby/object:Gem::Requirement
263
264
  requirements:
264
265
  - - ">="
265
266
  - !ruby/object:Gem::Version
266
267
  version: '0'
267
268
  requirements: []
268
- rubygems_version: 3.1.6
269
- signing_key:
269
+ rubygems_version: 3.3.7
270
+ signing_key:
270
271
  specification_version: 4
271
272
  summary: Access the Puppet Forge API from Ruby for resource information and to download
272
273
  releases.