recap 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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