jekyll-gitlab-letsencrypt 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fa8f3feb5f7a37e1c6d6dc0333149e93b3de8886
4
+ data.tar.gz: 41f642d68eb70f572c443d88065de1ee1cff3211
5
+ SHA512:
6
+ metadata.gz: 1e254b34b02b3791ec81a70e017ac13237b25fd98f0ac092e9dab70676d73730e497e3ebfe45d17c4b97cddc730a07e7f517ed6085e573d027514c061b6cbd6b
7
+ data.tar.gz: 86ea2abcec1da067c639d63b748a2a60cc6fa661c180de1a8fcd4f556d2e87ae4ed846b7e3b938034a57b49c4f496d79959f27ab8c054d560e015a1f55c7d5c3
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,7 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.1.0
5
+ - 2.2.0
6
+ - 2.3.3
7
+ before_install: gem install bundler --pre
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jekyll-gitlab-letsencrypt.gemspec
4
+ gemspec
@@ -0,0 +1,24 @@
1
+ The MIT License (MIT), with added prohibitions loosely based on http://neveragain.tech/
2
+
3
+ Copyright (c) 2017 Justin Aiken
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
+ - Use in any kind of the following use cases is expressly prohibited:
15
+ - Creation of databases of identifying information for the United States government to target individuals based on race, religion, or national origin.
16
+ - Collection and retention of data that would facilitate ethnic or religious targeting
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ THE SOFTWARE.
@@ -0,0 +1,126 @@
1
+ [![Build Status](http://img.shields.io/travis/JustinAiken/jekyll-gitlab-letsencrypt/master.svg)](http://travis-ci.org/JustinAiken/jekyll-gitlab-letsencrypt) [![Coveralls branch](http://img.shields.io/coveralls/JustinAiken/jekyll-gitlab-letsencrypt/master.svg)](https://coveralls.io/r/JustinAiken/jjekyll-gitlab-letsencrypt?branch=master) [![Code Climate](http://img.shields.io/codeclimate/github/JustinAiken/jekyll-gitlab-letsencrypt.svg)](https://codeclimate.com/github/JustinAiken/jekyll-gitlab-letsencrypt)
2
+
3
+ # jekyll-gitlab-letsencrypt
4
+
5
+ This plugin automagically does 90% of the letsencrypt process for your gitlab-hosted jekyll blog.
6
+
7
+ - *(automatic)* It registers your email to the letsencrypt server
8
+ - *(automatic)* It generates a challenge file, and commits it directly via the gitlab API
9
+ - *(automatic)* It sleeps until the challenge file is live on the internet
10
+ - *(automatic)* It asks letsencrypt to verify it
11
+ - *(automatic)* It spits out the certificate chain and private key
12
+ - *(manual)* You have to go to the URL provided and manually copy/paste them
13
+ - This step must be manual since there is no API through Gitlab for this step
14
+
15
+ ## Usage
16
+
17
+ ### Prerequisites
18
+
19
+ You must have:
20
+ - A jekyll blog
21
+ - Hosted on gitlab pages
22
+ - With a domain name set up and working
23
+ - Gitlab CI setup such that when you push to `master` (or your preferred branch), your changes are deployed live
24
+
25
+ Versions supported:
26
+ - Jekyll 3+
27
+ - Ruby 2.1+
28
+
29
+ ### Installation
30
+
31
+ - Add to your Gemfile:
32
+
33
+ ```ruby
34
+ group :jekyll_plugins do
35
+ gem 'jekyll-emojis'
36
+ gem 'jekyll-more-emojis'
37
+ ++ gem 'jekyll-gitlab-letsencrypt'
38
+ end
39
+ ```
40
+
41
+ and run `bundle install`
42
+
43
+ ## First-time Configuration
44
+
45
+ - Get a personal access token: https://gitlab.com/profile/personal_access_tokens
46
+
47
+ Add a `gitlab-letsencrypt` to your `_config.yml`:
48
+
49
+ ```yaml
50
+ gitlab-letsencrypt:
51
+ # Gitlab settings:
52
+ personal_access_token: 'MUCH SECRET' # Gotten from the step above ^^
53
+ gitlab_repo: 'gitlab_user/gitlab_repo' # Namespaced repository identifier
54
+
55
+ # Domain settings:
56
+ email: 'example@example.com' # Let's Encrypt email address
57
+ domain: 'example.com' # Domain that the cert will be issued for
58
+
59
+ # Jekyll settings:
60
+ base_path: './' # Where you want the file to go
61
+ pretty_url: false # Add a "/" on the end of the URL... set to `true` if you use permalink_style: pretty
62
+ filename: 'letsencrypt.html' # What to call the generated challenge file
63
+
64
+ # Delay settings:
65
+ initial_delay: 120 # How long to wait for Gitlab CI to push your changes before it starts checking
66
+ delay_time: 15 # How long to wait between each check once it starts looking for the file
67
+
68
+ # Optional settings you probably don't need:
69
+ endpoint: 'https://somewhere' # if you're doing the ACME thing outside of letsencrypt
70
+ branch: 'master' # Defaults to master, but you can use a different branch
71
+ layout: 'null' # Layout to use for challenge file - defaults to null, but you can change if needed
72
+ ```
73
+
74
+ ### Running
75
+
76
+ - Just type `jekyll letsencrypt`
77
+
78
+ ```shell
79
+ $ jekyll letsencrypt
80
+ Registering example@example.com to https://acme-v01.api.letsencrypt.org/...
81
+ Pushing file to Gitlab
82
+ Commiting challenge file as lets.html
83
+ Done Commiting! Check https://gitlab.com/gitlab_user/gitlab_repo/commits/master
84
+ Going to check http://example.com/.well-known/acme-challenge/lots_of_numbers/ for the challenge to be present...
85
+ Waiting 120 seconds before we start checking for challenge..
86
+ Got response code 404, waiting 15 seconds...
87
+ Got response code 404, waiting 15 seconds...
88
+ Got response code 200, file is present!
89
+ Requesting verification...
90
+ Challenge status = valid
91
+ Challenge is valid!
92
+ Certificate retrieved!
93
+ Go to https://gitlab.com/gitlab_user/gitlab_repo/pages
94
+ - If you already have an existing entry for example.com, remove it
95
+ - Then click + New Domain and enter the following:
96
+
97
+ Domain: example.com
98
+
99
+ Certificate (PEM):
100
+ -----BEGIN CERTIFICATE-----
101
+ ...
102
+ -----END CERTIFICATE-----
103
+ -----BEGIN CERTIFICATE-----
104
+ ...
105
+ -----END CERTIFICATE-----
106
+
107
+ Key (PEM):
108
+ -----BEGIN RSA PRIVATE KEY-----
109
+ ...
110
+ -----END RSA PRIVATE KEY-----
111
+
112
+
113
+
114
+
115
+ ... hit save, wait a bit, and your new SSL will be live!
116
+ ```
117
+
118
+ # License
119
+
120
+ MIT
121
+
122
+ # Credits/thanks
123
+
124
+ - :heart: Gitlab for free page hosting, free repos, and free CI!
125
+ - :heart: the Jekyll team for the easy-to-use blogging engine!
126
+ - Inspired by the excellent [gitlab-letsencrypt](https://github.com/rolodato/gitlab-letsencrypt) npm package.
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new :spec
5
+
6
+ task default: :spec
@@ -0,0 +1,28 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'jekyll/gitlab/letsencrypt/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "jekyll-gitlab-letsencrypt"
7
+ spec.version = Jekyll::Gitlab::Letsencrypt::VERSION
8
+ spec.authors = ["Justin Aiken"]
9
+ spec.email = ["60tonangel@gmail.com"]
10
+
11
+ spec.summary = %q{Automate letsencrypt renewals for gitlab pages.}
12
+ spec.description = %q{Automate letsencrypt renewals for gitlab pages.}
13
+ spec.homepage = "https://github.com/JustinAiken/jekyll-gitlab-letsencrypt"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match %r{^(spec)/} }
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler", ">= 1.13"
20
+ spec.add_development_dependency "rake", ">= 10.0"
21
+ spec.add_development_dependency "rspec", "~> 3.0"
22
+ spec.add_development_dependency "jekyll", ">= 3.0"
23
+ spec.add_development_dependency "vcr", "~> 3.0.3"
24
+ spec.add_development_dependency "coveralls"
25
+
26
+ spec.add_dependency "activesupport", ">= 3.0.0"
27
+ spec.add_dependency "acme-client", "~> 0.5.0"
28
+ end
@@ -0,0 +1,17 @@
1
+ module Jekyll
2
+ module Commands
3
+ module Gitlab
4
+ class Letsencrypt < ::Jekyll::Command
5
+ def self.init_with_program(prog)
6
+ prog.command(:letsencrypt) do |c|
7
+ c.description "Setup/Renew letsencrypt certificate"
8
+
9
+ c.action do |_args, _opts|
10
+ Jekyll::Gitlab::Letsencrypt::Process.process!
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext/module/delegation'
3
+
4
+ require 'jekyll/gitlab/letsencrypt/version'
5
+ require 'jekyll/gitlab/letsencrypt/configuration'
6
+ require 'jekyll/gitlab/letsencrypt/acme'
7
+ require 'jekyll/gitlab/letsencrypt/process'
8
+ require 'jekyll/gitlab/letsencrypt/committer'
9
+
10
+ module Jekyll
11
+ module Gitlab
12
+ module Letsencrypt
13
+ end
14
+ end
15
+ end
16
+
17
+ require 'jekyll/commands/gitlab/letsencrypt'
@@ -0,0 +1,43 @@
1
+ require 'openssl'
2
+ require 'acme-client'
3
+
4
+ module Jekyll
5
+ module Gitlab
6
+ module Letsencrypt
7
+ class Acme
8
+
9
+ delegate :email, :endpoint, :domain, to: Configuration
10
+
11
+ attr_accessor :registration
12
+
13
+ def register!
14
+ Jekyll.logger.info "Registering #{email} to #{endpoint}..."
15
+ @registration = client.register contact: "mailto:#{email}"
16
+ @registration.agree_terms
17
+ self
18
+ end
19
+
20
+ def authorized?
21
+ authorization.status == 'valid'
22
+ end
23
+
24
+ def challenge
25
+ @challenge ||= authorization.http01
26
+ end
27
+
28
+ def client
29
+ @client ||= begin
30
+ private_key = OpenSSL::PKey::RSA.new(4096)
31
+ ::Acme::Client.new private_key: private_key, endpoint: endpoint, connection_options: { request: { open_timeout: 5, timeout: 5 } }
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def authorization
38
+ @authorization ||= client.authorize(domain: domain)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,76 @@
1
+ require 'faraday'
2
+
3
+ module Jekyll
4
+ module Gitlab
5
+ module Letsencrypt
6
+ class Commiter
7
+
8
+ attr_accessor :content
9
+
10
+ delegate :filename, :personal_access_token, :gitlab_repo, :branch, to: Configuration
11
+
12
+ def initialize(content)
13
+ @content = content
14
+ end
15
+
16
+ def commit!
17
+ create_branch! unless branch_exists?
18
+ commit_file!
19
+ end
20
+
21
+ def create_branch!
22
+ Jekyll.logger.info "Creating branch #{branch}.."
23
+ connection.post do |req|
24
+ req.url "projects/#{repo_id}/repository/branches"
25
+ req.body = {
26
+ branch_name: branch,
27
+ ref: 'master'
28
+ }.to_json
29
+ end
30
+ end
31
+
32
+ def commit_file!
33
+ Jekyll.logger.info "Commiting challenge file as #{filename}"
34
+ connection.run_request(request_method, nil, nil, nil) do |req|
35
+ req.url "projects/#{repo_id}/repository/files"
36
+ req.body = {
37
+ file_path: filename,
38
+ commit_message: "Automated Let's Encrypt renewal",
39
+ branch_name: branch,
40
+ content: content
41
+ }.to_json
42
+ end
43
+ Jekyll.logger.info "Done Commiting! Check https://gitlab.com/#{gitlab_repo}/commits/#{branch}"
44
+ end
45
+
46
+ private
47
+
48
+ def branch_exists?
49
+ response = connection.get "projects/#{repo_id}/repository/branches"
50
+ JSON.parse(response.body).any? { |json| json['name'] == branch }
51
+ end
52
+
53
+ def request_method
54
+ response = connection.get "projects/#{repo_id}/repository/files?ref=#{branch}&file_path=#{filename}"
55
+ response.status == 404 ? :post : :put
56
+ end
57
+
58
+ def repo_id
59
+ @repo_id ||= begin
60
+ repo_name = gitlab_repo.gsub "/", "%2f"
61
+ response = connection.get "projects/#{repo_name}"
62
+ JSON.parse(response.body)['id']
63
+ end
64
+ end
65
+
66
+ def connection
67
+ @connection ||= Faraday.new(url: 'https://gitlab.com/api/v3/') do |faraday|
68
+ faraday.adapter Faraday.default_adapter
69
+ faraday.headers['Content-Type'] = 'application/json'
70
+ faraday.headers['PRIVATE-TOKEN'] = personal_access_token
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,80 @@
1
+ module Jekyll
2
+ module Gitlab
3
+ module Letsencrypt
4
+ class Configuration
5
+
6
+ DEFAULT_FILENAME = 'letsencrypt_challenge.html'
7
+ DEFAULT_ENDPOINT = 'https://acme-v01.api.letsencrypt.org/'
8
+ DEFAULT_BRANCH = 'master'
9
+ DEFAULT_LAYOUT = 'null'
10
+ DEFAULT_INITIAL_DELAY = 120
11
+ DEFAULT_DELAY_TIME = 15
12
+
13
+ REQUIRED_KEYS = %w{gitlab_repo personal_access_token email domain}
14
+
15
+ class << self
16
+
17
+ def valid?
18
+ REQUIRED_KEYS.all? { |key| jekyll_config.has_key? key }
19
+ end
20
+
21
+ def endpoint
22
+ jekyll_config['endpoint'] || DEFAULT_ENDPOINT
23
+ end
24
+
25
+ def gitlab_repo
26
+ jekyll_config['gitlab_repo']
27
+ end
28
+
29
+ def base_path
30
+ jekyll_config['base_path'] || ''
31
+ end
32
+
33
+ def pretty_url?
34
+ !!jekyll_config['pretty_url']
35
+ end
36
+
37
+ def layout
38
+ jekyll_config['layout'] || DEFAULT_LAYOUT
39
+ end
40
+
41
+ def personal_access_token
42
+ jekyll_config['personal_access_token']
43
+ end
44
+
45
+ def email
46
+ jekyll_config['email']
47
+ end
48
+
49
+ def domain
50
+ jekyll_config['domain']
51
+ end
52
+
53
+ def branch
54
+ jekyll_config['branch'] || DEFAULT_BRANCH
55
+ end
56
+
57
+ def filename
58
+ jekyll_config['filename'] || DEFAULT_FILENAME
59
+ end
60
+
61
+ def initial_delay
62
+ jekyll_config['initial_delay'] || DEFAULT_INITIAL_DELAY
63
+ end
64
+
65
+ def delay_time
66
+ jekyll_config['delay_time'] || DEFAULT_DELAY_TIME
67
+ end
68
+
69
+ def reset!
70
+ @jekyll_config = nil
71
+ end
72
+
73
+ def jekyll_config
74
+ @jekyll_config ||= (Jekyll.configuration({})['gitlab-letsencrypt'] || {})
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,130 @@
1
+ require 'faraday'
2
+
3
+ module Jekyll
4
+ module Gitlab
5
+ module Letsencrypt
6
+ class Process
7
+
8
+ attr_accessor :client
9
+
10
+ def self.process!
11
+ client = Acme.new.register!
12
+ self.new(client).process!
13
+ end
14
+
15
+ delegate :base_path, :gitlab_repo, :pretty_url?, :layout, :domain, :initial_delay, :delay_time, to: Configuration
16
+
17
+ def initialize(client)
18
+ @client = client
19
+ end
20
+
21
+ def process!
22
+ Jekyll.logger.abort_with "Client is already authorized." if client.authorized?
23
+
24
+ commit_to_gitlab!
25
+ wait_until_challenge_is_present
26
+ request_verification!
27
+ await_verification_confirmation
28
+ display_certificate
29
+ end
30
+
31
+ private
32
+
33
+ def commit_to_gitlab!
34
+ Jekyll.logger.info "Pushing file to Gitlab"
35
+ Commiter.new(challenge_content).commit!
36
+ end
37
+
38
+ def wait_until_challenge_is_present
39
+ Jekyll.logger.info "Going to check #{challenge_url} for the challenge to be present..."
40
+ Jekyll.logger.info "Waiting #{initial_delay} seconds before we start checking for challenge.."
41
+ sleep initial_delay
42
+
43
+ loop do
44
+ response = Faraday.get challenge_url
45
+ if response.success?
46
+ Jekyll.logger.info "Got response code #{response.status}, file is present!"
47
+ return
48
+ end
49
+ Jekyll.logger.info "Got response code #{response.status}, waiting #{delay_time} seconds..."
50
+ sleep delay_time
51
+ end
52
+ end
53
+
54
+ def request_verification!
55
+ Jekyll.logger.info "Requesting verification..."
56
+ challenge.request_verification
57
+ end
58
+
59
+ def await_verification_confirmation
60
+ tries = 0
61
+ loop do
62
+ tries = tries + 1
63
+ if challenge.authorization.verify_status == 'valid'
64
+ Jekyll.logger.info "Challenge is valid!"
65
+ return
66
+ end
67
+ Jekyll.logger.info "Challenge status = #{challenge.authorization.verify_status}"
68
+ Jekyll.logger.abort_with "Challenge failed to verify" if tries >= 3
69
+ sleep delay_time
70
+ end
71
+ end
72
+
73
+ def display_certificate
74
+ Jekyll.logger.info "Certifcate retrieved!"
75
+ Jekyll.logger.info "Go to https://gitlab.com/#{gitlab_repo}/pages"
76
+ Jekyll.logger.info " - If you already have an existing entry for #{domain}, remove it"
77
+ Jekyll.logger.info " - Then click + New Domain and enter the following:"
78
+ Jekyll.logger.info ""
79
+ Jekyll.logger.info "Domain: #{domain}"
80
+ Jekyll.logger.info ""
81
+ Jekyll.logger.info "Certificate (PEM): "
82
+ Jekyll.logger.info certificate.fullchain_to_pem
83
+ Jekyll.logger.info "\n"
84
+ Jekyll.logger.info "Key (PEM): "
85
+ Jekyll.logger.info certificate.request.private_key.to_pem
86
+ Jekyll.logger.info ""
87
+ Jekyll.logger.info ""
88
+ Jekyll.logger.info "... hit save, wait a bit, and your new SSL will be live!"
89
+ end
90
+
91
+ def challenge_content
92
+ permalink = ""
93
+ permalink += base_path if base_path
94
+ permalink += challenge.filename
95
+ permalink += "/" if pretty_url?
96
+
97
+ content = "---\n"
98
+ content += "layout: #{layout}\n"
99
+ content += "permalink: #{permalink}\n"
100
+ content += "---\n"
101
+ content += "\n"
102
+ content += challenge.file_content
103
+ content += "\n"
104
+
105
+ content
106
+ end
107
+
108
+ def challenge_url
109
+ @challenge_url ||= begin
110
+ url = "http://#{domain}/"
111
+ url += challenge.filename
112
+ url += "/" if pretty_url?
113
+ url
114
+ end
115
+ end
116
+
117
+ def challenge
118
+ @challenge ||= client.challenge
119
+ end
120
+
121
+ def certificate
122
+ @certificate ||= begin
123
+ csr = ::Acme::Client::CertificateRequest.new names: Array(domain)
124
+ client.client.new_certificate csr
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,7 @@
1
+ module Jekyll
2
+ module Gitlab
3
+ module Letsencrypt
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-gitlab-letsencrypt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Justin Aiken
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-02-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '10.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: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: jekyll
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: vcr
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 3.0.3
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 3.0.3
83
+ - !ruby/object:Gem::Dependency
84
+ name: coveralls
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activesupport
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 3.0.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 3.0.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: acme-client
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.5.0
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.5.0
125
+ description: Automate letsencrypt renewals for gitlab pages.
126
+ email:
127
+ - 60tonangel@gmail.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".rspec"
134
+ - ".travis.yml"
135
+ - Gemfile
136
+ - LICENSE.txt
137
+ - README.md
138
+ - Rakefile
139
+ - jekyll-gitlab-letsencrypt.gemspec
140
+ - lib/jekyll/commands/gitlab/letsencrypt.rb
141
+ - lib/jekyll/gitlab/letsencrypt.rb
142
+ - lib/jekyll/gitlab/letsencrypt/acme.rb
143
+ - lib/jekyll/gitlab/letsencrypt/committer.rb
144
+ - lib/jekyll/gitlab/letsencrypt/configuration.rb
145
+ - lib/jekyll/gitlab/letsencrypt/process.rb
146
+ - lib/jekyll/gitlab/letsencrypt/version.rb
147
+ homepage: https://github.com/JustinAiken/jekyll-gitlab-letsencrypt
148
+ licenses:
149
+ - MIT
150
+ metadata: {}
151
+ post_install_message:
152
+ rdoc_options: []
153
+ require_paths:
154
+ - lib
155
+ required_ruby_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ required_rubygems_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ requirements: []
166
+ rubyforge_project:
167
+ rubygems_version: 2.6.6
168
+ signing_key:
169
+ specification_version: 4
170
+ summary: Automate letsencrypt renewals for gitlab pages.
171
+ test_files: []