render_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f518a70ad78745e3ef73b6010b68fe7fd9bd49f6bd57b2a2ca0ce7ec63c9e059
4
+ data.tar.gz: d441fd7e1962cc2727a8bcaa1e2d1040c6a4352c2d2dc818e58919ebb2653a6c
5
+ SHA512:
6
+ metadata.gz: 432e9f31a2e42d761bcd2b65c7a1cbe3ee4cf5d2ebfd386d0f240dceca7dc9d852f4405b49382ec11990118440370c278034b0f8c3f10cc50d4bace402033a2d
7
+ data.tar.gz: 2afd4b56be70de6e0819cce4278c8d997392d8e4a148eb9d513308d96c7cc3fbbd67006896ea976b60f09e278b14951477ab9b48344da31a3ae754ede065d6cc
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.0.1] - 2021-12-12
4
+
5
+ - Initial release
6
+ - Partial support for service, deploy endpoints.
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Pat Allan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # Render API
2
+
3
+ A Ruby interface for [the render.com API](https://render.com/docs/api).
4
+
5
+ **Please note**: this gem is currently a proof-of-concept and does not support all of the API's endpoints yet - what's covered below in Usage is what's available right now. Full support is definitely the plan, and pull requests are welcome.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem "render_api"
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install render_api
22
+
23
+ ## Usage
24
+
25
+ ```ruby
26
+ client = RenderAPI.client(api_key)
27
+ client.services.list(limit: nil, cursor: nil, filters: nil)
28
+ client.deploys.list(service_id, limit: nil, cursor: nil, filters: nil)
29
+ client.deploys.create(service_id, clear_cache: "do_not_clear")
30
+ ```
31
+
32
+ ## Development
33
+
34
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to run the tests, and `bundle exec rubocop` to confirm linting and code structure. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
35
+
36
+ ## Contributing
37
+
38
+ Bug reports and pull requests are welcome on GitHub at https://github.com/pat/render_api. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/pat/render_api/blob/main/CODE_OF_CONDUCT.md).
39
+
40
+ ## License
41
+
42
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
43
+
44
+ ## Code of Conduct
45
+
46
+ Everyone interacting in the Render API project's codebase and other repository features is expected to follow the [code of conduct](https://github.com/pat/render_api/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./clients/deploys"
4
+ require_relative "./clients/services"
5
+ require_relative "./endpoint"
6
+
7
+ module RenderAPI
8
+ class Client
9
+ def initialize(api_key)
10
+ @api_key = api_key
11
+ end
12
+
13
+ def deploys
14
+ @deploys ||= Clients::Deploys.new(endpoint)
15
+ end
16
+
17
+ def services
18
+ @services ||= Clients::Services.new(endpoint)
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :api_key
24
+
25
+ def endpoint
26
+ @endpoint = Endpoint.new(api_key)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RenderAPI
4
+ module Clients
5
+ class Base
6
+ def initialize(endpoint)
7
+ @endpoint = endpoint
8
+ end
9
+
10
+ private
11
+
12
+ attr_reader :endpoint
13
+
14
+ def filter_parameter(value)
15
+ case value
16
+ when Array
17
+ value.join(",")
18
+ else
19
+ value.to_s
20
+ end
21
+ end
22
+
23
+ def list_parameters(limit: nil, cursor: nil, filters: nil)
24
+ parameters = {}
25
+ filters ||= {}
26
+
27
+ parameters[:limit] = limit unless limit.nil?
28
+ parameters[:cursor] = cursor unless cursor.nil?
29
+
30
+ filters.each do |key, value|
31
+ parameters[key] = filter_parameter(value)
32
+ end
33
+
34
+ parameters
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./base"
4
+
5
+ module RenderAPI
6
+ module Clients
7
+ class Deploys < Base
8
+ def create(service_id, clear_cache: nil)
9
+ body = nil
10
+ body = { clear_cache: clear_cache } unless clear_cache.nil?
11
+
12
+ endpoint.post(
13
+ "/services/#{service_id}/deploys", body: body
14
+ )
15
+ end
16
+
17
+ def list(service_id, ...)
18
+ endpoint.get(
19
+ "/services/#{service_id}/deploys", params: list_parameters(...)
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./base"
4
+
5
+ module RenderAPI
6
+ module Clients
7
+ class Services < Base
8
+ def list(...)
9
+ endpoint.get("/services", params: list_parameters(...))
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "http"
4
+
5
+ require_relative "./response"
6
+
7
+ module RenderAPI
8
+ class Endpoint
9
+ HOST = "https://api.render.com"
10
+ VERSION = "/v1"
11
+
12
+ def initialize(api_key)
13
+ @api_key = api_key
14
+ end
15
+
16
+ def get(path, params: nil)
17
+ request(:get, path, params: params)
18
+ end
19
+
20
+ def post(path, body: nil)
21
+ request(:post, path, body: body)
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :api_key
27
+
28
+ def http
29
+ HTTP
30
+ .auth("Bearer #{api_key}")
31
+ .headers("Accept" => "application/json")
32
+ end
33
+
34
+ def request(verb, path, body: nil, params: nil)
35
+ Response.new http.request(verb, url_for(path), body: body, params: params)
36
+ end
37
+
38
+ def url_for(path)
39
+ "#{HOST}#{VERSION}#{path}"
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RenderAPI
4
+ class Response
5
+ def initialize(http_response)
6
+ @http_response = http_response
7
+ end
8
+
9
+ def data
10
+ @data ||= http_response.parse(:json)
11
+ end
12
+
13
+ def headers
14
+ @headers ||= http_response.headers.to_h
15
+ end
16
+
17
+ def rate_limit
18
+ headers["Ratelimit-Limit"].to_i
19
+ end
20
+
21
+ def rate_limit_remaining
22
+ headers["Ratelimit-Remaining"].to_i
23
+ end
24
+
25
+ def rate_limit_reset
26
+ headers["Ratelimit-Reset"].to_i
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :http_response
32
+ end
33
+ end
data/lib/render_api.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "./render_api/client"
4
+
5
+ module RenderAPI
6
+ Error = Class.new(StandardError)
7
+
8
+ def self.client(api_key)
9
+ RenderAPI::Client.new(api_key)
10
+ end
11
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe "Deploys" do
4
+ let(:client) { RenderAPI.client "test-api-key" }
5
+ let(:service_id) { "random-string" }
6
+
7
+ subject { client.deploys }
8
+
9
+ describe "create" do
10
+ before :each do
11
+ stub_request(
12
+ :post, "https://api.render.com/v1/services/#{service_id}/deploys"
13
+ ).to_return_json(
14
+ body: {
15
+ "id" => "new-deploy",
16
+ "commit" => {
17
+ "id" => "string",
18
+ "message" => "string",
19
+ "createdAt" => "2021-12-12T08:34:38.327Z"
20
+ },
21
+ "status" => "created",
22
+ "finishedAt" => "2021-12-12T08:34:38.327Z",
23
+ "createdAt" => "2021-12-12T08:34:38.327Z",
24
+ "updatedAt" => "2021-12-12T08:34:38.327Z"
25
+ }
26
+ )
27
+ end
28
+
29
+ it "returns the new deploy details" do
30
+ response = subject.create(service_id)
31
+
32
+ expect(response.data["id"]).to eq("new-deploy")
33
+ end
34
+ end
35
+
36
+ describe "list" do
37
+ before :each do
38
+ stub_request(
39
+ :get, "https://api.render.com/v1/services/#{service_id}/deploys"
40
+ ).to_return_json(
41
+ body: [
42
+ {
43
+ "deploy" => {
44
+ "id" => "my-deploy",
45
+ "commit" => {
46
+ "id" => "string",
47
+ "message" => "string",
48
+ "createdAt" => "2021-12-12T08:31:33.669Z"
49
+ },
50
+ "status" => "created",
51
+ "finishedAt" => "2021-12-12T08:31:33.670Z",
52
+ "createdAt" => "2021-12-12T08:31:33.670Z",
53
+ "updatedAt" => "2021-12-12T08:31:33.670Z"
54
+ },
55
+ "cursor" => "string"
56
+ }
57
+ ]
58
+ )
59
+ end
60
+
61
+ it "returns deploy data" do
62
+ response = subject.list(service_id)
63
+
64
+ expect(response.data.length).to eq(1)
65
+ expect(response.data.first["deploy"]["id"]).to eq("my-deploy")
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe "Services" do
4
+ let(:client) { RenderAPI.client "test-api-key" }
5
+
6
+ subject { client.services }
7
+
8
+ describe "list" do
9
+ before :each do
10
+ stub_request(
11
+ :get, "https://api.render.com/v1/services"
12
+ ).to_return_json(
13
+ body: [
14
+ {
15
+ "service" => {
16
+ "id" => "string",
17
+ "autoDeploy" => "yes",
18
+ "branch" => "string",
19
+ "createdAt" => "2021-12-12T08:02:47.138Z",
20
+ "name" => "my-service",
21
+ "notifyOnFail" => "default",
22
+ "ownerId" => "string",
23
+ "repo" => "string",
24
+ "slug" => "string",
25
+ "suspended" => "suspended",
26
+ "suspenders" => [
27
+ "admin"
28
+ ],
29
+ "type" => "static_site",
30
+ "updatedAt" => "2021-12-12T08:02:47.138Z",
31
+ "serviceDetails" => {
32
+ "buildCommand" => "string",
33
+ "parentServer" => {
34
+ "id" => "string",
35
+ "name" => "string"
36
+ },
37
+ "publishPath" => "string",
38
+ "pullRequestPreviewsEnabled" => "yes",
39
+ "url" => "string"
40
+ }
41
+ },
42
+ "cursor" => "string"
43
+ }
44
+ ]
45
+ )
46
+ end
47
+
48
+ it "returns service data" do
49
+ response = subject.list
50
+
51
+ expect(response.data.length).to eq(1)
52
+ expect(response.data.first["service"]["name"]).to eq("my-service")
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "render_api"
4
+
5
+ require_relative "./support/webmock"
6
+
7
+ RSpec.configure do |config|
8
+ config.disable_monkey_patching!
9
+
10
+ config.expect_with(:rspec) { |c| c.syntax = :expect }
11
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "delegate"
4
+ require "webmock/rspec"
5
+
6
+ module WebmockJSONHelpers
7
+ def stub_request(method, uri)
8
+ RequestStub.new(super)
9
+ end
10
+
11
+ def a_request(method, uri)
12
+ RequestPattern.new(super)
13
+ end
14
+
15
+ class RequestStub < SimpleDelegator
16
+ def to_return_json(*response_hashes, &block)
17
+ typed_hashes = response_hashes.map do |hash|
18
+ typed = hash.dup
19
+
20
+ typed[:headers] ||= {}
21
+ typed[:headers]["Content-Type"] = "application/json"
22
+
23
+ typed[:body] = JSON.dump(hash[:body] || {})
24
+
25
+ typed
26
+ end
27
+
28
+ to_return(*typed_hashes, &block)
29
+ end
30
+ end
31
+
32
+ class RequestPattern < SimpleDelegator
33
+ def with_json_body
34
+ with do |request|
35
+ yield JSON.parse(request.body)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ RSpec.configure do |config|
42
+ config.include WebmockJSONHelpers
43
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: render_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Pat Allan
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-12-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: http
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - pat@freelancing-gods.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".rspec"
91
+ - CHANGELOG.md
92
+ - Gemfile
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - lib/render_api.rb
97
+ - lib/render_api/client.rb
98
+ - lib/render_api/clients/base.rb
99
+ - lib/render_api/clients/deploys.rb
100
+ - lib/render_api/clients/services.rb
101
+ - lib/render_api/endpoint.rb
102
+ - lib/render_api/response.rb
103
+ - spec/features/deploys_spec.rb
104
+ - spec/features/services_spec.rb
105
+ - spec/spec_helper.rb
106
+ - spec/support/webmock.rb
107
+ homepage: https://github.com/pat/render_api
108
+ licenses:
109
+ - MIT
110
+ metadata:
111
+ homepage_uri: https://github.com/pat/render_api
112
+ source_code_uri: https://github.com/pat/render_api
113
+ changelog_uri: https://github.com/pat/render_api/blob/main/CHANGELOG.md
114
+ rubygems_mfa_required: 'true'
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: 2.7.0
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubygems_version: 3.2.32
131
+ signing_key:
132
+ specification_version: 4
133
+ summary: Ruby interface for the render.com API.
134
+ test_files:
135
+ - spec/features/deploys_spec.rb
136
+ - spec/features/services_spec.rb
137
+ - spec/spec_helper.rb
138
+ - spec/support/webmock.rb
139
+ - ".rspec"
140
+ - Gemfile
141
+ - Rakefile