bridgetown-deploy_hook 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +12 -0
- data/CONTRIBUTING.md +53 -0
- data/LICENSE.md +21 -0
- data/README.md +98 -0
- data/bridgetown-deploy_hook.gemspec +35 -0
- data/lib/bridgetown/deploy_hook/authorization.rb +112 -0
- data/lib/bridgetown/deploy_hook/initializer.rb +19 -0
- data/lib/bridgetown/deploy_hook/version.rb +10 -0
- data/lib/bridgetown-deploy_hook.rb +34 -0
- data/lib/roda/plugins/bridgetown_deploy_hook.rb +115 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 48fcc6269af2fb7964d63514ef469a0a6816ceab6392904e96047dbcb700b599
|
4
|
+
data.tar.gz: 82a3243dbcda7345a0b0243038685d8270cbc6af8c3e6457c6770b24c9a7b2d3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5f2ebb6640d09564dd7573c7345cb440027dfd541aa8f4a5d432165d7b967e61444d8585c48d03999e154121df3a5d4fa2a026c31e966a0982f0b6a659b78e17
|
7
|
+
data.tar.gz: 6778c4a3638d745fe08145f9f6459a650f64128d98c3bb9cb92c6c0427e2d664ab50b8dfb4ccfd540d71523415fa282f69433792aaa4704684b36ae322f2a329
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## [0.1.0](https://github.com/michaelherold/bridgetown-deploy_hook/tree/v0.1.0) - 2023-03-11
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- The ability to specify authorizers for any HTTP Authorization schemes, whether current or future, through the initializer. These can be anything responding to `#call` with a nilable string argument with a truthy value for success and a falsey one for failure.
|
12
|
+
- The ability the set the route for the deploy hook.
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
In the spirit of [free software](http://www.fsf.org/licensing/essays/free-sw.html), we encourage **everyone** to help improve this project. Here are some ways _you_ can contribute:
|
4
|
+
|
5
|
+
* Use alpha, beta, and pre-release versions.
|
6
|
+
* Report bugs.
|
7
|
+
* Suggest new features.
|
8
|
+
* Write or edit documentation.
|
9
|
+
* Write specifications.
|
10
|
+
* Write code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace).
|
11
|
+
* Refactor code.
|
12
|
+
* Fix [issues](https://github.com/michaelherold/bridgetown-deploy_hook/issues).
|
13
|
+
* Review patches.
|
14
|
+
|
15
|
+
## Submitting an Issue
|
16
|
+
|
17
|
+
We use the [GitHub issue tracker](https://github.com/michaelherold/bridgetown-deploy_hook/issues) to track bugs and features. Before submitting a bug report or feature request, check to make sure no one has already submitted it.
|
18
|
+
|
19
|
+
When submitting a bug report, please include a `<details>` block that includes a stack trace and any details that may be necessary to reproduce the bug, including your gem version, Ruby version, and operating system. This looks like the following:
|
20
|
+
|
21
|
+
```markdown
|
22
|
+
<details>
|
23
|
+
<summary>A description of the details block</summary>
|
24
|
+
|
25
|
+
All of the content that you want in here, perhaps with code fences. Note that
|
26
|
+
if you only have a code fence in here, you _must_ separate it from the <summary>
|
27
|
+
tag and the closing </details> or it won't render correctly.
|
28
|
+
|
29
|
+
Notice the empty line here ↓
|
30
|
+
|
31
|
+
</details>
|
32
|
+
```
|
33
|
+
|
34
|
+
Ideally, a bug report should include a pull request with failing specs.
|
35
|
+
|
36
|
+
## Submitting a Pull Request
|
37
|
+
|
38
|
+
1. Fork the repository.
|
39
|
+
2. Create a topic branch.
|
40
|
+
3. Add specs for your unimplemented feature or bug fix.
|
41
|
+
4. Run `bundle exec rake test`. If your specs pass, return to step 3.
|
42
|
+
5. Implement your feature or bug fix.
|
43
|
+
6. Run `bundle exec rake`. If your specs or any of the linters fail, return to step 5.
|
44
|
+
7. Open `coverage/index.html`. If your changes are not fully covered by your tests, return to step 3.
|
45
|
+
8. Add documentation for your feature or bug fix.
|
46
|
+
9. Commit and push your changes.
|
47
|
+
10. Submit a pull request.
|
48
|
+
|
49
|
+
## Tools to Help You Succeed
|
50
|
+
|
51
|
+
After checking out the repository, run `bin/setup` to install dependencies. Then, run `bundle exec rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
52
|
+
|
53
|
+
Before committing code, run `bundle exec rake` to check that the code conforms to the style guidelines of the project, that all of the tests are green (if you're writing a feature; if you're only submitting a failing test, then it does not have to pass!), and that you sufficiently documented the changes.
|
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright © 2023 Michael Herold
|
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,98 @@
|
|
1
|
+
# Bridgetown deploy hook plugin
|
2
|
+
|
3
|
+
A [Bridgetown](https://www.bridgetownrb.com) plugin for triggering behavior via a webhook.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Run this command to add this plugin to your site's Gemfile:
|
8
|
+
|
9
|
+
bundle add bridgetown-deploy_hook
|
10
|
+
|
11
|
+
Or you can use [an automation script](https://www.bridgetownrb.com/docs/automations) instead for guided setup:
|
12
|
+
|
13
|
+
bin/bt apply https://github.com/michaelherold/bridgetown-deploy_hook
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
To use a post-deploy hook, you must run Bridgetown with the Roda app; a static website will not work. First, add the Roda plugin to your app and call the helper for enabling the route:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
# server/roda_app.rb
|
21
|
+
class RodaApp < Bridgetown::Rack::Roda
|
22
|
+
plugin :bridgetown_ssr
|
23
|
+
plugin :bridgetown_deploy_hook
|
24
|
+
|
25
|
+
route do |r|
|
26
|
+
r.bridgetown_deploy_hook
|
27
|
+
end
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
Note that you must enable the plugin _after_ the `:bridgetown_ssr` plugin because the latter is what sets up your Bridgetown site for use by the Roda app.
|
32
|
+
|
33
|
+
Next, configure your route and authorization methods using the initializer. For example, if you want `/my-deploy-hook` to be the route for your hook and use a static [Bearer token](https://datatracker.ietf.org/doc/html/rfc6750) from your environment variables as an authorization mechanism:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
# config/initializers.rb
|
37
|
+
|
38
|
+
Bridgetown.configure do
|
39
|
+
init(
|
40
|
+
"bridgetown-deploy_hook",
|
41
|
+
authorization: {
|
42
|
+
bearer: ->(token) { token == ENV["BEARER_TOKEN"] }
|
43
|
+
}
|
44
|
+
route: "my-deploy-hook"
|
45
|
+
)
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
Lastly, register the action that you want to run with the deploy hook:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
# config/initializers.rb
|
53
|
+
# ... or any other auto-loaded file in your app
|
54
|
+
Bridgetown::Hooks.register_one :site, :post_deploy do |site|
|
55
|
+
# Your code here
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
`site` is your `Bridgetown::Site` instance so you have access to all of your configuration and resources that you have configured.
|
60
|
+
|
61
|
+
### Authorization
|
62
|
+
|
63
|
+
You may register anything that responds to `#call`, takes a string argument of the directives for your authorization type, and responds with a truthy value when authorization succeeds.
|
64
|
+
|
65
|
+
Each [authorization scheme](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes) may have a single handler registered to it. Register them with either the symbol or string cooresponding to the lowercase version of the scheme. For example, if you want to register both a [Basic](https://datatracker.ietf.org/doc/html/rfc7617) handler and a [Bearer](https://datatracker.ietf.org/doc/html/rfc6750) handler, that would look like the following:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
# config/initializers.rb
|
69
|
+
|
70
|
+
Bridgetown.configure do
|
71
|
+
init(
|
72
|
+
"bridgetown-deploy_hook",
|
73
|
+
authorization: {
|
74
|
+
basic: my_basic_handler,
|
75
|
+
bearer: my_bearer_handler,
|
76
|
+
}
|
77
|
+
route: "my-deploy-hook"
|
78
|
+
)
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
The **handlers receive the raw value from the header**, not a destructured version. So the Basic handler receives the Base64-encoded `user:password` pair, not the user and the password, so you must handle the parsing of the value appropriately for the authorization scheme.
|
83
|
+
|
84
|
+
### Plugin authors
|
85
|
+
|
86
|
+
Plugins may also interact with the deploy hook by registering their own [non-reloadable](https://www.bridgetownrb.com/docs/plugins/hooks#reloadable-vs-non-reloadable-hooks) hook handlers.
|
87
|
+
|
88
|
+
As an example:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
Bridgetown::Hooks.register_one :site, :post_deploy, reloadable: false do |site|
|
92
|
+
MyPlugin.do_the_work(site)
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
## Contributing
|
97
|
+
|
98
|
+
So you're interested in contributing to Bridgetown deploy hook? Check out our [contributing guidelines](CONTRIBUTING.md) for more information on how to do that.
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/bridgetown/deploy_hook/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "bridgetown-deploy_hook"
|
7
|
+
spec.version = Bridgetown::DeployHook::VERSION
|
8
|
+
spec.authors = ["Michael Herold"]
|
9
|
+
spec.email = ["opensource@michaeljherold.com"]
|
10
|
+
spec.summary = "Add a Bridgetown hook triggered by HTTP for running post-deploy actions"
|
11
|
+
spec.description = spec.summary
|
12
|
+
spec.homepage = "https://github.com/michaelherold/bridgetown-deploy_hook"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = %w[CHANGELOG.md CONTRIBUTING.md LICENSE.md README.md]
|
16
|
+
spec.files += %w[bridgetown-deploy_hook.gemspec]
|
17
|
+
spec.files += Dir["lib/**/*.rb"]
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.required_ruby_version = ">= 3.0.0"
|
21
|
+
|
22
|
+
spec.add_dependency "bridgetown", ">= 1.2", "< 2.0"
|
23
|
+
spec.add_dependency "zeitwerk"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", ">= 2"
|
26
|
+
|
27
|
+
spec.metadata = {
|
28
|
+
"bug_tracker_uri" => "https://github.com/michaelherold/bridgetown-deploy_hook/issues",
|
29
|
+
"changelog_uri" => "https://github.com/michaelherold/bridgetown-deploy_hook/blob/main/CHANGELOG.md",
|
30
|
+
"documentation_uri" => "https://rubydoc.info/gems/bridgetown-deploy_hook/#{Bridgetown::DeployHook::VERSION}",
|
31
|
+
"homepage_uri" => "https://github.com/michaelherold/bridgetown-deploy_hook",
|
32
|
+
"rubygems_mfa_required" => "true",
|
33
|
+
"source_code_uri" => "https://github.com/michaelherold/bridgetown-deploy_hook"
|
34
|
+
}
|
35
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bridgetown
|
4
|
+
module DeployHook
|
5
|
+
# Handles authorizing a request via its [Authorization header][1]
|
6
|
+
#
|
7
|
+
# You can configure the authorization strategies via the
|
8
|
+
# bridgetown-deploy_hook initializer. For example, if you want to allow a
|
9
|
+
# [Bearer token][2], give the configuration a callable at the `:bearer`
|
10
|
+
# value in the authorization parameter.
|
11
|
+
#
|
12
|
+
# @example Allowing a specific Bearer token
|
13
|
+
#
|
14
|
+
# Bridgetown.configure do
|
15
|
+
# init(
|
16
|
+
# "bridgetown-deploy_hook",
|
17
|
+
# authorization: {
|
18
|
+
# bearer: ->(token) { token == "myvaluemaybefromtheenvironment" }
|
19
|
+
# }
|
20
|
+
# )
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# The webhook handler parses the Authorization header and dispatches the
|
24
|
+
# authorization request to the appropriate scheme registered in the
|
25
|
+
# configuration. For example, if you want to allow [HTTP Basic
|
26
|
+
# authorization][3], the scheme is `Basic` so register the `:basic` or
|
27
|
+
# `"basic"` key in the site configuration.
|
28
|
+
#
|
29
|
+
# The authorization parameters are passed directly without any parsing or
|
30
|
+
# conversion so your interpreter will need to be able to convert the raw
|
31
|
+
# string appropriately. Missing values will end up with a `nil` so ensure
|
32
|
+
# you handle the `nil` case as well.
|
33
|
+
#
|
34
|
+
# Handlers can be anything that responds to a `#call` of a String or `nil`
|
35
|
+
# with a Boolean (or any truthy/falsey combination if that floats your
|
36
|
+
# boat).
|
37
|
+
#
|
38
|
+
# [1]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization
|
39
|
+
# [2]: https://datatracker.ietf.org/doc/html/rfc6750
|
40
|
+
# [3]: https://datatracker.ietf.org/doc/html/rfc7617
|
41
|
+
class Authorization
|
42
|
+
# The default authorizer that rejects everything
|
43
|
+
#
|
44
|
+
# @private
|
45
|
+
#
|
46
|
+
# @return [#call<String, nil>: Boolean] the authorizer
|
47
|
+
REJECT_ALL = ->(*) { false }.freeze
|
48
|
+
|
49
|
+
# Initializes a new {Authorization}
|
50
|
+
#
|
51
|
+
# @since 0.1.0
|
52
|
+
# @api public
|
53
|
+
#
|
54
|
+
# @example Using the authorizers from the current Bridgetown site
|
55
|
+
#
|
56
|
+
# Bridgetown::DeployHook::Authorization.new(
|
57
|
+
# "Basic YmlsYm86dGVzdA==",
|
58
|
+
# config: Bridgetown::Current.site.config.deploy_hook
|
59
|
+
# )
|
60
|
+
#
|
61
|
+
# @param header [String, nil] the value from the Authorization header
|
62
|
+
# @param config [HashWithDotAccess::Hash] the deploy hook configuration
|
63
|
+
# for a `Bridgetown::Site`
|
64
|
+
# @return [void]
|
65
|
+
def initialize(header, config:)
|
66
|
+
scheme, @parameters = header&.split(" ", 2)
|
67
|
+
@authorizer = config.authorization.fetch(scheme&.downcase, REJECT_ALL)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Authorizes the request based on its Authorization header
|
71
|
+
#
|
72
|
+
# @since 0.1.0
|
73
|
+
# @api public
|
74
|
+
#
|
75
|
+
# @example Authorizing every Bearer token (don't do this!)
|
76
|
+
#
|
77
|
+
# auth = Bridgetown::DeployHook::Authorization.new(
|
78
|
+
# "Bearer 123",
|
79
|
+
# config: HashWithDotAccess::Hash.new(
|
80
|
+
# authorization: {bearer: ->(_) { true }}
|
81
|
+
# )
|
82
|
+
# )
|
83
|
+
# auth.call #=> true
|
84
|
+
#
|
85
|
+
# @return [Boolean] true when authorized, false otherwise
|
86
|
+
def call
|
87
|
+
authorizer.call(parameters)
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# The authorizer responsible for checking the header value
|
93
|
+
#
|
94
|
+
# This can be anything that responds to a `#call` of a String or `nil`
|
95
|
+
# with a Boolean.
|
96
|
+
#
|
97
|
+
# @api private
|
98
|
+
# @private
|
99
|
+
#
|
100
|
+
# @return [#call<String, nil>: Boolean]
|
101
|
+
attr_reader :authorizer
|
102
|
+
|
103
|
+
# The parameters extracted from the Authorization header
|
104
|
+
#
|
105
|
+
# @api private
|
106
|
+
# @private
|
107
|
+
#
|
108
|
+
# @return [String, nil]
|
109
|
+
attr_reader :parameters
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @param config [HashWithDotAccess::Hash] the configuration for the Bridgetown site
|
4
|
+
# @param authorization [Hash<(Symbol, String, nil), #call<String, nil>: Boolean>] a
|
5
|
+
# Hash mapping Authorization schemes to authenticators, callables that map
|
6
|
+
# string-encoded parameters to Boolean values to indicate whether the attempt
|
7
|
+
# was a success or failure
|
8
|
+
# @param route [String] the route for the deploy hook within the Roda application
|
9
|
+
Bridgetown.initializer "bridgetown-deploy_hook" do |config, authorization: {}, route: "_bridgetown/deploy"|
|
10
|
+
options = {authorization: authorization, route: route}
|
11
|
+
|
12
|
+
# :nocov: Because it's not possible to show coverage for both branches
|
13
|
+
if config.deploy_hook
|
14
|
+
config.deploy_hook Bridgetown::Utils.deep_merge_hashes(options, config.deploy_hook)
|
15
|
+
else
|
16
|
+
config.deploy_hook(options)
|
17
|
+
end
|
18
|
+
# :nocov:
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "bridgetown/deploy_hook/version"
|
4
|
+
|
5
|
+
# A progressive site generator and fullstack framework
|
6
|
+
#
|
7
|
+
# @see https://www.bridgetownrb.com/
|
8
|
+
module Bridgetown
|
9
|
+
# A Bridgetown plugin that adds support for post-deploy webhooks
|
10
|
+
#
|
11
|
+
# Post-deploy actions receive the Bridgetown site as a block parameter so can
|
12
|
+
# operate on the site as a whole if they wish. This could be for sending
|
13
|
+
# Webmentions or other linkbacks, notifying your team of a deployment for a
|
14
|
+
# client site, or anything else you might find yourself needing to do.
|
15
|
+
#
|
16
|
+
# @example Adding a post-deploy hook to send a Slack notification
|
17
|
+
#
|
18
|
+
# Bridgetown::Hooks.register_one :site, :post_deploy do |site|
|
19
|
+
# SendSlackNotification.call(site)
|
20
|
+
# end
|
21
|
+
module DeployHook
|
22
|
+
# The Zeitwerk loader responsible for auto-loading constants
|
23
|
+
#
|
24
|
+
# @private
|
25
|
+
Loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false).tap do |loader|
|
26
|
+
loader.ignore(__FILE__)
|
27
|
+
loader.ignore(File.join(__dir__, "bridgetown", "deploy_hook", "initializer"))
|
28
|
+
loader.ignore(File.join(__dir__, "roda", "plugins", "deploy_hook"))
|
29
|
+
loader.setup
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
require_relative "bridgetown/deploy_hook/initializer"
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# A routing tree for building Rack applications
|
4
|
+
#
|
5
|
+
# @see https://roda.jeremyevans.net/
|
6
|
+
class Roda
|
7
|
+
# The namespace Roda uses for loading plugins by convention
|
8
|
+
module RodaPlugins
|
9
|
+
# A plugin that integrates a post-deploy webhook into a Bridgetown Roda app
|
10
|
+
#
|
11
|
+
# This plugin requires the Bridgetown SSR plugin to be enabled before it.
|
12
|
+
#
|
13
|
+
# It creates a route via the configuration set in the initializer that
|
14
|
+
# authorizes requests via {Bridgetown::DeployHook::Authorization} and runs
|
15
|
+
# the post deploy hook when authorized.
|
16
|
+
#
|
17
|
+
# See {Bridgetown::DeployHook} for an example of adding a post-deploy hook.
|
18
|
+
#
|
19
|
+
# See {Bridgetown::DeployHook::Authorization} for more information about
|
20
|
+
# authorization strategies.
|
21
|
+
module BridgetownDeployHook
|
22
|
+
# The string representing an empty response body
|
23
|
+
#
|
24
|
+
# @api private
|
25
|
+
# @private
|
26
|
+
EMPTY_BODY = ""
|
27
|
+
|
28
|
+
# The Roda hook for configuring the plugin
|
29
|
+
#
|
30
|
+
# @since 0.1.0
|
31
|
+
# @api public
|
32
|
+
#
|
33
|
+
# @example Adding the plugin to your Bridgetown Roda app
|
34
|
+
#
|
35
|
+
# class RodaApp < Bridgetown::Rack::Roda
|
36
|
+
# plugin :bridgetown_ssr
|
37
|
+
# plugin :bridgetown_deploy_hook
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# @param app [::Roda] the Roda application to configure
|
41
|
+
# @return [void]
|
42
|
+
def self.configure(app)
|
43
|
+
return unless app.opts[:bridgetown_site].nil?
|
44
|
+
|
45
|
+
# :nocov: Because it's difficult to set up multiple contexts
|
46
|
+
raise(
|
47
|
+
"Roda app failure: the bridgetown_ssr plugin must be registered before " \
|
48
|
+
"bridgetown_deploy_hook"
|
49
|
+
)
|
50
|
+
# :nocov:
|
51
|
+
end
|
52
|
+
|
53
|
+
# Methods included in to the Roda request
|
54
|
+
#
|
55
|
+
# @see http://roda.jeremyevans.net/rdoc/classes/Roda/RodaPlugins/Base/RequestMethods.html
|
56
|
+
module RequestMethods
|
57
|
+
# Builds the deploy hook route within the Roda application
|
58
|
+
#
|
59
|
+
# @since 0.1.0
|
60
|
+
# @api public
|
61
|
+
#
|
62
|
+
# @example Enabling the deploy hook route
|
63
|
+
#
|
64
|
+
# class RodaApp < Bridgetown::Rack::Roda
|
65
|
+
# plugin :bridgetown_ssr
|
66
|
+
# plugin :bridgetown_deploy_hook
|
67
|
+
#
|
68
|
+
# route do |r|
|
69
|
+
# r.bridgetown_deploy_hook
|
70
|
+
# end
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# @return [void]
|
74
|
+
def bridgetown_deploy_hook
|
75
|
+
site = roda_class.opts[:bridgetown_site]
|
76
|
+
config = site.config.deploy_hook
|
77
|
+
|
78
|
+
on(config.route) do
|
79
|
+
is do
|
80
|
+
authorization = Bridgetown::DeployHook::Authorization.new(
|
81
|
+
env["HTTP_AUTHORIZATION"],
|
82
|
+
config: config
|
83
|
+
)
|
84
|
+
|
85
|
+
response["Content-Type"] = "application/json"
|
86
|
+
|
87
|
+
if (authorized = authorization.call)
|
88
|
+
response.status = 200
|
89
|
+
response.write('{"status":"success"}')
|
90
|
+
else
|
91
|
+
response["WWW-Authenticate"] = config.authorization.keys
|
92
|
+
response.status = 401
|
93
|
+
|
94
|
+
response.write('{"status":"error","error":"unauthorized"}')
|
95
|
+
end
|
96
|
+
|
97
|
+
get do
|
98
|
+
Bridgetown::Hooks.trigger(:site, :post_deploy, site) if authorized
|
99
|
+
|
100
|
+
halt response.finish
|
101
|
+
end
|
102
|
+
|
103
|
+
head do
|
104
|
+
response.finish # to properly set the Content-Length header
|
105
|
+
halt response.finish_with_body(EMPTY_BODY)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
register_plugin :bridgetown_deploy_hook, BridgetownDeployHook
|
114
|
+
end
|
115
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bridgetown-deploy_hook
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Herold
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-03-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bridgetown
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.2'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: zeitwerk
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: bundler
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '2'
|
61
|
+
description: Add a Bridgetown hook triggered by HTTP for running post-deploy actions
|
62
|
+
email:
|
63
|
+
- opensource@michaeljherold.com
|
64
|
+
executables: []
|
65
|
+
extensions: []
|
66
|
+
extra_rdoc_files: []
|
67
|
+
files:
|
68
|
+
- CHANGELOG.md
|
69
|
+
- CONTRIBUTING.md
|
70
|
+
- LICENSE.md
|
71
|
+
- README.md
|
72
|
+
- bridgetown-deploy_hook.gemspec
|
73
|
+
- lib/bridgetown-deploy_hook.rb
|
74
|
+
- lib/bridgetown/deploy_hook/authorization.rb
|
75
|
+
- lib/bridgetown/deploy_hook/initializer.rb
|
76
|
+
- lib/bridgetown/deploy_hook/version.rb
|
77
|
+
- lib/roda/plugins/bridgetown_deploy_hook.rb
|
78
|
+
homepage: https://github.com/michaelherold/bridgetown-deploy_hook
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata:
|
82
|
+
bug_tracker_uri: https://github.com/michaelherold/bridgetown-deploy_hook/issues
|
83
|
+
changelog_uri: https://github.com/michaelherold/bridgetown-deploy_hook/blob/main/CHANGELOG.md
|
84
|
+
documentation_uri: https://rubydoc.info/gems/bridgetown-deploy_hook/0.1.0
|
85
|
+
homepage_uri: https://github.com/michaelherold/bridgetown-deploy_hook
|
86
|
+
rubygems_mfa_required: 'true'
|
87
|
+
source_code_uri: https://github.com/michaelherold/bridgetown-deploy_hook
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 3.0.0
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubygems_version: 3.2.32
|
104
|
+
signing_key:
|
105
|
+
specification_version: 4
|
106
|
+
summary: Add a Bridgetown hook triggered by HTTP for running post-deploy actions
|
107
|
+
test_files: []
|