california 0.4.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: 9adb6fd666b3eabfd3b9bd6c4da5dd419c3f06b5
4
+ data.tar.gz: ff63ffad385ad07dd09c421c05babc3140aa44e6
5
+ SHA512:
6
+ metadata.gz: dd60f30690bc3442ce3ad810c5df6295c69ed69cc89410d69f80d73f17abb18d816078d08cbddf510694fd33167858004aa5847cf4c7cae5506e90a4bc54958d
7
+ data.tar.gz: fd9fbae30bdcce5eb55436f738634d759cf9a66aa34a47a869f1daabad874af6ab7b134ec4c96788b2ad9017a08082aca6819c3b4f5067f132a3405e3b0c2359
@@ -0,0 +1,20 @@
1
+ Copyright 2015 halo
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.
@@ -0,0 +1,57 @@
1
+ ## Opinionated capistrano deployment for dummies Edit
2
+
3
+ [![Build Status](https://travis-ci.org/halo/california.svg?branch=master)](https://travis-ci.org/halo/california)
4
+
5
+ ### Requirements
6
+
7
+ * Ruby >= 2.0
8
+ * Bundler
9
+
10
+ ### Installation
11
+
12
+ Create a new repository with a Gemfile like this and run `bundle install` to get the california gem.
13
+
14
+ ```ruby
15
+ # Content of Gemfile
16
+ source 'https://rubygems.org'
17
+
18
+ gem 'california', github: 'halo/california'
19
+ ```
20
+
21
+ Then run the generator for creating your first app you may want to deploy.
22
+ Let's say the name of the app is "hello_world".
23
+
24
+ ```ruby
25
+ # Inside the directory of your newly created repository
26
+ bundle exec california generate hello_world
27
+ ```
28
+
29
+ Modify `hello_world/deploy/production.rb` (or whichever stages you have) and define which servers you want to deploy to.
30
+
31
+ ### Server preparation
32
+
33
+ When deploying your `hello_world` app, it is assumed that you can ssh into the server with the user `hello_world` and that the repository has been cloned to `/mnt/apps/hello_world/repository`.
34
+
35
+ Any additional environment variables needed to configure your application should be located in a file called `/mnt/envs/hello_world`.
36
+
37
+ ```bash
38
+ # Example of content of /mnt/envs/hello_world
39
+ SECRET_TOKEN="abcdef"
40
+ DATABASE_URL="postgres://db.example.com"
41
+ ```
42
+
43
+ ### Deployment
44
+
45
+ Essentially you just run vanilla capistrano 3 commands from inside the respective application directory.
46
+
47
+ ```ruby
48
+ cd hello_world
49
+
50
+ # Examples:
51
+ bundle exec cap staging deploy
52
+ bundle exec cap production deploy migrate=true
53
+ ```
54
+
55
+ ### Copyright
56
+
57
+ MIT 2016 halo. See [MIT-LICENSE](http://github.com/halo/california/blob/master/MIT-LICENSE).
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/california/cli'
3
+
4
+ California::Cli.start ARGV
@@ -0,0 +1,10 @@
1
+ require 'pathname'
2
+ require 'capistrano/setup'
3
+ require 'capistrano/framework'
4
+
5
+ require 'capistrano/scm/plugin'
6
+ # No-op to tell capistrano that we don't want any SCM hooks to be loaded
7
+ install_plugin Capistrano::SCM::Plugin
8
+
9
+ load 'california/capistrano/tasks/deploy.rake'
10
+ load 'california/capistrano/tasks/rails.rake'
@@ -0,0 +1,116 @@
1
+ # The basic capistrano framework provides us with a certain order of tasks when you run "rake deploy".
2
+ # See https://github.com/capistrano/capistrano/blob/master/lib/capistrano/tasks/framework.rake
3
+ # In the code below we hook in into those tasks provided by the deploy framework.
4
+
5
+ namespace :deploy do
6
+
7
+ # –––––––––––––––––
8
+ # Updating the code
9
+ # –––––––––––––––––
10
+
11
+ task :updating do
12
+ logger.info 'Updating the repository...'
13
+
14
+ on roles :app do
15
+ as fetch(:application) do
16
+ within fetch(:deploy_to) do
17
+
18
+ # Remembering which revision we had before making any changes.
19
+ set :previous_revision, capture(:git, 'rev-parse', 'HEAD')
20
+
21
+ # Updating the code.
22
+ execute :git, :reset, '--hard'
23
+ execute :git, :fetch, :origin
24
+ execute :git, :checkout, '--force', "origin/#{fetch(:branch)}"
25
+
26
+ # The update went well so let's persist the revision change.
27
+ # Note: We use ruby because there is no bash command that can write to files *without I/O redirection*.
28
+ set :current_revision, capture(:git, 'rev-parse', 'HEAD')
29
+ execute :ruby, '-e', %("File.write :REVISION.to_s, %|#{fetch(:current_revision)}|" )
30
+ execute :ruby, '-e', %("File.write :PREV_REVISION.to_s, %|#{fetch(:previous_revision)}|" )
31
+ execute :ruby, '-e', %("File.write :BRANCH.to_s, %|#{fetch(:branch)}|" )
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ # ––––––––––––––
38
+ # Set robots.txt
39
+ # ––––––––––––––
40
+
41
+ desc 'Disallow robots unless deploying to production.'
42
+ task :disallow_robots do
43
+ next if fetch(:stage).to_s == 'production'
44
+ logger.info "Overriding robots.txt for environment #{fetch(:stage)}..."
45
+
46
+ on roles :app do
47
+ as fetch(:application) do
48
+ within File.join(fetch(:deploy_to), 'public') do
49
+ execute :echo, %("User-agent: *\nDisallow: /\n" > robots.txt)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ # –––––––––––––––
56
+ # Running Bundler
57
+ # –––––––––––––––
58
+
59
+ task :updated do
60
+ logger.info 'Running Bundler...'
61
+
62
+ on roles :app do
63
+ as fetch(:application) do
64
+ within fetch(:deploy_to) do
65
+
66
+ # Running Bundler.
67
+ core_count = capture(:nproc).chomp
68
+ execute :bundle, :install, '--deployment', '--quiet', '--without', 'development', 'test', '--jobs', core_count
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ # ––––––––––––––––––
75
+ # Restarting the app
76
+ # ––––––––––––––––––
77
+
78
+ task :publishing do
79
+ logger.info 'Restarting the app...'
80
+
81
+ on roles :app do
82
+ as fetch(:application) do
83
+ within File.join(fetch(:deploy_to), 'tmp') do
84
+
85
+ execute :touch, 'restart.txt'
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ # ––––––––––––––––––––––––––
92
+ # Persisting the deploy time
93
+ # ––––––––––––––––––––––––––
94
+
95
+ task :finishing do
96
+ logger.info 'Persisting the deploy time...'
97
+
98
+ on roles :app do
99
+ as fetch(:application) do
100
+ within fetch(:deploy_to) do
101
+
102
+ execute :ruby, '-e', %("File.write :DEPLOYED_AT.to_s, Time.now")
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ task :finished do
109
+ logger.info 'Congratulations! ¯\_(ツ)_/¯'
110
+ end
111
+
112
+ task :failed do
113
+ logger.info 'Oh no, the deployment failed'
114
+ end
115
+
116
+ end
@@ -0,0 +1,32 @@
1
+ namespace :rails do
2
+
3
+ namespace :assets do
4
+ task :precompile do
5
+ logger.info 'Precompiling assets on all web servers...'
6
+
7
+ on roles :web_server do
8
+ as fetch(:application) do
9
+ within fetch(:deploy_to) do
10
+ execute :bundle, :exec, :rake, 'assets:precompile'
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ task :migrate do
18
+ on primary :migrator do
19
+ as fetch(:application) do
20
+ if fetch(:migrate)
21
+ within fetch(:deploy_to) do
22
+ logger.info 'Migrating the database...'
23
+ execute :bundle, :exec, :rake, 'db:migrate'
24
+ end
25
+ else
26
+ logger.warn 'Skipping Rails migrations because you did NOT add this to your cap command: migrate=true'
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,21 @@
1
+ require 'thor'
2
+
3
+ module California
4
+ class Cli < Thor
5
+ include Thor::Actions
6
+
7
+ desc 'generate APPNAME', 'Generates the skeleton for a new app'
8
+
9
+ def generate(appname)
10
+ template 'templates/app/Capfile', "#{appname}/Capfile"
11
+ template 'templates/app/config/deploy.rb', "#{appname}/config/deploy.rb"
12
+ template 'templates/app/config/deploy/stage.rb', "#{appname}/config/deploy/staging.rb"
13
+ template 'templates/app/config/deploy/stage.rb', "#{appname}/config/deploy/production.rb"
14
+ end
15
+
16
+ def self.source_root
17
+ File.dirname __FILE__
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,2 @@
1
+ # Wrapper so you can call `load 'california/stage` without `.rb` extension
2
+ load 'california/stage.rb'
@@ -0,0 +1,100 @@
1
+ module BenderLogger
2
+ def self.logger
3
+ @logger ||= logger!
4
+ end
5
+
6
+ def self.logger!
7
+ instance = ::Logger.new STDOUT
8
+ instance.formatter = proc do |_, _, _, msg|
9
+ line = '–' * (msg.size + 2)
10
+ [nil, line, " #{msg}", line, nil].join("\n") + "\n"
11
+ end
12
+ instance
13
+ end
14
+
15
+ end
16
+
17
+ def logger
18
+ BenderLogger.logger
19
+ end
20
+
21
+ # Rails environment sanity check.
22
+ if fetch(:rails_env)
23
+ raise 'Please refrain from setting the :rails_env parameter. We use :rack_env instead.'
24
+ end
25
+
26
+ # We derive the environment from the stage name.
27
+ set :rack_env, 'production' if fetch(:stage).to_s.include?('production')
28
+ set :rack_env, 'staging' if fetch(:stage).to_s.include?('staging')
29
+ set :rack_env, 'test' if fetch(:stage).to_s.include?('test')
30
+
31
+ # Rack environment sanity check.
32
+ unless %w[test staging production].include? fetch(:rack_env)
33
+ raise "#{fetch(:rack_env).inspect} does not seem to be a valid Rails environment."
34
+ end
35
+
36
+ # Making sure we set the right environment in every context.
37
+ fetch(:default_env)[:rack_env] = fetch(:rack_env)
38
+ fetch(:default_env)[:rails_env] = fetch(:rack_env)
39
+
40
+ # Unlike "normal" capistrano, we deploy right into the repository.
41
+ set :deploy_to, "/mnt/apps/#{fetch(:application)}/repository"
42
+ # Alias for cap task that use release_path
43
+ set(:release_path, -> { fetch(:deploy_to) })
44
+
45
+ # The branch can be set in various ways, default is master.
46
+ set :branch, ENV['branch'] || ENV['BRANCH'] || fetch(:branch, :master)
47
+
48
+ # Keep track of whether we should run migrations or not.
49
+ # We do this to get rid of the overhead of maintaining a separate "migrations" task.
50
+ set :migrate, ENV['migrate'] || ENV['MIGRATE'] || fetch(:migrate, false)
51
+
52
+ # Branch sanity check
53
+ in_production = fetch(:rack_env).to_s.downcase == 'production'
54
+ non_master_branch = fetch(:branch).to_s.downcase != 'master'
55
+
56
+ if in_production && non_master_branch && ENV['i_dont_know_what_im_doing'] != 'true'
57
+ message = "You are courageous, trying to deploy the branch #{fetch(:branch).inspect} to production.\n"
58
+ message += "If you know what you're doing you can bypass this warning \
59
+ by adding this to your cap command: i_dont_know_what_im_doing=true"
60
+ raise message
61
+ end
62
+
63
+ module SSHKit
64
+ class Command
65
+ # Define $HOME to be in /mnt/apps/USERNAME
66
+ # Add ~/bin to $PATH
67
+ # Source any existing .bash_profile in the home directory
68
+ def user
69
+ return yield unless options[:user]
70
+ %(sudo -u #{options[:user]} #{environment_string} -- bash -c '\
71
+ export HOME=/mnt/apps/#{options[:user]}; \
72
+ export PATH="$HOME/bin:$PATH"; \
73
+ source $HOME/.bash_profile; \
74
+ #{yield.to_s.gsub("'", %q('"'"'))}')
75
+ end
76
+ end
77
+
78
+ class CommandMap
79
+ def defaults
80
+ Hash.new do |hash, command|
81
+ # Avoid using `/usr/bin/env` at all
82
+ hash[command] = command.to_s
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ module Capistrano
89
+ class Configuration
90
+ class Server < SSHKit::Host
91
+ class Properties
92
+
93
+ # Making the properties indifferent to symbol/string keys.
94
+ def fetch(key)
95
+ @properties[key] || @properties[key.to_s]
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,2 @@
1
+ # You can run `cap` commands in directories that have a `Capfile`.
2
+ require 'california/capfile'
@@ -0,0 +1,8 @@
1
+ set :application, File.basename(File.expand_path('../..', __FILE__))
2
+
3
+ # Disallow robots unless deploying to production.
4
+ after 'deploy:updated', 'deploy:disallow_robots'
5
+
6
+ # For Rails you should uncomment these custom task hooks.
7
+ # after 'deploy:updated', 'rails:assets:precompile'
8
+ # after 'deploy:updated', 'rails:migrate'
@@ -0,0 +1,17 @@
1
+ # The stage name is derived from this very filename,
2
+ # which should include "production", "staging", or "test" in its name.
3
+ set :stage, File.basename(__FILE__, '.rb')
4
+
5
+ # Loading task defaults.
6
+ load 'california/stage'
7
+
8
+ # You need to define at least one server.
9
+ # The one with the role "migrator" will be entitled to run migrations:
10
+ # server '203.0.113.19', roles: %w{ all app web_server migrator }
11
+
12
+ # You may also set any custom Capistrano options:
13
+ # set :ssh_options, {
14
+ # forward_agent: true,
15
+ # port: 12345,
16
+ # keys: Pathname.new('~/.ssh/mykey').expand_path.to_s,
17
+ # }
@@ -0,0 +1,3 @@
1
+ module California
2
+ VERSION = '0.4.1'.freeze
3
+ end
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: california
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.1
5
+ platform: ruby
6
+ authors:
7
+ - halo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.19'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.19'
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: guard-rspec
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: rb-fsevent
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
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
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
+ description: See https://github.com/halo/california
98
+ email:
99
+ executables:
100
+ - california
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - LICENSE.md
105
+ - README.md
106
+ - bin/california
107
+ - lib/california/capfile.rb
108
+ - lib/california/capistrano/tasks/deploy.rake
109
+ - lib/california/capistrano/tasks/rails.rake
110
+ - lib/california/cli.rb
111
+ - lib/california/stage
112
+ - lib/california/stage.rb
113
+ - lib/california/templates/app/Capfile
114
+ - lib/california/templates/app/config/deploy.rb
115
+ - lib/california/templates/app/config/deploy/stage.rb
116
+ - lib/california/version.rb
117
+ homepage: https://github.com/halo/california
118
+ licenses: []
119
+ metadata: {}
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 2.5.2
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: Capistrano 3 for dummies.
140
+ test_files: []