recap 0.2.0 → 1.0.0

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.
Files changed (68) hide show
  1. data/.gitignore +2 -1
  2. data/README.md +55 -10
  3. data/Rakefile +19 -5
  4. data/bin/recap +2 -2
  5. data/features/managing-processes.feature +1 -1
  6. data/features/setting-environment-variables.feature +26 -1
  7. data/features/steps/capistrano_steps.rb +10 -6
  8. data/features/support/project.rb +24 -5
  9. data/features/templates/project/Capfile.erb +1 -1
  10. data/lib/recap/recipes/rails.rb +6 -0
  11. data/lib/recap/recipes/ruby.rb +11 -0
  12. data/lib/recap/recipes/static.rb +3 -0
  13. data/lib/recap/recipes.rb +18 -0
  14. data/lib/recap/support/capistrano_extensions.rb +85 -0
  15. data/lib/recap/support/cli.rb +57 -0
  16. data/lib/recap/{compatibility.rb → support/compatibility.rb} +2 -2
  17. data/lib/recap/support/environment.rb +61 -0
  18. data/lib/recap/support/namespace.rb +47 -0
  19. data/lib/recap/support/shell_command.rb +35 -0
  20. data/lib/recap/support/templates/Capfile.erb +6 -0
  21. data/lib/recap/tasks/bootstrap.rb +77 -0
  22. data/lib/recap/{bundler.rb → tasks/bundler.rb} +15 -6
  23. data/lib/recap/{deploy.rb → tasks/deploy.rb} +30 -17
  24. data/lib/recap/tasks/env.rb +111 -0
  25. data/lib/recap/{foreman.rb → tasks/foreman.rb} +20 -12
  26. data/lib/recap/{preflight.rb → tasks/preflight.rb} +13 -11
  27. data/lib/recap/tasks/rails.rb +42 -0
  28. data/lib/recap/tasks.rb +16 -0
  29. data/lib/recap/version.rb +1 -1
  30. data/lib/recap.rb +119 -10
  31. data/recap.gemspec +3 -2
  32. data/spec/models/capistrano_extensions_spec.rb +41 -0
  33. data/spec/models/cli_spec.rb +25 -0
  34. data/spec/models/environment_spec.rb +14 -14
  35. data/spec/models/shell_command_spec.rb +55 -0
  36. data/spec/spec_helper.rb +1 -1
  37. data/spec/tasks/bootstrap_spec.rb +9 -13
  38. data/spec/tasks/bundler_spec.rb +39 -7
  39. data/spec/tasks/deploy_spec.rb +42 -26
  40. data/spec/tasks/env_spec.rb +81 -5
  41. data/spec/tasks/foreman_spec.rb +10 -5
  42. data/spec/tasks/rails_spec.rb +80 -0
  43. metadata +65 -57
  44. data/doc/index.html +0 -235
  45. data/doc/lib/recap/bootstrap.html +0 -42
  46. data/doc/lib/recap/bundler.html +0 -168
  47. data/doc/lib/recap/capistrano_extensions.html +0 -208
  48. data/doc/lib/recap/cli.html +0 -42
  49. data/doc/lib/recap/compatibility.html +0 -73
  50. data/doc/lib/recap/deploy.html +0 -328
  51. data/doc/lib/recap/env.html +0 -108
  52. data/doc/lib/recap/foreman.html +0 -42
  53. data/doc/lib/recap/namespace.html +0 -42
  54. data/doc/lib/recap/preflight.html +0 -163
  55. data/doc/lib/recap/rails.html +0 -42
  56. data/doc/lib/recap/version.html +0 -42
  57. data/doc/lib/recap.html +0 -42
  58. data/index.rb +0 -62
  59. data/lib/recap/bootstrap.rb +0 -47
  60. data/lib/recap/capistrano_extensions.rb +0 -74
  61. data/lib/recap/cli.rb +0 -32
  62. data/lib/recap/deploy/templates/Capfile.erb +0 -6
  63. data/lib/recap/env.rb +0 -58
  64. data/lib/recap/environment.rb +0 -54
  65. data/lib/recap/namespace.rb +0 -37
  66. data/lib/recap/rails.rb +0 -24
  67. data/lib/recap/ruby.rb +0 -3
  68. data/lib/recap/static.rb +0 -1
@@ -0,0 +1,77 @@
1
+ # Recap has a number of requirements on your server before you can deploy applications
2
+ # with it. These include:
3
+ #
4
+ # - Each application needs its own account on the server. The full account environment
5
+ # is loaded whenever an application command or process is run, so this is the place where
6
+ # other application specific configuration should happen.
7
+ # - Each deploying user needs a personal account on the server which they should be able to
8
+ # ssh into.
9
+ # - This personal account needs to be able to `sudo`, both to switch to the application user
10
+ # and to run other administrative commands.
11
+
12
+ require 'recap/tasks'
13
+
14
+ module Recap::Tasks::Bootstrap
15
+ extend Recap::Support::Namespace
16
+
17
+ # The bootstrap namespace has a couple of task that help configure application and personal accounts
18
+ # and personal accounts to meet these requirements.
19
+ namespace :bootstrap do
20
+ set(:remote_username) { capture('whoami').strip }
21
+ set(:application_home) { "/home/#{application_user}"}
22
+
23
+ # The `bootstrap:application` task sets up the account on the server the application itself uses. This
24
+ # account should be dedicated to running this application.
25
+ desc 'Sets up the server account used by the application, including home directory and environment support'
26
+ task :application do
27
+ # If the account doesn't already exist on the server, the task creates it.
28
+ if exit_code("id #{application_user}").strip != "0"
29
+ sudo "useradd #{application_user} -d #{application_home}"
30
+ end
31
+
32
+ # If the home directory doesn't exist, or isn't both readable and writable by members of the application
33
+ # group (all the accounts allowed to deploy the app) then the task creates the directory and fixes
34
+ # file permissions.
35
+ sudo "mkdir -p #{application_home}"
36
+ sudo "chown #{application_user}:#{application_group} #{application_home}"
37
+ sudo "chmod 755 #{application_home}"
38
+
39
+ # A script `.recap` is added to set the configuration environment (set with `env:set` and
40
+ # `env:edit` tasks). The script loads the `.env` file in the users home folder, creates
41
+ # a new copy with `export ` prefixed to each line, and sources this new copy.
42
+ put_as_app %{
43
+ if [ -s "$HOME/.env" ]; then
44
+ sed -e 's/\\r//g' -e 's/^/export /g' .env > .recap-env-export
45
+ . $HOME/.recap-env-export
46
+ fi
47
+ }, "#{application_home}/.recap"
48
+
49
+ # Finally, `.profile` needs to source the `.recap` script, so that the configuration environment is
50
+ # available whenever the environment is loaded.
51
+ as_app "touch .profile", "~"
52
+
53
+ if exit_code("grep '\\. $HOME/\\.recap' #{application_home}/.profile") != "0"
54
+ as_app %{echo ". \\$HOME/.recap" >> .profile}, "~"
55
+ end
56
+ end
57
+
58
+ # The `bootstrap:user` task sets up the personal accounts of user who can deploy applications.
59
+ # In order to deploy a particular app, the account's git configuration must be set (so
60
+ # that releases can be tagged), and the account must be a member of the application group.
61
+ desc 'Sets up the server account used by a deploying user'
62
+ task :user do
63
+ git_user_name = Recap::Support::ShellCommand.execute("git config user.name").strip
64
+ git_user_email = Recap::Support::ShellCommand.execute("git config user.email").strip
65
+ run "git config --global user.name '#{git_user_name}'"
66
+ run "git config --global user.email '#{git_user_email}'"
67
+ sudo "usermod --append -G #{application_group} #{remote_username}"
68
+ end
69
+
70
+ # The `bootstrap` task simply runs both the `bootstrap:application` and `bootstrap:user` tasks
71
+ # in turn.
72
+ task :default do
73
+ application
74
+ user
75
+ end
76
+ end
77
+ end
@@ -1,10 +1,12 @@
1
1
  # The bundler recipe ensures that the application bundle is installed whenever the code is updated.
2
2
 
3
- module Recap::Bundler
4
- extend Recap::Namespace
3
+ require 'recap/tasks'
4
+
5
+ module Recap::Tasks::Bundler
6
+ extend Recap::Support::Namespace
5
7
 
6
8
  namespace :bundle do
7
- # Each bundle is declared in a `Gemfile`, by default in the root of the application directory
9
+ # Each bundle is declared in a `Gemfile`, by default in the root of the application directory.
8
10
  set(:bundle_gemfile) { "#{deploy_to}/Gemfile" }
9
11
 
10
12
  # As well as a `Gemfile`, application repositories should also contain a `Gemfile.lock`.
@@ -16,7 +18,7 @@ module Recap::Bundler
16
18
 
17
19
  # Not all gems are needed for production environments, so by default the `development`, `test` and
18
20
  # `assets` groups are skipped.
19
- set(:bundle_without) { "development test assets" }
21
+ set(:bundle_without) { "development test" }
20
22
 
21
23
  # The main bundle install command uses all the settings above, together with the `--deployment`,
22
24
  # `--binstubs` and `--quiet` flags
@@ -32,7 +34,7 @@ module Recap::Bundler
32
34
  end
33
35
 
34
36
  # Occassionally it's useful to force an install (such as if something has gone wrong in
35
- # a previous deployment)
37
+ # a previous deployment).
36
38
  desc "Install the latest gem bundle"
37
39
  task :default do
38
40
  if deployed_file_exists?(bundle_gemfile)
@@ -47,9 +49,16 @@ module Recap::Bundler
47
49
  end
48
50
  end
49
51
 
52
+ task :check_installed do
53
+ if exit_code_as_app('bundle --version', '.') != "0"
54
+ abort "The application user '#{application_user}' cannot execute `bundle`. Please check you have bundler installed."
55
+ end
56
+ end
57
+ after 'preflight:check', 'bundle:check_installed'
58
+
50
59
  # To install the bundle automatically each time the code is updated or cloned, hooks are added to
51
60
  # the `deploy:clone_code` and `deploy:update_code` tasks.
52
61
  after 'deploy:clone_code', 'bundle:install:if_changed'
53
62
  after 'deploy:update_code', 'bundle:install:if_changed'
54
63
  end
55
- end
64
+ end
@@ -1,19 +1,26 @@
1
- require 'recap'
2
- require 'recap/capistrano_extensions'
1
+ # These tasks provide the basic mechanism getting new code onto servers using git.
3
2
 
4
- require 'recap/preflight'
5
- require 'recap/bootstrap'
6
- require 'recap/env'
3
+ require 'recap/tasks'
4
+ require 'recap/support/capistrano_extensions'
7
5
 
8
- module Recap::Deploy
9
- extend Recap::Namespace
6
+ # These deployment tasks are designed to work alongside the tasks for
7
+ # [altering environment variables](env.html), as well as the
8
+ # [preflight checks](preflight.html) and
9
+ # [bootstrap tasks](bootstrap.html).
10
+
11
+ require 'recap/tasks/env'
12
+ require 'recap/tasks/preflight'
13
+ require 'recap/tasks/bootstrap'
14
+
15
+ module Recap::Tasks::Deploy
16
+ extend Recap::Support::Namespace
10
17
 
11
18
  namespace :deploy do
12
19
  # To use this recipe, both the application's name and its git repository are required.
13
20
  set(:application) { abort "You must set the name of your application in your Capfile, e.g.: set :application, 'tomafro.net'" }
14
- set(:repository) { abort "You must set the git respository location in your Capfile, e.g.: set :respository, 'git@github.com/tomafro/tomafro.net'"}
21
+ set(:repository) { abort "You must set the git respository location in your Capfile, e.g.: set :respository, 'git@github.com/tomafro/tomafro.net'" }
15
22
 
16
- # The recipe assumes that the application code will be run as a dedicated user. Any any user who
23
+ # The recipe assumes that the application code will be run as a dedicated user. Any user who
17
24
  # can deploy the application should be added as a member of the application's group. By default,
18
25
  # both the application user and group take the same name as the application.
19
26
  set(:application_user) { application }
@@ -23,8 +30,8 @@ module Recap::Deploy
23
30
  set(:branch, 'master')
24
31
 
25
32
  # Unlike a standard capistrano deployment, all releases are stored directly in the `deploy_to`
26
- # directory. The default is `/home/#{application_user}/apps/#{application}`.
27
- set(:deploy_to) { "/home/#{application_user}/apps/#{application}" }
33
+ # directory. The default is `/home/#{application_user}/app`.
34
+ set(:deploy_to) { "/home/#{application_user}/app" }
28
35
 
29
36
  # Each release is marked by a unique tag, generated with the current timestamp. While this can be
30
37
  # changed, it's not recommended, as the sort order of the tag names is important; later tags must
@@ -47,16 +54,21 @@ module Recap::Deploy
47
54
  # `:pty` is set to `true`.
48
55
  default_run_options[:pty] = true
49
56
 
50
- # The `deploy:setup` task prepares all the servers for the deployment.
57
+ # The `deploy:setup` task prepares all the servers for the deployment. It ensures the `env`
58
+ # has been set, and clones the code.
51
59
  desc "Prepare servers for deployment"
52
60
  task :setup, :except => {:no_release => true} do
53
61
  transaction do
62
+ top.env.set
54
63
  clone_code
55
64
  end
56
65
  end
57
66
 
58
- # Clone the repository into the deployment directory.
67
+ # The `deploy:clone_code` task clones the project repository into the `deploy_to` location
68
+ # and ensures it has the correct file permissions. It shouldn't be necessary to call this
69
+ # task manually as it is run as part of `deploy:setup`.
59
70
  task :clone_code, :except => {:no_release => true} do
71
+ on_rollback { as_app "rm -fr #{deploy_to}" }
60
72
  # Before cloning, the directory needs to exist and be both readable and writable by the application group
61
73
  as_app "mkdir -p #{deploy_to}", "~"
62
74
  as_app "chmod g+rw #{deploy_to}"
@@ -64,11 +76,12 @@ module Recap::Deploy
64
76
  git "clone #{repository} ."
65
77
  end
66
78
 
67
- # The main deployment task (called with `cap deploy`) deploys the latest application code to all
68
- # servers, tags the release and restarts the application.
79
+ # The `deploy` task ensures the environment is set, updates the application code,
80
+ # tags the release and restarts the application.
69
81
  desc "Deploy the latest application code"
70
82
  task :default do
71
83
  transaction do
84
+ top.env.set
72
85
  update_code
73
86
  tag
74
87
  end
@@ -111,8 +124,8 @@ module Recap::Deploy
111
124
  end
112
125
  end
113
126
 
114
- # In case of emergency or when manually testing deployment, it can be useful to remove all
115
- # previously deployed files before starting again.
127
+ # The `destroy` task can be used in an emergency or when manually testing deployment. It removes
128
+ # all previously deployed files, leaving a blank slate to run `deploy:setup` on.
116
129
  desc "Remove all deployed files"
117
130
  task :destroy do
118
131
  sudo "rm -rf #{deploy_to}"
@@ -0,0 +1,111 @@
1
+ # Recap encourages the storage of application configuration (such as database passwords, S3 keys and
2
+ # other things that change between deploys) in environment variables.
3
+ # [12factor.net](http://www.12factor.net) has [http://www.12factor.net/config](a good set of reasons
4
+ # why this is desirable).
5
+ #
6
+ # To enable this, [recap](https://github.com/freerange/recap) stores these configuration variables
7
+ # in `.env`, and adds a script to the user's `.profile` to set these whenever the environment is
8
+ # loaded (see [bootstrap](bootstrap.html)).
9
+ #
10
+ # Variables can be set in two ways. First, using either the `env:set` or `env:edit` tasks,
11
+ # the `.env` file can be directly manipulated. This is generally the best way to manipulate
12
+ # these values.
13
+ #
14
+ # The other way to set them is using the `set_default_env` method directly in your `Capfile`.
15
+ # This sets a default value, which will be used if no other value is set. An example where
16
+ # this might be useful is where you know your app should run using ruby 1.8.7. Using
17
+ # `set_default_env :RBENV_VERSION, "1.8.7-p352"` in your `Capfile` will use this ruby as the default.
18
+ # Then, in a different deployment you might want to test using a different version of ruby,
19
+ # so could use `cap env:set RBENV_VERSION=1.9.3-p0` to override the default.
20
+
21
+ require 'recap/tasks'
22
+
23
+ module Recap::Tasks::Env
24
+ extend Recap::Support::Namespace
25
+
26
+ namespace :env do
27
+ set(:environment_file) { "/home/#{application_user}/.env" }
28
+
29
+ # The `env` task displays the current configuration environment. Note that this doesn't
30
+ # include all environment variables, only those stored in the `.env` file.
31
+ desc 'View the current server environment'
32
+ task :default do
33
+ if current_environment.empty?
34
+ puts "There are no config variables set"
35
+ else
36
+ puts "The config variables are:"
37
+ puts
38
+ puts current_environment
39
+ end
40
+ end
41
+
42
+ # A single variable can be set using the `env:set` task, followed by a variable and value,
43
+ # for example `cap env:set VARIABLE=VALUE`. Variables can be unset using `cap env:set VARIABLE=`.
44
+ desc 'Set a variable in the environment, using "cap env:set VARIABLE=VALUE". Unset using "cap env:set VARIABLE="'
45
+ task :set do
46
+ env = env_argv.inject(current_environment) do |env, string|
47
+ env.set_string(string)
48
+ logger.debug "Setting #{string}"
49
+ logger.debug "Env is now: #{env}"
50
+ env
51
+ end
52
+ update_remote_environment(env)
53
+ default
54
+ end
55
+
56
+ # The `env:edit` task uses your EDITOR to load the `.env` file locally, saving any changes
57
+ # to all servers.
58
+ desc 'Edit the server environment'
59
+ task :edit do
60
+ content = edit_file environment_file
61
+ env = Recap::Support::Environment.from_string(content)
62
+ update_remote_environment(env)
63
+ default
64
+ end
65
+
66
+ # The `env:reset` tasks reverts all variables back to their default values. If there is no default value,
67
+ # the variable will be removed.
68
+ desc 'Reset the server environment to its default values'
69
+ task :reset do
70
+ as_app "rm -f #{environment_file}", "~"
71
+ set
72
+ end
73
+
74
+ def current_environment
75
+ @current_environment ||= begin
76
+ if deployed_file_exists?(environment_file, '.')
77
+ Recap::Support::Environment.from_string(capture("cat #{environment_file}"))
78
+ else
79
+ Recap::Support::Environment.new
80
+ end
81
+ end
82
+ end
83
+
84
+ def update_remote_environment(env)
85
+ logger.debug "Env is now #{env}"
86
+
87
+ default_env.each do |name, value|
88
+ env.set(name, value) unless env.get(name)
89
+ end
90
+
91
+ if env.empty?
92
+ as_app "rm -f #{environment_file}", "~"
93
+ else
94
+ put_as_app env.to_s, environment_file
95
+ end
96
+ end
97
+ end
98
+
99
+ # Default environment values can be set by a recipe using `set_default_env :NAME, 'VALUE'`.
100
+ def set_default_env(name, value)
101
+ default_env[name] = value
102
+ end
103
+
104
+ def default_env
105
+ @default_env ||= {}
106
+ end
107
+
108
+ def env_argv
109
+ ARGV[1..-1]
110
+ end
111
+ end
@@ -1,24 +1,28 @@
1
- module Recap::Foreman
2
- extend Recap::Namespace
1
+ # These tasks configure recap to use Foreman to stop, start and restart your application processes.
2
+
3
+ require 'recap/tasks'
4
+
5
+ module Recap::Tasks::Foreman
6
+ extend Recap::Support::Namespace
3
7
 
4
8
  namespace :foreman do
5
- # Processes are delcared in a `Procfile`, by default in the root of the application directory
9
+ # Processes are declared in a `Procfile`, by default in the root of the application directory.
6
10
  set(:procfile) { "#{deploy_to}/Procfile" }
7
11
 
8
- # Foreman startup scripts are exported in `upstart` format by default
12
+ # Foreman startup scripts are exported in `upstart` format by default.
9
13
  set(:foreman_export_format, "upstart")
10
14
 
11
- # Scripts are exported (as the the application user) to a temporary location first
15
+ # Scripts are exported (as the the application user) to a temporary location first.
12
16
  set(:foreman_tmp_location) { "#{deploy_to}/tmp/foreman" }
13
17
 
14
- # After exports, the scripts are moved to their final location, usually `/etc/init`
18
+ # After exports, the scripts are moved to their final location, usually `/etc/init`.
15
19
  set(:foreman_export_location, "/etc/init")
16
20
 
17
- # The standard foreman export
21
+ # The standard foreman export.
18
22
  set(:foreman_export_command) { "./bin/foreman export #{foreman_export_format} #{foreman_tmp_location} --procfile #{procfile} --app #{application} --user #{application_user} --log #{deploy_to}/log" }
19
23
 
20
24
  namespace :export do
21
- # After each deployment, the startup scripts are exported if the `Procfile` has changed
25
+ # After each deployment, the startup scripts are exported if the `Procfile` has changed.
22
26
  task :if_changed do
23
27
  if deployed_file_changed?(procfile)
24
28
  top.foreman.export.default
@@ -28,6 +32,7 @@ module Recap::Foreman
28
32
  # To export the scripts, they are first generated in a temporary location, then copied to their final
29
33
  # destination. This is done because the foreman export command needs to be run as the application user,
30
34
  # while sudo is required to write to `/etc/init`.
35
+ desc 'Export foreman configuration'
31
36
  task :default do
32
37
  if deployed_file_exists?(procfile)
33
38
  as_app foreman_export_command
@@ -37,21 +42,24 @@ module Recap::Foreman
37
42
  end
38
43
  end
39
44
 
40
- # Starts all processes that form the application
45
+ # Starts all processes that form the application.
46
+ desc 'Start all application processes'
41
47
  task :start do
42
48
  if deployed_file_exists?(procfile)
43
49
  sudo "start #{application}"
44
50
  end
45
51
  end
46
52
 
47
- # Restarts all processes that form the application
53
+ # Restarts all processes that form the application.
54
+ desc 'Restart all application processes'
48
55
  task :restart do
49
56
  if deployed_file_exists?(procfile)
50
57
  sudo "restart #{application} || sudo start #{application}"
51
58
  end
52
59
  end
53
60
 
54
- # Stops all processes that form the application
61
+ # Stops all processes that form the application.
62
+ desc 'Stop all application processes'
55
63
  task :stop do
56
64
  if deployed_file_exists?(procfile)
57
65
  sudo "stop #{application}"
@@ -61,4 +69,4 @@ module Recap::Foreman
61
69
  after 'deploy:update_code', 'foreman:export:if_changed'
62
70
  after 'deploy:restart', 'foreman:restart'
63
71
  end
64
- end
72
+ end
@@ -17,50 +17,52 @@
17
17
  # This preflight recipe checks each of these things in turn, and attempts to give helpful advice
18
18
  # should a check fail.
19
19
 
20
- module Recap::Preflight
21
- extend Recap::Namespace
20
+ require 'recap/tasks'
21
+
22
+ module Recap::Tasks::Preflight
23
+ extend Recap::Support::Namespace
22
24
 
23
25
  namespace :preflight do
24
- # The preflight check is pretty quick, so run it before every `deploy:setup` and `deploy`
26
+ # The preflight check is pretty quick, so run it before every `deploy:setup` and `deploy`.
25
27
  before 'deploy:setup', 'preflight:check'
26
28
  before 'deploy', 'preflight:check'
27
29
 
28
30
  set(:remote_username) { capture('whoami').strip }
29
31
 
30
32
  task :check do
31
- # First check the `application_user` exists
33
+ # First check the `application_user` exists.
32
34
  if exit_code("id #{application_user}").strip != "0"
33
35
  abort %{
34
- The application user '#{application_user}' doesn't exist. You can create this user by logging into the server and running:
36
+ The application user '#{application_user}' doesn't exist. Did you run the `bootstrap` task? You can also create this user by logging into the server and running:
35
37
 
36
38
  sudo useradd #{application_user}
37
39
  \n}
38
40
  end
39
41
 
40
- # Then the `application_group`
42
+ # Then the `application_group`.
41
43
  if exit_code("id -g #{application_group}") != "0"
42
44
  abort %{
43
- The application group '#{application_group}' doesn't exist. You can create this group by logging into the server and running:
45
+ The application group '#{application_group}' doesn't exist. Did you run the `bootstrap` task? You can also create this group by logging into the server and running:
44
46
 
45
47
  sudo groupadd #{application_group}
46
48
  sudo usermod --append -G #{application_group} #{application_user}
47
49
  \n}
48
50
  end
49
51
 
50
- # Check the git configuration exists
52
+ # Check the git configuration exists.
51
53
  if capture('git config user.name || true').strip.empty? || capture('git config user.email || true').strip.empty?
52
54
  abort %{
53
- Your remote user must have a git user.name and user.email set. You can set these by logging into the server as #{remote_username} and running:
55
+ Your remote user must have a git user.name and user.email set. Did you run the `bootstrap` task? You can also set these by logging into the server as #{remote_username} and running:
54
56
 
55
57
  git config --global user.email "you@example.com"
56
58
  git config --global user.name "Your Name"
57
59
  \n}
58
60
  end
59
61
 
60
- # And finally check the remote user is a member of the `application_group`
62
+ # And finally check the remote user is a member of the `application_group`.
61
63
  unless capture('groups').split(" ").include?(application_group)
62
64
  abort %{
63
- Your remote user must be a member of the '#{application_group}' group in order to perform deployments. You can add yourself to this group by logging into the server and running:
65
+ Your remote user must be a member of the '#{application_group}' group in order to perform deployments. Did you run the `bootstrap` task? You can also add yourself to this group by logging into the server and running:
64
66
 
65
67
  sudo usermod --append -G #{application_group} #{remote_username}
66
68
  \n}
@@ -0,0 +1,42 @@
1
+ # The rails tasks add to the standard deployment with tasks to support running
2
+ # database migrations and precompiling assets.
3
+
4
+ require 'recap/tasks'
5
+
6
+ module Recap::Tasks::Rails
7
+ extend Recap::Support::Namespace
8
+
9
+ namespace :rails do
10
+ namespace :db do
11
+ task :load_schema do
12
+ if deployed_file_exists?("db/schema.rb")
13
+ as_app './bin/rake db:create db:schema:load'
14
+ end
15
+ end
16
+
17
+ task :migrate do
18
+ if deployed_file_changed?("db/schema.rb")
19
+ as_app './bin/rake db:migrate'
20
+ end
21
+ end
22
+ end
23
+
24
+ # The `rails:assets:precompile` runs rails' asset precompilation rake task on
25
+ # the server. As assets come from so many sources (app/assets, vendor/assets
26
+ # and from individual gems) it's not easy to determine whether compilation is
27
+ # required, so it is done on every deploy.
28
+ namespace :assets do
29
+ task :precompile do
30
+ as_app "./bin/rake RAILS_GROUPS=assets assets:precompile"
31
+ end
32
+ end
33
+
34
+ # After the code is first cloned (during `deploy:setup`) load the schema into
35
+ # the database.
36
+ after "deploy:clone_code", "rails:db:load_schema"
37
+
38
+ # On every deploy, after the code is updated, run the database migrations
39
+ # and precompile the assets.
40
+ after "deploy:update_code", "rails:db:migrate", "rails:assets:precompile"
41
+ end
42
+ end
@@ -0,0 +1,16 @@
1
+ # Recap provides a number of capistrano tasks to aid with deployment. The core functionality
2
+ # is found in the [tasks for deployment](tasks/deploy.html) and those for
3
+ # [altering environment variables](tasks/env.html).
4
+ #
5
+ # Supporting these are [preflight checks](tasks/preflight.html) to ensure servers and
6
+ # users are correctly setup, and the [bootstrap tasks](tasks/bootstrap.html) that help
7
+ # do this setting up.
8
+ #
9
+ # In addition, there are extensions for [bundler](tasks/bundler.html),
10
+ # [foreman](tasks/foreman.html), and [rails](tasks/rails.html) that add extra
11
+ # functionality to the standard deploy.
12
+
13
+ require 'recap'
14
+
15
+ module Recap::Tasks
16
+ end
data/lib/recap/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Recap
2
- VERSION = "0.2.0"
2
+ VERSION = '1.0.0'
3
3
  end