handsome_fencer-circle_c_i 0.1.5
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +27 -0
- data/lib/generators/handsome_fencer.rb +3 -0
- data/lib/generators/handsome_fencer/circle_c_i/deploy_key_generator.rb +18 -0
- data/lib/generators/handsome_fencer/circle_c_i/exposed_env_files_generator.rb +15 -0
- data/lib/generators/handsome_fencer/circle_c_i/install_generator.rb +28 -0
- data/lib/generators/handsome_fencer/circle_c_i/obfuscated_env_files_generator.rb +15 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/circle.env +9 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/config.yml +62 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/Dockerfile +11 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/development.env +9 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/production.env +9 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/database/development.env +2 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/web/production.env +9 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/expose_env.rb +3 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/obfuscate_env.rb +3 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/docker-compose.yml +77 -0
- data/lib/generators/handsome_fencer/circle_c_i/templates/lib/tasks/deploy.rake +99 -0
- data/lib/handsome_fencer/circle_c_i.rb +8 -0
- data/lib/handsome_fencer/circle_c_i/crypto.rb +93 -0
- data/lib/handsome_fencer/circle_c_i/railtie.rb +9 -0
- data/lib/handsome_fencer/circle_c_i/version.rb +5 -0
- data/lib/tasks/handsome_fencer/circle_c_i_tasks.rake +17 -0
- metadata +139 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7f1b79823feff3fab032cdd6fd7d10e0638454b4adb5d872427061e774dd804b
|
4
|
+
data.tar.gz: f119c0cec97a44590213de00d00f731a2104f9113fa4fb709ae3d061fa707c57
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d25c45549f31e162fa7e3ed44b054afb6dfeb74787128b8031857ad2e237191ec7256c3a840e6db1e356b352ccef3653571404b57e540188fbbd30e59a12161c
|
7
|
+
data.tar.gz: 970a3754ef7d647b9bbc3d693dcc78c58f39b13ec5e2698877514388c31a9cd72f8b4f84bb4ea3387c9927f89c5653ae0cde8f4697d67f3dbc61d4f4af694d6b
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2018 schadenfred
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# HandsomeFencer::CircleCI
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'handsome_fencer-circle_c_i'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install handsome_fencer-circle_c_i
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'HandsomeFencer::CircleCI'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'bundler/gem_tasks'
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
|
21
|
+
Rake::TestTask.new(:test) do |t|
|
22
|
+
t.libs << 'test'
|
23
|
+
t.pattern = 'test/**/*_test.rb'
|
24
|
+
t.verbose = false
|
25
|
+
end
|
26
|
+
|
27
|
+
task default: :test
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'handsome_fencer/circle_c_i/crypto'
|
2
|
+
module HandsomeFencer
|
3
|
+
module CircleCI
|
4
|
+
|
5
|
+
class DeployKeyGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
desc "generate deploy key"
|
8
|
+
|
9
|
+
def generate_deploy_key
|
10
|
+
@cipher = OpenSSL::Cipher.new 'AES-128-CBC'
|
11
|
+
@salt = '8 octets'
|
12
|
+
@new_key = @cipher.random_key
|
13
|
+
|
14
|
+
create_file ".circleci/deploy.key", Base64.encode64(@new_key)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'handsome_fencer/circle_c_i/crypto'
|
2
|
+
module HandsomeFencer
|
3
|
+
module CircleCI
|
4
|
+
|
5
|
+
class ExposedEnvFilesGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
desc "expose .env files inside .circleci directory"
|
8
|
+
|
9
|
+
def expose_env_files
|
10
|
+
@cipher = HandsomeFencer::CircleCI::Crypto.new
|
11
|
+
@cipher.expose
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'handsome_fencer/circle_c_i/crypto'
|
2
|
+
module HandsomeFencer
|
3
|
+
module CircleCI
|
4
|
+
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
desc "Sets up some necessary files for continuous deployments using docker and CircleCI"
|
8
|
+
|
9
|
+
def copy_circle_templates
|
10
|
+
directory "circleci", ".circleci", recursive: true
|
11
|
+
end
|
12
|
+
|
13
|
+
def copy_deploy_task
|
14
|
+
directory 'lib/', 'lib', recursive: true
|
15
|
+
end
|
16
|
+
|
17
|
+
def copy_docker_compose
|
18
|
+
copy_file "docker-compose.yml", "docker-compose.yml"
|
19
|
+
end
|
20
|
+
|
21
|
+
def insert_gitignores
|
22
|
+
create_file '.gitignore' if File.exist? '.gitignore'
|
23
|
+
append_to_file '.gitignore', "\n.circleci/**/*.env"
|
24
|
+
append_to_file '.gitignore', "\n.circleci/**/*.key"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'handsome_fencer/circle_c_i/crypto'
|
2
|
+
module HandsomeFencer
|
3
|
+
module CircleCI
|
4
|
+
|
5
|
+
class ObfuscatedEnvFilesGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
desc "obfuscate .env files inside .circleci directory"
|
8
|
+
|
9
|
+
def obfuscate_env_files
|
10
|
+
@cipher = HandsomeFencer::CircleCI::Crypto.new
|
11
|
+
@cipher.obfuscate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
export DOCKERHUB_PASS="set me"
|
2
|
+
export DOCKERHUB_EMAIL="set me"
|
3
|
+
export DOCKERHUB_USER="set me"
|
4
|
+
export PUSH_DEPLOY_TAG=${CIRCLE_PREVIOUS_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
5
|
+
export DEPLOY_TAG=${CIRCLE_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
6
|
+
export DEPLOY_PATH="name of our app"
|
7
|
+
export SERVER_HOST="server ip address"
|
8
|
+
export SERVER_USER="probably root"
|
9
|
+
export SERVER_PORT="probably 22"
|
@@ -0,0 +1,62 @@
|
|
1
|
+
defaults: &defaults
|
2
|
+
working_directory: /tmp
|
3
|
+
|
4
|
+
version: 2
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
|
8
|
+
build:
|
9
|
+
machine: true
|
10
|
+
steps:
|
11
|
+
- checkout
|
12
|
+
- run: gem install handsomefencer-environment
|
13
|
+
- run: ruby expose_env.rb
|
14
|
+
- run: docker-compose build dev_app database
|
15
|
+
- run: docker-compose run dev_app bin/rails db:create db:migrate test
|
16
|
+
|
17
|
+
push:
|
18
|
+
docker:
|
19
|
+
- image: circleci/ruby:2.5.1-node-browsers
|
20
|
+
environment:
|
21
|
+
BASH_ENV: .env/circle/deploy.env
|
22
|
+
steps:
|
23
|
+
- checkout
|
24
|
+
- setup_remote_docker
|
25
|
+
- run: gem install handsomefencer-environment
|
26
|
+
- run: ruby expose_env.rb
|
27
|
+
- run: docker-compose up -d --build
|
28
|
+
- run:
|
29
|
+
name: Tag web image
|
30
|
+
command: docker tag $(docker images | grep project_web | awk '{ print $3 }') rennmappe/bacchanal_web:$DEPLOY_TAG
|
31
|
+
- run: docker login -u $DOCKERHUB_USER -p $DOCKERHUB_PASS
|
32
|
+
- run: docker push rennmappe/bacchanal_web:$DEPLOY_TAG
|
33
|
+
|
34
|
+
deploy:
|
35
|
+
docker:
|
36
|
+
- image: circleci/ruby:2.5.1-node-browsers
|
37
|
+
environment:
|
38
|
+
BASH_ENV: .env/circle/deploy.env
|
39
|
+
steps:
|
40
|
+
- checkout
|
41
|
+
- add_ssh_keys
|
42
|
+
- run: bundle install --without production
|
43
|
+
- run: ruby expose_env.rb
|
44
|
+
- run: bin/rails docker:deploy
|
45
|
+
|
46
|
+
workflows:
|
47
|
+
version: 2
|
48
|
+
build-and-deploy:
|
49
|
+
jobs:
|
50
|
+
- build
|
51
|
+
- push:
|
52
|
+
requires:
|
53
|
+
- build
|
54
|
+
filters:
|
55
|
+
branches:
|
56
|
+
only: master
|
57
|
+
- deploy:
|
58
|
+
requires:
|
59
|
+
- push
|
60
|
+
filters:
|
61
|
+
branches:
|
62
|
+
only: master
|
@@ -0,0 +1,11 @@
|
|
1
|
+
FROM ruby:2.5-alpine
|
2
|
+
|
3
|
+
LABEL maintainer="your-email-here@gmail.com"
|
4
|
+
|
5
|
+
RUN apk add --no-cache --update build-base linux-headers \
|
6
|
+
postgresql-dev nodejs tzdata libxml2-dev libxslt-dev
|
7
|
+
|
8
|
+
COPY Gemfile* /usr/src/app/
|
9
|
+
WORKDIR /usr/src/app
|
10
|
+
RUN bundle install
|
11
|
+
COPY . /usr/src/app/
|
data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/development.env
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
export DOCKERHUB_PASS="set me"
|
2
|
+
export DOCKERHUB_EMAIL="set me"
|
3
|
+
export DOCKERHUB_USER="set me"
|
4
|
+
export PUSH_DEPLOY_TAG=${CIRCLE_PREVIOUS_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
5
|
+
export DEPLOY_TAG=${CIRCLE_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
6
|
+
export DEPLOY_PATH="name of our app"
|
7
|
+
export SERVER_HOST="server ip address"
|
8
|
+
export SERVER_USER="probably root"
|
9
|
+
export SERVER_PORT="probably 22"
|
data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/production.env
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
export DOCKERHUB_PASS="set me"
|
2
|
+
export DOCKERHUB_EMAIL="set me"
|
3
|
+
export DOCKERHUB_USER="set me"
|
4
|
+
export PUSH_DEPLOY_TAG=${CIRCLE_PREVIOUS_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
5
|
+
export DEPLOY_TAG=${CIRCLE_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
6
|
+
export DEPLOY_PATH="name of our app"
|
7
|
+
export SERVER_HOST="server ip address"
|
8
|
+
export SERVER_USER="probably root"
|
9
|
+
export SERVER_PORT="probably 22"
|
data/lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/web/production.env
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
export DOCKERHUB_PASS="set me"
|
2
|
+
export DOCKERHUB_EMAIL="set me"
|
3
|
+
export DOCKERHUB_USER="set me"
|
4
|
+
export PUSH_DEPLOY_TAG=${CIRCLE_PREVIOUS_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
5
|
+
export DEPLOY_TAG=${CIRCLE_BUILD_NUM}_${CIRCLE_SHA1:0:7}
|
6
|
+
export DEPLOY_PATH="name of our app"
|
7
|
+
export SERVER_HOST="server ip address"
|
8
|
+
export SERVER_USER="probably root"
|
9
|
+
export SERVER_PORT="probably 22"
|
@@ -0,0 +1,77 @@
|
|
1
|
+
version: '3.1'
|
2
|
+
|
3
|
+
services:
|
4
|
+
|
5
|
+
dev_app:
|
6
|
+
build:
|
7
|
+
context: .
|
8
|
+
dockerfile: ./docker/app/Dockerfile
|
9
|
+
|
10
|
+
depends_on:
|
11
|
+
- database
|
12
|
+
ports:
|
13
|
+
- "35729:35729"
|
14
|
+
- "3000:3000"
|
15
|
+
volumes:
|
16
|
+
- .:/usr/src/app
|
17
|
+
- gem_cache:/gems
|
18
|
+
env_file:
|
19
|
+
- .env/development/database.env
|
20
|
+
- .env/development/app.env
|
21
|
+
command: [ "bin/rails", "s" ]
|
22
|
+
|
23
|
+
stdin_open: true
|
24
|
+
tty: true
|
25
|
+
secrets:
|
26
|
+
- host_ssh_key
|
27
|
+
|
28
|
+
app:
|
29
|
+
|
30
|
+
build:
|
31
|
+
context: .
|
32
|
+
dockerfile: ./docker/app/Dockerfile
|
33
|
+
|
34
|
+
depends_on:
|
35
|
+
- database
|
36
|
+
ports:
|
37
|
+
- "3000:3000"
|
38
|
+
volumes:
|
39
|
+
- .:/usr/src/app
|
40
|
+
- gem_cache:/gems
|
41
|
+
environment:
|
42
|
+
- RAILS_ENV=production
|
43
|
+
env_file:
|
44
|
+
- .env/development/database.env
|
45
|
+
- .env/development/app.env
|
46
|
+
|
47
|
+
command: [ "bundle", "exec", "puma", "-C", "config/puma.rb" ]
|
48
|
+
|
49
|
+
secrets:
|
50
|
+
- host_ssh_key
|
51
|
+
|
52
|
+
web:
|
53
|
+
build:
|
54
|
+
context: .
|
55
|
+
dockerfile: ./docker/web/Dockerfile
|
56
|
+
command: [ "nginx", "-g", "daemon off;" ]
|
57
|
+
|
58
|
+
depends_on:
|
59
|
+
- app
|
60
|
+
expose:
|
61
|
+
- 80
|
62
|
+
|
63
|
+
database:
|
64
|
+
image: postgres
|
65
|
+
env_file:
|
66
|
+
- .env/development/database.env
|
67
|
+
|
68
|
+
volumes:
|
69
|
+
- db-data:/var/lib/postgresql/data
|
70
|
+
|
71
|
+
volumes:
|
72
|
+
db-data:
|
73
|
+
gem_cache:
|
74
|
+
|
75
|
+
secrets:
|
76
|
+
host_ssh_key:
|
77
|
+
file: ~/.ssh/id_rsa
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# use SSHKit directly instead of Capistrano
|
2
|
+
require 'sshkit'
|
3
|
+
require 'sshkit/dsl'
|
4
|
+
include SSHKit::DSL
|
5
|
+
|
6
|
+
deploy_tag = ENV['DEPLOY_TAG']
|
7
|
+
hostname = ENV['SERVER_HOST']
|
8
|
+
user = ENV['SERVER_USER']
|
9
|
+
dockerhub_user = ENV['DOCKERHUB_USER']
|
10
|
+
dockerhub_pass = ENV['DOCKERHUB_PASS']
|
11
|
+
port = ENV['SERVER_PORT']
|
12
|
+
deploy_env = ENV['DEPLOY_ENV'] || :production
|
13
|
+
deploy_path = ENV['DEPLOY_PATH']
|
14
|
+
|
15
|
+
server = SSHKit::Host.new(hostname: hostname, port: port, user: user)
|
16
|
+
|
17
|
+
namespace :deploy do
|
18
|
+
|
19
|
+
desc 'copy to server files needed to run and manage Docker containers'
|
20
|
+
|
21
|
+
task :configs do
|
22
|
+
|
23
|
+
on server do
|
24
|
+
within deploy_path do
|
25
|
+
upload! File.expand_path('../../config/containers/docker-compose.yml', __dir__), '.'
|
26
|
+
upload! File.expand_path('../../.env', __dir__), '.', recursive: true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
namespace :docker do
|
34
|
+
|
35
|
+
desc 'logs into Docker Hub for pushing and pulling'
|
36
|
+
|
37
|
+
task :login do
|
38
|
+
on server do
|
39
|
+
execute "mkdir -p #{deploy_path}"
|
40
|
+
within deploy_path do
|
41
|
+
execute 'docker', 'login', '-u', dockerhub_user, '-p', dockerhub_pass
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
desc 'stops all Docker containers via Docker Compose'
|
47
|
+
|
48
|
+
task stop: 'deploy:configs' do
|
49
|
+
on server do
|
50
|
+
within deploy_path do
|
51
|
+
with rails_env: deploy_env, deploy_tag: deploy_tag do
|
52
|
+
execute 'docker-compose', 'stop'
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
desc 'starts all Docker containers via Docker Compose'
|
60
|
+
|
61
|
+
task start: 'deploy:configs' do
|
62
|
+
on server do
|
63
|
+
within deploy_path do
|
64
|
+
with rails_env: deploy_env, deploy_tag: deploy_tag do
|
65
|
+
execute 'docker-compose', 'up', '-d'
|
66
|
+
execute 'echo', deploy_tag , '>', 'deploy.tag'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'pulls images from Docker Hub'
|
73
|
+
|
74
|
+
task pull: 'docker:login' do
|
75
|
+
on server do
|
76
|
+
within deploy_path do
|
77
|
+
["#{deploy_path}_app", "#{deploy_path}_web"].each do |image_name|
|
78
|
+
execute 'docker', 'pull', "rennmappe/#{image_name}:#{deploy_tag}"
|
79
|
+
end
|
80
|
+
execute 'docker', 'pull', 'postgres:9.4.5'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
desc 'runs database migrations in application container via Docker Compose'
|
87
|
+
task migrate: 'deploy:configs' do
|
88
|
+
on server do
|
89
|
+
within deploy_path do
|
90
|
+
with rails_env: deploy_env, deploy_tag: deploy_tag do
|
91
|
+
execute 'docker-compose', 'run', 'app', "bin/rails", 'db:create', 'db:migrate'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
desc 'pulls images, stops old containers, updates the database, and starts new containers'
|
98
|
+
task deploy: %w{docker:pull docker:stop docker:migrate docker:start }
|
99
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'base64'
|
3
|
+
require 'byebug'
|
4
|
+
|
5
|
+
module HandsomeFencer
|
6
|
+
module CircleCI
|
7
|
+
class Crypto
|
8
|
+
|
9
|
+
DeployKeyError = Class.new(StandardError)
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@cipher = OpenSSL::Cipher.new 'AES-128-CBC'
|
13
|
+
@salt = '8 octets'
|
14
|
+
@pass_phrase = get_deploy_key
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_deploy_key
|
18
|
+
case
|
19
|
+
when ENV['DEPLOY_KEY'].nil? && !File.exist?(dkfile)
|
20
|
+
raise DeployKeyError, "No deploy key set. Please generate a deploy key using '$ bin/rails generate handsome_fencer:circle_c_i:deploy_key' or set it using '$ export ENV['DEPLOY_KEY'] = some-complicated-key'"
|
21
|
+
when ENV['DEPLOY_KEY'].present?
|
22
|
+
Base64.decode64(ENV['DEPLOY_KEY'])
|
23
|
+
when File.exist?(dkfile)
|
24
|
+
Base64.decode64(File.read(dkfile))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def read_deploy_key
|
29
|
+
File.exist?(dkfile) ? File.read(dkfile) : save_deploy_key
|
30
|
+
end
|
31
|
+
|
32
|
+
def save_deploy_key
|
33
|
+
|
34
|
+
@new_key = @cipher.random_key
|
35
|
+
|
36
|
+
write_to_file Base64.encode64(@new_key), dkfile
|
37
|
+
# ignore_sensitive_files
|
38
|
+
read_deploy_key
|
39
|
+
end
|
40
|
+
|
41
|
+
def ignore_sensitive_files
|
42
|
+
if File.exist? '.gitignore'
|
43
|
+
["/#{dkfile}", "/.env/*"].each do |pattern|
|
44
|
+
unless File.read('.gitignore').match pattern
|
45
|
+
open('.gitignore', 'a') { |f| f << pattern }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def encrypt(file)
|
52
|
+
file = Rails.root.join(file).to_s
|
53
|
+
@cipher.encrypt.pkcs5_keyivgen @pass_phrase, @salt
|
54
|
+
encrypted = @cipher.update(File.read file) + @cipher.final
|
55
|
+
write_to_file(Base64.encode64(encrypted), file + '.enc')
|
56
|
+
end
|
57
|
+
|
58
|
+
def decrypt(file)
|
59
|
+
encrypted = Base64.decode64 File.read(file.to_s)
|
60
|
+
@cipher.decrypt.pkcs5_keyivgen @pass_phrase, @salt
|
61
|
+
decrypted = @cipher.update(encrypted) + @cipher.final
|
62
|
+
decrypted_file = file.split('.enc').first
|
63
|
+
write_to_file decrypted, decrypted_file
|
64
|
+
end
|
65
|
+
|
66
|
+
def source_files(directory=nil, extension=nil)
|
67
|
+
Dir.glob(directory + "/**/*#{extension}")
|
68
|
+
end
|
69
|
+
|
70
|
+
def obfuscate(directory=nil, extension=nil)
|
71
|
+
extension = extension || '.env'
|
72
|
+
directory = directory || '.circleci'
|
73
|
+
source_files(directory, extension).each { |file| encrypt file }
|
74
|
+
end
|
75
|
+
|
76
|
+
def expose(directory=nil, extension=nil)
|
77
|
+
extension = extension || '.env.enc'
|
78
|
+
directory = directory || '.circleci'
|
79
|
+
source_files(directory, extension).each { |file| decrypt(file) }
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def dkfile
|
85
|
+
".circleci/deploy.key"
|
86
|
+
end
|
87
|
+
|
88
|
+
def write_to_file(data, filename)
|
89
|
+
File.open(filename, "w") { |io| io.write data }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
namespace "handsome_fencer" do
|
2
|
+
|
3
|
+
# namespace "circleci" do
|
4
|
+
#
|
5
|
+
# @cipher = HandsomeFencer::CircleCI::Crypto.new
|
6
|
+
#
|
7
|
+
# desc "obfuscate .circleci variables"
|
8
|
+
# task :obfuscate do
|
9
|
+
# @cipher.obfuscate
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# desc "expose .circleci variables"
|
13
|
+
# task :expose do
|
14
|
+
# @cipher.expose
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: handsome_fencer-circle_c_i
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- schadenfred
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-09-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
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: sshkit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
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: sqlite3
|
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: minitest-given
|
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: byebug
|
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: Obfuscate sensitive data in source control, expose it again for circle
|
84
|
+
and then deploy
|
85
|
+
email:
|
86
|
+
- fred.schoeneman@gmail.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- MIT-LICENSE
|
92
|
+
- README.md
|
93
|
+
- Rakefile
|
94
|
+
- lib/generators/handsome_fencer.rb
|
95
|
+
- lib/generators/handsome_fencer/circle_c_i/deploy_key_generator.rb
|
96
|
+
- lib/generators/handsome_fencer/circle_c_i/exposed_env_files_generator.rb
|
97
|
+
- lib/generators/handsome_fencer/circle_c_i/install_generator.rb
|
98
|
+
- lib/generators/handsome_fencer/circle_c_i/obfuscated_env_files_generator.rb
|
99
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/circle.env
|
100
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/config.yml
|
101
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/Dockerfile
|
102
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/development.env
|
103
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/app/production.env
|
104
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/database/development.env
|
105
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/containers/web/production.env
|
106
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/expose_env.rb
|
107
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/circleci/obfuscate_env.rb
|
108
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/docker-compose.yml
|
109
|
+
- lib/generators/handsome_fencer/circle_c_i/templates/lib/tasks/deploy.rake
|
110
|
+
- lib/handsome_fencer/circle_c_i.rb
|
111
|
+
- lib/handsome_fencer/circle_c_i/crypto.rb
|
112
|
+
- lib/handsome_fencer/circle_c_i/railtie.rb
|
113
|
+
- lib/handsome_fencer/circle_c_i/version.rb
|
114
|
+
- lib/tasks/handsome_fencer/circle_c_i_tasks.rake
|
115
|
+
homepage: https://github.com/schadenfred/handsomefencer-environment
|
116
|
+
licenses:
|
117
|
+
- MIT
|
118
|
+
metadata: {}
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
requirements: []
|
134
|
+
rubyforge_project:
|
135
|
+
rubygems_version: 2.7.7
|
136
|
+
signing_key:
|
137
|
+
specification_version: 4
|
138
|
+
summary: Handsome deployment of Rails apps using Circle and Docker
|
139
|
+
test_files: []
|