wordpresstrano 0.2.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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +5 -0
- data/lib/capistrano/wordpress/helpers/fixnum.rb +22 -0
- data/lib/capistrano/wordpress/helpers/hash.rb +10 -0
- data/lib/capistrano/wordpress/hooks.rb +95 -0
- data/lib/capistrano/wordpress/tasks/binaries.rake +35 -0
- data/lib/capistrano/wordpress/tasks/config.rake +85 -0
- data/lib/capistrano/wordpress/tasks/database.rake +355 -0
- data/lib/capistrano/wordpress/tasks/deploy.rake +24 -0
- data/lib/capistrano/wordpress/tasks/htaccess.rake +132 -0
- data/lib/capistrano/wordpress/tasks/maintenance.rake +68 -0
- data/lib/capistrano/wordpress/tasks/robots.rake +37 -0
- data/lib/capistrano/wordpress/tasks/uploads.rake +122 -0
- data/lib/capistrano/wordpress/tasks/webroot.rake +38 -0
- data/lib/capistrano/wordpress/tasks/wordpress.rake +89 -0
- data/lib/capistrano/wordpress.rb +13 -0
- data/lib/wordpresstrano.rb +1 -0
- data/wordpresstrano.gemspec +16 -0
- metadata +82 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5436061cb8fc9afe6050e4f86f69595e9259c791
|
4
|
+
data.tar.gz: 1513416e7fed88eaa04554fd21f9711dc60d0667
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3719edf22d551b9ff9d8dac8691b77123d2b3e3ecbf237742ed040d331f8ee81975d3bd3304edfc4122bcab4ec9869deeda8f51a81a1849fd481f1a88a9a5800
|
7
|
+
data.tar.gz: 644b5f81e4007e13770fce41c8cfb18f4b3a9f66320a99d0ff8364e1de837e7ab05928b7b34b075489e12adf303db08f378118b9dcfba91cc4b3171c284d9fd2
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Nialto Services
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
class Fixnum
|
2
|
+
# Get the ordinal string of the integer value
|
3
|
+
def ordinal
|
4
|
+
abs_number = self.to_i.abs
|
5
|
+
|
6
|
+
if (11..13).include?(abs_number % 100)
|
7
|
+
"th"
|
8
|
+
else
|
9
|
+
case abs_number % 10
|
10
|
+
when 1; "st"
|
11
|
+
when 2; "nd"
|
12
|
+
when 3; "rd"
|
13
|
+
else "th"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Get the ordinal string prefixed with the integer value
|
19
|
+
def ordinalize
|
20
|
+
"#{self}#{self.ordinal}"
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# Check binaries before performing tasks
|
2
|
+
before "db:backup", "binaries:check"
|
3
|
+
before "db:create", "binaries:check"
|
4
|
+
before "db:list_backups", "binaries:check"
|
5
|
+
before "db:pull", "binaries:check"
|
6
|
+
before "db:push", "binaries:check"
|
7
|
+
before "db:reset", "binaries:check"
|
8
|
+
before "db:restore", "binaries:check"
|
9
|
+
before "deploy", "binaries:check"
|
10
|
+
before "htaccess:pull", "binaries:check"
|
11
|
+
before "htaccess:push", "binaries:check"
|
12
|
+
before "uploads:pull", "binaries:check"
|
13
|
+
before "uploads:push", "binaries:check"
|
14
|
+
before "uploads:setperms", "binaries:check"
|
15
|
+
before "wp:core:download", "binaries:check"
|
16
|
+
before "wp:core:remove", "binaries:check"
|
17
|
+
|
18
|
+
# Check directories before performing tasks
|
19
|
+
before "config:generate", "deploy:check:directories"
|
20
|
+
before "db:backup", "deploy:check:directories"
|
21
|
+
before "db:create", "deploy:check:directories"
|
22
|
+
before "db:list_backups", "deploy:check:directories"
|
23
|
+
before "db:pull", "deploy:check:directories"
|
24
|
+
before "db:push", "deploy:check:directories"
|
25
|
+
before "db:reset", "deploy:check:directories"
|
26
|
+
before "db:restore", "deploy:check:directories"
|
27
|
+
before "deploy:shared_configs", "deploy:check:directories"
|
28
|
+
before "htaccess:pull", "deploy:check:directories"
|
29
|
+
before "htaccess:push", "deploy:check:directories"
|
30
|
+
before "robots:generate", "deploy:check:directories"
|
31
|
+
before "uploads:pull", "deploy:check:directories"
|
32
|
+
before "uploads:push", "deploy:check:directories"
|
33
|
+
|
34
|
+
# Check if maintenance mode should be enabled before pushing the database
|
35
|
+
before "db:push", "db:check_maintenance_enable"
|
36
|
+
|
37
|
+
# Create the MySQL database before pushing content to it
|
38
|
+
before "db:push", "db:create"
|
39
|
+
|
40
|
+
# Backup the database before pushing
|
41
|
+
before "db:push", "db:backup"
|
42
|
+
|
43
|
+
# Check if maintenance mode should be enabled before restoring the database
|
44
|
+
before "db:restore", "db:check_maintenance_enable"
|
45
|
+
|
46
|
+
# Create the database before restoring
|
47
|
+
before "db:restore", "db:create"
|
48
|
+
|
49
|
+
# Deploy shared configuration files before deploying
|
50
|
+
before "deploy", "deploy:shared_configs"
|
51
|
+
|
52
|
+
# Move the database backup from the release we rolled away from
|
53
|
+
# into the release's root before it's archived
|
54
|
+
before "deploy:cleanup_rollback", "db:cleanup_rollback_database"
|
55
|
+
|
56
|
+
# Load the local WordPress version so that when downloading the
|
57
|
+
# WordPress core on a remote server, the version matches the local installation.
|
58
|
+
before "deploy:updated", "wp:core:load_local_version"
|
59
|
+
|
60
|
+
# Remove the existing WordPress core before downloading a new one
|
61
|
+
before "wp:core:download", "wp:core:remove"
|
62
|
+
|
63
|
+
# Download the WordPress core files before finishing deploy:updated
|
64
|
+
before "deploy:updated", "wp:core:download"
|
65
|
+
|
66
|
+
# Link the release into the website root
|
67
|
+
after "deploy:finished", "webroot:symlink"
|
68
|
+
|
69
|
+
# Touch the release directory after deploying
|
70
|
+
# This is required as after the first deployment, we enable
|
71
|
+
# maintenance mode for every subsequent deployment. This causes
|
72
|
+
# the previous release directory to have a newer timestamp than
|
73
|
+
# the new release directory which leads to issues with the rollback
|
74
|
+
# feature as the releases directory is sorted by modification time
|
75
|
+
# when capistrano looks for the release to rollback to.
|
76
|
+
after "deploy:finishing", "deploy:touch_release"
|
77
|
+
|
78
|
+
# Set permissions on the resources after deploying them
|
79
|
+
after "config:generate", "config:setperms"
|
80
|
+
after "htaccess:push", "htaccess:setperms"
|
81
|
+
after "robots:generate", "robots:setperms"
|
82
|
+
after "uploads:push", "uploads:setperms"
|
83
|
+
after "deploy:finished", "webroot:setperms"
|
84
|
+
|
85
|
+
# Check if maintenance mode should be disabled after pushing the database
|
86
|
+
after "db:push", "db:check_maintenance_disable"
|
87
|
+
|
88
|
+
# Check if maintenance mode should be disabled after restoring the database
|
89
|
+
after "db:restore", "db:check_maintenance_disable"
|
90
|
+
|
91
|
+
# Push the local resources after finishing deploy:updated
|
92
|
+
after "deploy:reverted", "db:rollback"
|
93
|
+
after "deploy:updated", "htaccess:push"
|
94
|
+
after "deploy:updated", "uploads:push"
|
95
|
+
after "deploy:updated", "db:push" # We want this to happen last so leave it here :)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
namespace :binaries do
|
2
|
+
desc "Check that all required binaries are installed"
|
3
|
+
task :check do
|
4
|
+
next if true == fetch(:checked_binaries)
|
5
|
+
|
6
|
+
required_binaries = {
|
7
|
+
local: [:php, :rm, :rsync, :wp],
|
8
|
+
remote: {
|
9
|
+
:all => [:chmod, :find, :rm, :wp],
|
10
|
+
:app => [:ln, :readlink, :rsync],
|
11
|
+
:db => [:du, :grep, :mysqlshow]
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
run_locally do
|
16
|
+
required_binaries[:local].each do |binary|
|
17
|
+
unless test :which, binary
|
18
|
+
abort "The binary '#{binary}' is missing from the local system"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
required_binaries[:remote].each do |role, binaries|
|
24
|
+
on roles(role) do |server|
|
25
|
+
binaries.each do |binary|
|
26
|
+
unless test :which, binary
|
27
|
+
abort "The binary '#{binary}' is missing from #{server.user}@#{server.hostname}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
set :checked_binaries, true
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
namespace :config do
|
2
|
+
desc "Generate a wp-config.php file"
|
3
|
+
task :generate do
|
4
|
+
file = "wp-config.php"
|
5
|
+
|
6
|
+
local_path = File.join(Dir.pwd, file)
|
7
|
+
remote_path = File.join(shared_path, file)
|
8
|
+
|
9
|
+
template_path = File.join("config", "templates", "#{file}.erb")
|
10
|
+
template_content = File.read(template_path)
|
11
|
+
|
12
|
+
run_locally do
|
13
|
+
database_config = fetch(:local_database_config)
|
14
|
+
|
15
|
+
unless database_config.has_keys? :hostname, :username, :database, :password
|
16
|
+
abort "The local database configuration is invalid"
|
17
|
+
end
|
18
|
+
|
19
|
+
database_hostname = database_config[:hostname]
|
20
|
+
database_username = database_config[:username]
|
21
|
+
database_name = database_config[:database]
|
22
|
+
database_password = database_config[:password]
|
23
|
+
|
24
|
+
secret_keys = Net::HTTP.get URI("https://api.wordpress.org/secret-key/1.1/salt")
|
25
|
+
|
26
|
+
if secret_keys.nil? or secret_keys.empty?
|
27
|
+
abort "Unable to fetch secret keys using the WordPress API"
|
28
|
+
end
|
29
|
+
|
30
|
+
configuration = ERB.new(template_content).result(binding)
|
31
|
+
|
32
|
+
if test("[ -f #{local_path} ]")
|
33
|
+
execute :rm, "-f", local_path
|
34
|
+
end
|
35
|
+
|
36
|
+
info "Writing local #{file} file"
|
37
|
+
|
38
|
+
File.write(local_path, configuration)
|
39
|
+
end
|
40
|
+
|
41
|
+
database_config = fetch(:database_config)
|
42
|
+
|
43
|
+
unless database_config.has_keys? :hostname, :username, :database, :password
|
44
|
+
abort "The #{fetch(:stage)} database configuration is invalid"
|
45
|
+
end
|
46
|
+
|
47
|
+
database_hostname = database_config[:hostname]
|
48
|
+
database_username = database_config[:username]
|
49
|
+
database_name = database_config[:database]
|
50
|
+
database_password = database_config[:password]
|
51
|
+
|
52
|
+
secret_keys = Net::HTTP.get URI("https://api.wordpress.org/secret-key/1.1/salt")
|
53
|
+
|
54
|
+
if secret_keys.nil? or secret_keys.empty?
|
55
|
+
abort "Unable to fetch secret keys using the WordPress API"
|
56
|
+
end
|
57
|
+
|
58
|
+
configuration = ERB.new(template_content).result(binding)
|
59
|
+
|
60
|
+
on roles(:app) do |server|
|
61
|
+
if test("[ -f #{remote_path} ]")
|
62
|
+
execute :rm, "-f", remote_path
|
63
|
+
end
|
64
|
+
|
65
|
+
upload! StringIO.new(configuration), remote_path
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
desc "Set permissions on the wp-config.php file"
|
70
|
+
task :setperms do
|
71
|
+
on roles(:app) do |server|
|
72
|
+
file = "wp-config.php"
|
73
|
+
|
74
|
+
remote_path = File.join(shared_path, file)
|
75
|
+
|
76
|
+
unless test("[ -f #{remote_path} ]")
|
77
|
+
error "A #{file} file does not exist on #{server.user}@#{server.hostname}"
|
78
|
+
end
|
79
|
+
|
80
|
+
info "Setting permissions for #{file} on #{server.user}@#{server.hostname}"
|
81
|
+
|
82
|
+
execute :chmod, 644, remote_path
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,355 @@
|
|
1
|
+
namespace :db do
|
2
|
+
desc "Pull down the WordPress database"
|
3
|
+
task :pull do
|
4
|
+
file = "#{SecureRandom.hex(8)}.sql"
|
5
|
+
|
6
|
+
local_path = File.join(Dir.pwd, file)
|
7
|
+
remote_path = File.join(fetch(:tmp_dir), file)
|
8
|
+
|
9
|
+
next if 0 == roles(:db).count
|
10
|
+
|
11
|
+
if 1 < roles(:db).count
|
12
|
+
run_locally do
|
13
|
+
info "Found #{roles(:db).count} database servers"
|
14
|
+
|
15
|
+
roles(:db).each_with_index do |server, index|
|
16
|
+
info "#{index + 1}) #{server.user}@#{server.hostname} (Port #{server.port or 22})"
|
17
|
+
end
|
18
|
+
|
19
|
+
set :database_pull_server, ask("the number of the server to pull the database from", "1")
|
20
|
+
end
|
21
|
+
else
|
22
|
+
set :database_pull_server, "1"
|
23
|
+
end
|
24
|
+
|
25
|
+
database_pull_server = fetch(:database_pull_server).to_i
|
26
|
+
|
27
|
+
if 1 > database_pull_server or roles(:db).count < database_pull_server
|
28
|
+
run_locally do
|
29
|
+
error "Unable to locate a server with an id '#{database_pull_server}'"
|
30
|
+
end
|
31
|
+
|
32
|
+
next
|
33
|
+
end
|
34
|
+
|
35
|
+
database_pull_server = roles(:db)[database_pull_server - 1]
|
36
|
+
|
37
|
+
on roles(:db) do |server|
|
38
|
+
next unless server.matches? database_pull_server
|
39
|
+
|
40
|
+
info "Pulling WordPress database from #{server.user}@#{server.hostname}"
|
41
|
+
|
42
|
+
within release_path do
|
43
|
+
execute :wp, "db", "export", remote_path
|
44
|
+
end
|
45
|
+
|
46
|
+
download! remote_path, local_path
|
47
|
+
|
48
|
+
execute :rm, "-f", remote_path
|
49
|
+
|
50
|
+
run_locally do
|
51
|
+
execute :wp, "db", "import", local_path
|
52
|
+
execute :rm, "-f", local_path
|
53
|
+
|
54
|
+
if fetch(:local_site_url) and fetch(:site_url)
|
55
|
+
execute :wp, "search-replace", fetch(:site_url), fetch(:local_site_url)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
set :database_pull_server, nil
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "Push up the WordPress database"
|
64
|
+
task :push do
|
65
|
+
file = "#{SecureRandom.hex(8)}.sql"
|
66
|
+
|
67
|
+
local_path = File.join(Dir.pwd, file)
|
68
|
+
remote_path = File.join(fetch(:tmp_dir), file)
|
69
|
+
|
70
|
+
on roles(:db) do |server|
|
71
|
+
info "Pushing WordPress database to #{server.user}@#{server.hostname}"
|
72
|
+
|
73
|
+
run_locally do
|
74
|
+
execute :wp, "db", "export", local_path
|
75
|
+
end
|
76
|
+
|
77
|
+
upload! local_path, remote_path
|
78
|
+
|
79
|
+
run_locally do
|
80
|
+
execute :rm, "-f", local_path
|
81
|
+
end
|
82
|
+
|
83
|
+
within release_path do
|
84
|
+
execute :wp, "db", "import", remote_path
|
85
|
+
execute :rm, "-f", remote_path
|
86
|
+
|
87
|
+
if fetch(:local_site_url) and fetch(:site_url)
|
88
|
+
execute :wp, "search-replace", fetch(:local_site_url), fetch(:site_url)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
desc "Create the MySQL database"
|
95
|
+
task :create do
|
96
|
+
database_config = fetch(:database_config)
|
97
|
+
|
98
|
+
unless database_config.has_keys? :hostname, :username, :database, :password
|
99
|
+
abort "The #{fetch(:stage)} database configuration is invalid"
|
100
|
+
end
|
101
|
+
|
102
|
+
database_name = database_config[:database]
|
103
|
+
database_hostname = database_config[:hostname]
|
104
|
+
database_username = database_config[:username]
|
105
|
+
database_password = database_config[:password]
|
106
|
+
|
107
|
+
on roles(:db) do |server|
|
108
|
+
within release_path do
|
109
|
+
if test("[ \"#{database_name}\" == $(mysqlshow --user=\"#{database_username}\" --password=\"#{database_password}\" #{database_name} | grep -v Wildcard | grep -o #{database_name}) ]")
|
110
|
+
info "The MySQL database already exists on #{server.user}@#{server.hostname}"
|
111
|
+
|
112
|
+
next
|
113
|
+
end
|
114
|
+
|
115
|
+
info "Creating MySQL database on #{server.user}@#{server.hostname}"
|
116
|
+
|
117
|
+
execute :wp, "db", "create"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
desc "Drop the MySQL database"
|
123
|
+
task :drop do
|
124
|
+
database_config = fetch(:database_config)
|
125
|
+
|
126
|
+
unless database_config.has_keys? :hostname, :username, :database, :password
|
127
|
+
abort "The #{fetch(:stage)} database configuration is invalid"
|
128
|
+
end
|
129
|
+
|
130
|
+
database_name = database_config[:database]
|
131
|
+
database_hostname = database_config[:hostname]
|
132
|
+
database_username = database_config[:username]
|
133
|
+
database_password = database_config[:password]
|
134
|
+
|
135
|
+
on roles(:db) do |server|
|
136
|
+
within release_path do
|
137
|
+
unless test("[ \"#{database_name}\" == $(mysqlshow --user=\"#{database_username}\" --password=\"#{database_password}\" #{database_name} | grep -v Wildcard | grep -o #{database_name}) ]")
|
138
|
+
info "The MySQL database does not exist on #{server.user}@#{server.hostname}"
|
139
|
+
|
140
|
+
next
|
141
|
+
end
|
142
|
+
|
143
|
+
info "Deleting MySQL database on #{server.user}@#{server.hostname}"
|
144
|
+
|
145
|
+
execute :wp, "db", "drop", "--yes"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
desc "Reset the MySQL database"
|
151
|
+
task :reset do
|
152
|
+
on roles(:db) do |server|
|
153
|
+
within release_path do
|
154
|
+
unless test :wp, "core", "is-installed"
|
155
|
+
info "The WordPress database does not appear to be installed on #{server.user}@#{server.hostname}"
|
156
|
+
|
157
|
+
next
|
158
|
+
end
|
159
|
+
|
160
|
+
info "Resetting the WordPress database on #{server.user}@#{server.hostname}"
|
161
|
+
|
162
|
+
execute :wp, "db", "reset", "--yes"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
desc "Create a backup of the WordPress database"
|
168
|
+
task :backup do
|
169
|
+
backups_directory = File.join(fetch(:deploy_to), "backups", "database")
|
170
|
+
|
171
|
+
on roles(:db) do |server|
|
172
|
+
next unless test("[ -d #{current_path} ]")
|
173
|
+
|
174
|
+
actual_current_path = capture("readlink -f #{current_path}").strip
|
175
|
+
|
176
|
+
file = File.basename(actual_current_path)
|
177
|
+
file = "#{file}.sql"
|
178
|
+
|
179
|
+
remote_path = File.join(backups_directory, file)
|
180
|
+
|
181
|
+
info "Backing up WordPress database on #{server.user}@#{server.hostname}"
|
182
|
+
|
183
|
+
execute :mkdir, "-p", backups_directory
|
184
|
+
|
185
|
+
if test("[ -f #{remote_path} ]")
|
186
|
+
execute :rm, "-f", remote_path
|
187
|
+
end
|
188
|
+
|
189
|
+
within release_path do
|
190
|
+
execute :wp, "db", "export", remote_path
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
desc "Restore a backup of the WordPress database"
|
196
|
+
task :restore do
|
197
|
+
backups_directory = File.join(fetch(:deploy_to), "backups", "database")
|
198
|
+
|
199
|
+
backup_id = fetch(:rollback_timestamp, ENV["id"])
|
200
|
+
|
201
|
+
unless backup_id
|
202
|
+
run_locally do
|
203
|
+
info "No backup id provided to restore database backup"
|
204
|
+
end
|
205
|
+
|
206
|
+
next
|
207
|
+
end
|
208
|
+
|
209
|
+
on roles(:db) do |server|
|
210
|
+
file = "#{backup_id}.sql"
|
211
|
+
|
212
|
+
remote_path = File.join(backups_directory, file)
|
213
|
+
|
214
|
+
unless test("[ -f #{remote_path} ]")
|
215
|
+
info "Could not find database backup #{backup_id} on #{server.user}@#{server.hostname}"
|
216
|
+
|
217
|
+
next
|
218
|
+
end
|
219
|
+
|
220
|
+
info "Restoring WordPress database #{backup_id} on #{server.user}@#{server.hostname}"
|
221
|
+
|
222
|
+
within release_path do
|
223
|
+
execute :wp, "db", "import", remote_path
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
desc "List all WordPress database backups"
|
229
|
+
task :list_backups do
|
230
|
+
on roles(:db) do |server|
|
231
|
+
next unless server.matches? roles(:db).first # Hack to make sure we run only once
|
232
|
+
|
233
|
+
backups_directory = File.join(fetch(:deploy_to), "backups", "database")
|
234
|
+
|
235
|
+
unless test("[ -d #{backups_directory} ]")
|
236
|
+
info "No database backups found"
|
237
|
+
|
238
|
+
next
|
239
|
+
end
|
240
|
+
|
241
|
+
backup_paths = capture("find #{backups_directory} -name '*.sql' -maxdepth 1")
|
242
|
+
|
243
|
+
if backup_paths.nil? or backup_paths.empty?
|
244
|
+
info "No database backups found"
|
245
|
+
|
246
|
+
next
|
247
|
+
end
|
248
|
+
|
249
|
+
if 1 == backup_paths.lines.count
|
250
|
+
info "Found 1 database backup"
|
251
|
+
else
|
252
|
+
info "Found #{backup_paths.lines.count} database backups"
|
253
|
+
end
|
254
|
+
|
255
|
+
backup_paths.each_line do |backup_path|
|
256
|
+
backup_path = backup_path.strip
|
257
|
+
|
258
|
+
backup_basename = File.basename(backup_path).gsub(".sql", "").strip
|
259
|
+
|
260
|
+
backup_time = Time.parse(backup_basename)
|
261
|
+
backup_time = backup_time.strftime("%A #{backup_time.day.ordinalize} %B %Y at %H:%M:%S")
|
262
|
+
|
263
|
+
backup_size = capture("du -h #{backup_path} | awk '{ print \$1 }'")
|
264
|
+
|
265
|
+
info "#{backup_time} - #{backup_size} (ID: #{backup_basename})"
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
# Rollback the WordPress database
|
271
|
+
# This is only useful when called during a deploy:rollback task
|
272
|
+
task :rollback do
|
273
|
+
actual_current_path = nil
|
274
|
+
actual_release_path = nil
|
275
|
+
|
276
|
+
on roles(:db) do |server|
|
277
|
+
next unless server.matches? roles(:db).first # Hack to make sure we run only once
|
278
|
+
|
279
|
+
actual_current_path = capture("readlink -f #{current_path}").strip
|
280
|
+
actual_release_path = capture("readlink -f #{release_path}").strip
|
281
|
+
end
|
282
|
+
|
283
|
+
if actual_current_path == actual_release_path
|
284
|
+
run_locally do
|
285
|
+
error "This task is only useful when called during a deploy:rollback task!"
|
286
|
+
end
|
287
|
+
|
288
|
+
next
|
289
|
+
end
|
290
|
+
|
291
|
+
invoke 'db:backup'
|
292
|
+
invoke 'db:restore'
|
293
|
+
|
294
|
+
set :rollback_from_timestamp, File.basename(actual_current_path)
|
295
|
+
end
|
296
|
+
|
297
|
+
# Move the database backup from the release we rolled away from
|
298
|
+
# into the release's root before it's archived
|
299
|
+
task :cleanup_rollback_database do
|
300
|
+
rollback_from_timestamp = fetch(:rollback_from_timestamp)
|
301
|
+
|
302
|
+
unless :rollback_from_timestamp
|
303
|
+
run_locally do
|
304
|
+
error "No timestamp set for the release we rolled away from"
|
305
|
+
end
|
306
|
+
|
307
|
+
next
|
308
|
+
end
|
309
|
+
|
310
|
+
file = "#{rollback_from_timestamp}.sql"
|
311
|
+
|
312
|
+
backups_directory = File.join(fetch(:deploy_to), "backups", "database")
|
313
|
+
|
314
|
+
source_path = File.join(backups_directory, file)
|
315
|
+
destination_path = File.join(releases_path, rollback_from_timestamp, file)
|
316
|
+
|
317
|
+
on roles(:db) do |server|
|
318
|
+
unless test("[ -f #{source_path} ]")
|
319
|
+
error "The database backup file does not exist on #{server.user}@#{server.hostname}"
|
320
|
+
|
321
|
+
next
|
322
|
+
end
|
323
|
+
|
324
|
+
info "Moving database backup #{rollback_from_timestamp} into release on #{server.user}@#{server.hostname}"
|
325
|
+
|
326
|
+
execute :mv, source_path, destination_path
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
# Enable maintenance mode if WordPress is already installed (used by db:push)
|
331
|
+
task :check_maintenance_enable do
|
332
|
+
maintenance_path = File.join(current_path, ".maintenance")
|
333
|
+
|
334
|
+
on roles(:db) do
|
335
|
+
next unless test("[ -d #{current_path} ]")
|
336
|
+
next if test("[ -f #{maintenance_path} ]")
|
337
|
+
next if true == fetch(:db_enabled_maintenance_mode)
|
338
|
+
|
339
|
+
within current_path do
|
340
|
+
if test :wp, "core", "is-installed"
|
341
|
+
set :db_enabled_maintenance_mode, true
|
342
|
+
|
343
|
+
invoke 'maintenance:enable'
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
# Disable maintenance mode if it was enabled by check_maintenance_enable
|
350
|
+
task :check_maintenance_disable do
|
351
|
+
next unless true == fetch(:db_enabled_maintenance_mode)
|
352
|
+
|
353
|
+
invoke 'maintenance:disable'
|
354
|
+
end
|
355
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
namespace :deploy do
|
2
|
+
task :shared_configs do
|
3
|
+
config_path = File.join(shared_path, "wp-config.php")
|
4
|
+
robots_path = File.join(shared_path, "robots.txt")
|
5
|
+
|
6
|
+
on roles(:app) do
|
7
|
+
unless test("[ -f #{config_path} ]")
|
8
|
+
invoke "config:generate"
|
9
|
+
end
|
10
|
+
|
11
|
+
unless test("[ -f #{robots_path} ]")
|
12
|
+
invoke "robots:generate"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
task :touch_release do
|
18
|
+
on roles(:app) do |server|
|
19
|
+
info "Touching release directory on #{server.user}@#{server.hostname}"
|
20
|
+
|
21
|
+
execute :touch, release_path
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
namespace :htaccess do
|
2
|
+
desc "Pull down the .htaccess file"
|
3
|
+
task :pull do
|
4
|
+
file = ".htaccess"
|
5
|
+
|
6
|
+
remote_file = File.join(release_path, file)
|
7
|
+
|
8
|
+
next if 0 == roles(:app).count
|
9
|
+
|
10
|
+
if 1 < roles(:app).count
|
11
|
+
run_locally do
|
12
|
+
info "Found #{roles(:app).count} application servers"
|
13
|
+
|
14
|
+
roles(:app).each_with_index do |server, index|
|
15
|
+
info "#{index + 1}) #{server.user}@#{server.hostname} (Port #{server.port or 22})"
|
16
|
+
end
|
17
|
+
|
18
|
+
set :htaccess_pull_server, ask("the number of the server to pull the #{file} file from", "1")
|
19
|
+
end
|
20
|
+
else
|
21
|
+
set :htaccess_pull_server, "1"
|
22
|
+
end
|
23
|
+
|
24
|
+
htaccess_pull_server = fetch(:htaccess_pull_server).to_i
|
25
|
+
|
26
|
+
if 1 > htaccess_pull_server or roles(:app).count < htaccess_pull_server
|
27
|
+
run_locally do
|
28
|
+
error "Unable to locate a server with an id '#{htaccess_pull_server}'"
|
29
|
+
end
|
30
|
+
|
31
|
+
next
|
32
|
+
end
|
33
|
+
|
34
|
+
htaccess_pull_server = roles(:app)[htaccess_pull_server - 1]
|
35
|
+
|
36
|
+
on roles(:app) do |server|
|
37
|
+
next unless server.matches? htaccess_pull_server
|
38
|
+
|
39
|
+
unless test("[ -f #{remote_file} ]")
|
40
|
+
error "There isn't a #{file} file on #{server.user}@#{server.hostname}"
|
41
|
+
|
42
|
+
next
|
43
|
+
end
|
44
|
+
|
45
|
+
if File.file? file
|
46
|
+
local_sha256sum = Digest::SHA256.hexdigest(File.read(file))
|
47
|
+
remote_sha256sum = capture("sha256sum #{remote_file}").split(' ').first
|
48
|
+
|
49
|
+
if local_sha256sum == remote_sha256sum
|
50
|
+
info "No changes detected in #{file} file on #{server.user}@#{server.hostname}"
|
51
|
+
|
52
|
+
next
|
53
|
+
end
|
54
|
+
|
55
|
+
unless fetch(:confirm_pull_htaccess)
|
56
|
+
set :confirm_pull_htaccess, ask("confirmation for local #{file} file overwrite", "Y/n")
|
57
|
+
end
|
58
|
+
|
59
|
+
next unless [true, "y", "yes"].include? fetch(:confirm_pull_htaccess).downcase
|
60
|
+
end
|
61
|
+
|
62
|
+
info "Pulling #{file} file from #{server.user}@#{server.hostname}"
|
63
|
+
|
64
|
+
download! remote_file, file
|
65
|
+
|
66
|
+
break
|
67
|
+
end
|
68
|
+
|
69
|
+
set :htaccess_pull_server, nil
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "Push up the .htaccess file"
|
73
|
+
task :push do
|
74
|
+
file = ".htaccess"
|
75
|
+
|
76
|
+
local_path = File.join(Dir.pwd, file)
|
77
|
+
remote_path = File.join(release_path, file)
|
78
|
+
|
79
|
+
unless File.file? file
|
80
|
+
run_locally do
|
81
|
+
htaccess = "# BEGIN WordPress\n"
|
82
|
+
htaccess << "<IfModule mod_rewrite.c>\n"
|
83
|
+
htaccess << "RewriteEngine On\n"
|
84
|
+
htaccess << "RewriteBase /\n"
|
85
|
+
htaccess << "RewriteRule ^index\.php$ - [L]\n"
|
86
|
+
htaccess << "RewriteCond %{REQUEST_FILENAME} !-f\n"
|
87
|
+
htaccess << "RewriteCond %{REQUEST_FILENAME} !-d\n"
|
88
|
+
htaccess << "RewriteRule . /index.php [L]\n"
|
89
|
+
htaccess << "</IfModule>\n"
|
90
|
+
htaccess << "# END WordPress\n"
|
91
|
+
|
92
|
+
File.write(local_path, htaccess)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
on roles(:app) do |server|
|
97
|
+
if test("[ -f #{remote_path} ]")
|
98
|
+
local_sha256sum = Digest::SHA256.hexdigest(File.read(local_path))
|
99
|
+
remote_sha256sum = capture("sha256sum #{remote_path}").split(' ').first
|
100
|
+
|
101
|
+
if local_sha256sum == remote_sha256sum
|
102
|
+
info "No changes detected in #{file} on #{server.user}@#{server.hostname}"
|
103
|
+
|
104
|
+
next
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
info "Pushing #{file} file to #{server.user}@#{server.hostname}"
|
109
|
+
|
110
|
+
upload! local_path, remote_path
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
desc "Set permissions on the .htaccess file"
|
115
|
+
task :setperms do
|
116
|
+
file = ".htaccess"
|
117
|
+
|
118
|
+
remote_path = File.join(release_path, file)
|
119
|
+
|
120
|
+
on roles(:app) do |server|
|
121
|
+
unless test("[ -f #{remote_path} ]")
|
122
|
+
info "No #{file} file found on #{server.user}@#{server.hostname}"
|
123
|
+
|
124
|
+
next
|
125
|
+
end
|
126
|
+
|
127
|
+
info "Setting permissions for #{file} on #{server.user}@#{server.hostname}"
|
128
|
+
|
129
|
+
execute :chmod, 644, remote_path
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
namespace :maintenance do
|
2
|
+
desc "Enable maintenance mode on the WordPress site"
|
3
|
+
task :enable do
|
4
|
+
file = ".maintenance"
|
5
|
+
|
6
|
+
on roles(:app) do |server|
|
7
|
+
actual_current_path = capture("readlink -f #{current_path}").strip
|
8
|
+
|
9
|
+
remote_path = File.join(actual_current_path, file)
|
10
|
+
|
11
|
+
if test("[ -f #{remote_path} ]")
|
12
|
+
info "Maintenance mode is already enabled on #{server.user}@#{server.hostname}"
|
13
|
+
|
14
|
+
next
|
15
|
+
end
|
16
|
+
|
17
|
+
maintenance_info = fetch(:maintenance_info, {
|
18
|
+
title: "Maintenance",
|
19
|
+
header: "This site is currently undergoing maintenance.",
|
20
|
+
body: "Please check back in a moment."
|
21
|
+
})
|
22
|
+
|
23
|
+
file_content = "<?php header('HTTP/1.1 503 Service Unavailable'); ?>\n"
|
24
|
+
file_content << "<?php header('Content-Type: text/html'); ?>\n"
|
25
|
+
file_content << "<!DOCTYPE html>\n"
|
26
|
+
file_content << "<html>\n"
|
27
|
+
file_content << " <head>\n"
|
28
|
+
file_content << " <meta charset=\"utf-8\">\n"
|
29
|
+
file_content << " <meta name=\"viewport\" content=\"initial-scale=1.0\">\n"
|
30
|
+
file_content << " <title>#{maintenance_info[:title]}</title>\n" if maintenance_info.has_key? :title
|
31
|
+
file_content << " </head>\n"
|
32
|
+
file_content << " <body class=\"body\">\n"
|
33
|
+
file_content << " <h1>#{maintenance_info[:header]}</h1>\n" if maintenance_info.has_key? :header
|
34
|
+
file_content << " <h3>#{maintenance_info[:subheader]}</h3>\n" if maintenance_info.has_key? :subheader
|
35
|
+
file_content << " <p>#{maintenance_info[:body]}</p>\n" if maintenance_info.has_key? :body
|
36
|
+
file_content << " </body>\n"
|
37
|
+
file_content << "</html>\n"
|
38
|
+
file_content << "<?php exit; ?>\n"
|
39
|
+
|
40
|
+
info "Enabling WordPress maintenance mode on #{server.user}@#{server.hostname}"
|
41
|
+
|
42
|
+
upload! StringIO.new(file_content), remote_path
|
43
|
+
|
44
|
+
execute :chmod, 644, remote_path
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
desc "Disable maintenance mode on the WordPress site"
|
49
|
+
task :disable do
|
50
|
+
file = ".maintenance"
|
51
|
+
|
52
|
+
on roles(:app) do |server|
|
53
|
+
actual_current_path = capture("readlink -f #{current_path}").strip
|
54
|
+
|
55
|
+
remote_path = File.join(actual_current_path, file)
|
56
|
+
|
57
|
+
unless test("[ -f #{remote_path} ]")
|
58
|
+
info "Maintenance mode is not enabled on #{server.user}@#{server.hostname}"
|
59
|
+
|
60
|
+
next
|
61
|
+
end
|
62
|
+
|
63
|
+
info "Disabling WordPress maintenance mode on #{server.user}@#{server.hostname}"
|
64
|
+
|
65
|
+
execute :rm, "-f", remote_path
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
namespace :robots do
|
2
|
+
desc "Generate a robots.txt file"
|
3
|
+
task :generate do
|
4
|
+
file = "robots.txt"
|
5
|
+
|
6
|
+
remote_path = File.join(shared_path, file)
|
7
|
+
|
8
|
+
on roles(:app) do |server|
|
9
|
+
info "Generating a #{file} file on #{server.user}@#{server.hostname}"
|
10
|
+
|
11
|
+
if :production != fetch(:stage)
|
12
|
+
debug "Disallowing all user agents in #{file} on #{server.user}@#{server.hostname}"
|
13
|
+
|
14
|
+
upload! StringIO.new("User-agent: *\nDisallow: /"), remote_path
|
15
|
+
else
|
16
|
+
upload! StringIO.new, remote_path
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Set permissions on the robots.txt file"
|
22
|
+
task :setperms do
|
23
|
+
file = "robots.txt"
|
24
|
+
|
25
|
+
remote_path = File.join(shared_path, file)
|
26
|
+
|
27
|
+
on roles(:app) do |server|
|
28
|
+
unless test("[ -f #{remote_path} ]")
|
29
|
+
error "A #{file} file does not exist on #{server.user}@#{server.hostname}"
|
30
|
+
end
|
31
|
+
|
32
|
+
info "Setting permissions for #{file} on #{server.user}@#{server.hostname}"
|
33
|
+
|
34
|
+
execute :chmod, 644, remote_path
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
namespace :uploads do
|
2
|
+
desc "Pull down the uploads directory"
|
3
|
+
task :pull do
|
4
|
+
directory = File.join("wp-content", "uploads")
|
5
|
+
|
6
|
+
local_path = File.join(Dir.pwd, directory)
|
7
|
+
remote_path = File.join(release_path, directory)
|
8
|
+
|
9
|
+
next if 0 == roles(:app).count
|
10
|
+
|
11
|
+
if 1 < roles(:app).count
|
12
|
+
run_locally do
|
13
|
+
info "Found #{roles(:app).count} application servers"
|
14
|
+
|
15
|
+
roles(:app).each_with_index do |server, index|
|
16
|
+
info "#{index + 1}) #{server.user}@#{server.hostname} (Port #{server.port or 22})"
|
17
|
+
end
|
18
|
+
|
19
|
+
set :uploads_pull_server, ask("the number of the server to pull the #{directory} directory from", "1")
|
20
|
+
end
|
21
|
+
else
|
22
|
+
set :uploads_pull_server, "1"
|
23
|
+
end
|
24
|
+
|
25
|
+
uploads_pull_server = fetch(:uploads_pull_server).to_i
|
26
|
+
|
27
|
+
if 1 > uploads_pull_server or roles(:app).count < uploads_pull_server
|
28
|
+
run_locally do
|
29
|
+
error "Unable to locate a server with an id '#{uploads_pull_server}'"
|
30
|
+
end
|
31
|
+
|
32
|
+
next
|
33
|
+
end
|
34
|
+
|
35
|
+
uploads_pull_server = roles(:app)[uploads_pull_server - 1]
|
36
|
+
|
37
|
+
on roles(:app) do |server|
|
38
|
+
next unless server.matches? uploads_pull_server
|
39
|
+
|
40
|
+
unless test("[ -d #{remote_path} ]")
|
41
|
+
error "There isn't a #{directory} directory on #{server.user}@#{server.hostname}"
|
42
|
+
|
43
|
+
next
|
44
|
+
end
|
45
|
+
|
46
|
+
run_locally do
|
47
|
+
execute :mkdir, "-p", local_path
|
48
|
+
end
|
49
|
+
|
50
|
+
info "Pulling #{directory} directory from #{server.user}@#{server.hostname}"
|
51
|
+
|
52
|
+
# Fix for rsync
|
53
|
+
remote_path += "/"
|
54
|
+
|
55
|
+
run_locally do
|
56
|
+
execute :rsync, "-lrtvzO", "--delete-before", (server.port ? "-e 'ssh -p #{server.port}'" : nil), "#{server.user}@#{server.hostname}:#{remote_path}", local_path
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
set :uploads_pull_server, nil
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "Push up the uploads directory"
|
64
|
+
task :push do
|
65
|
+
directory = File.join("wp-content", "uploads")
|
66
|
+
|
67
|
+
local_path = File.join(Dir.pwd, directory)
|
68
|
+
remote_path = File.join(release_path, directory)
|
69
|
+
|
70
|
+
unless File.directory? local_path
|
71
|
+
error "No local uploads directory exists"
|
72
|
+
|
73
|
+
next
|
74
|
+
end
|
75
|
+
|
76
|
+
on roles(:app) do |server|
|
77
|
+
if test("[ -d #{current_path} ]") and (ENV["clone_uploads"].nil? or ENV["clone_uploads"].empty? or [true, "true", "yes", "y"].include? ENV["clone_uploads"].downcase)
|
78
|
+
actual_current_path = capture("readlink -f #{current_path}").strip
|
79
|
+
actual_release_path = capture("readlink -f #{release_path}").strip
|
80
|
+
|
81
|
+
previous_remote_path = File.join(actual_current_path, directory)
|
82
|
+
|
83
|
+
if actual_current_path != actual_release_path and test("[ -d #{previous_remote_path} ]")
|
84
|
+
debug "Cloning uploads directory from current release on #{server.user}@#{server.hostname}"
|
85
|
+
|
86
|
+
execute :cp, "-R", "--preserve=timestamps", previous_remote_path, remote_path
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
execute :mkdir, "-p", remote_path
|
91
|
+
|
92
|
+
info "Pushing #{directory} directory to #{server.user}@#{server.hostname}"
|
93
|
+
|
94
|
+
# Fix for rsync
|
95
|
+
local_path += "/"
|
96
|
+
|
97
|
+
run_locally do
|
98
|
+
execute :rsync, "-lrtvzO", "--delete-before", (server.port ? "-e 'ssh -p #{server.port}'" : nil), local_path, "#{server.user}@#{server.hostname}:#{remote_path}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
desc "Set permissions on the uploads directory"
|
104
|
+
task :setperms do
|
105
|
+
directory = File.join("wp-content", "uploads")
|
106
|
+
|
107
|
+
remote_path = File.join(release_path, directory)
|
108
|
+
|
109
|
+
on roles(:app) do |server|
|
110
|
+
unless test("[ -d #{remote_path} ]")
|
111
|
+
error "No uploads directory exists on #{server.user}@#{server.hostname}"
|
112
|
+
|
113
|
+
next
|
114
|
+
end
|
115
|
+
|
116
|
+
info "Setting permissions for the uploads directory on #{server.user}@#{server.hostname}"
|
117
|
+
|
118
|
+
execute :find, remote_path, "-type d", "-exec", :chmod, 755, "{}", "\\;"
|
119
|
+
execute :find, remote_path, "-type f", "-exec", :chmod, 644, "{}", "\\;"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
namespace :webroot do
|
2
|
+
desc "Symlink the current release into the website root"
|
3
|
+
task :symlink do
|
4
|
+
remote_path = fetch(:website_root)
|
5
|
+
|
6
|
+
next unless remote_path
|
7
|
+
|
8
|
+
on roles(:app) do |server|
|
9
|
+
if test("[ -d #{remote_path} ]")
|
10
|
+
execute :rm, "-rf", remote_path
|
11
|
+
end
|
12
|
+
|
13
|
+
info "Symlinking the current release into the website root on #{server.user}@#{server.hostname}"
|
14
|
+
|
15
|
+
execute :ln, "-nfs", release_path, remote_path
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Set permissions on the uploads directory"
|
20
|
+
task :setperms do
|
21
|
+
remote_path = fetch(:website_root)
|
22
|
+
|
23
|
+
next unless remote_path
|
24
|
+
|
25
|
+
on roles(:app) do |server|
|
26
|
+
unless test("[ -d #{remote_path} ]")
|
27
|
+
error "No website root directory exists on #{server.user}@#{server.hostname}"
|
28
|
+
|
29
|
+
next
|
30
|
+
end
|
31
|
+
|
32
|
+
info "Setting permissions for the website root directory on #{server.user}@#{server.hostname}"
|
33
|
+
|
34
|
+
execute :find, remote_path, "-type d", "-exec", :chmod, 755, "{}", "\\;"
|
35
|
+
execute :find, remote_path, "-type f", "-exec", :chmod, 644, "{}", "\\;"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
namespace :wp do
|
2
|
+
namespace :core do
|
3
|
+
# Load the local version (for use with wp:core:deploy)
|
4
|
+
task :load_local_version do
|
5
|
+
run_locally do
|
6
|
+
version_script_path = File.join(Dir.pwd, "wp-includes", "version.php")
|
7
|
+
|
8
|
+
unless File.file? version_script_path
|
9
|
+
abort "No valid WordPress installation could be found locally"
|
10
|
+
end
|
11
|
+
|
12
|
+
set :wp_version, capture("php -r \"include '#{version_script_path}'; echo \\$wp_version;\"")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Download the WordPress core files into the release"
|
17
|
+
task :download do
|
18
|
+
on roles(:app) do |server|
|
19
|
+
version = fetch(:wp_version, ENV["version"])
|
20
|
+
|
21
|
+
info "Downloading WordPress Core" + (version ? " (Version #{version})" : "")
|
22
|
+
|
23
|
+
tmp_dir = File.join(fetch(:tmp_dir), SecureRandom.hex(8))
|
24
|
+
|
25
|
+
execute :mkdir, "-p", tmp_dir
|
26
|
+
|
27
|
+
within tmp_dir do
|
28
|
+
execute :wp, "core", "download", (version ? "--version=#{version}" : "")
|
29
|
+
|
30
|
+
excludes = [".", "license.txt", "readme.html", "wp-config-sample.php", "wp-content"]
|
31
|
+
excludes = excludes.map { |e| "! -name '#{e}' " }.join(" ").squeeze(" ").strip
|
32
|
+
|
33
|
+
paths = capture :find, ".", "-maxdepth 1", excludes
|
34
|
+
paths = paths.split("\n")
|
35
|
+
paths.each do |path|
|
36
|
+
execute :cp, "-R", path, release_path
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
execute :rm, "-rf", tmp_dir
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "Remove the WordPress core files from the release"
|
45
|
+
task :remove do
|
46
|
+
on roles(:app) do
|
47
|
+
within release_path do
|
48
|
+
paths = []
|
49
|
+
|
50
|
+
excludes = [".", "wp-config.php", "wp-content"]
|
51
|
+
excludes = excludes.map { |e| "! -name '#{e}' " }.join(" ").squeeze(" ").strip
|
52
|
+
|
53
|
+
["index.php", "wp-*", "xmlrpc.php"].each do |glob|
|
54
|
+
find_output = capture :find, ".", "-maxdepth 1", "-name '#{glob}'", excludes
|
55
|
+
|
56
|
+
paths.concat(find_output.split("\n"))
|
57
|
+
end
|
58
|
+
|
59
|
+
next if 1 > paths.length
|
60
|
+
|
61
|
+
info "Removing #{paths.length} WordPress core file(s)"
|
62
|
+
|
63
|
+
paths.each do |path|
|
64
|
+
execute :rm, "-rf", path
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "Execute a WordPress CLI command"
|
72
|
+
task :exec do
|
73
|
+
set :wp_exec_command, ask("The WordPress CLI command to execute", "help")
|
74
|
+
|
75
|
+
unless fetch(:wp_exec_command)
|
76
|
+
abort "You didn't enter a command to execute"
|
77
|
+
end
|
78
|
+
|
79
|
+
on roles(:all) do |server|
|
80
|
+
next if ENV["role"] and !server.roles.map { |role| role.to_s }.include? ENV["role"]
|
81
|
+
|
82
|
+
within release_path do
|
83
|
+
puts capture :wp, fetch(:wp_exec_command)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
set :wp_exec_command, nil
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "securerandom"
|
3
|
+
require "time"
|
4
|
+
|
5
|
+
# Load all helpers and capistrano tasks
|
6
|
+
["wordpress/helpers/**/*.rb", "wordpress/tasks/**/*.rake", "wordpress/hooks.rb"].each do |glob|
|
7
|
+
Dir.glob(File.expand_path(File.join('..', glob), __FILE__)).each do |file_path|
|
8
|
+
load file_path
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Tell capistrano about files we want linked into releases
|
13
|
+
set :linked_files, fetch(:linked_files, []).push("robots.txt", "wp-config.php")
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'capistrano/wordpress'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'wordpresstrano'
|
3
|
+
s.version = '0.2.0'
|
4
|
+
s.date = '2015-08-09'
|
5
|
+
s.authors = ['Nialto Services']
|
6
|
+
s.email = 'support@nialtoservices.co.uk'
|
7
|
+
s.summary = 'Deploy WordPress sites to web servers using Capistrano'
|
8
|
+
s.description = 'Deploy your WordPress sites to web servers like cPanel using the Capistrano deployment tool'
|
9
|
+
s.homepage = 'http://rubygems.org/gems/wordpresstrano'
|
10
|
+
s.files = `git ls-files`.split($/)
|
11
|
+
s.require_paths = ['lib']
|
12
|
+
s.license = 'MIT'
|
13
|
+
|
14
|
+
s.required_ruby_version = '>= 2.0.0'
|
15
|
+
s.add_dependency 'capistrano', '~> 3.0', '>= 3.4.0'
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wordpresstrano
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nialto Services
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-09 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.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.4.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.4.0
|
33
|
+
description: Deploy your WordPress sites to web servers like cPanel using the Capistrano
|
34
|
+
deployment tool
|
35
|
+
email: support@nialtoservices.co.uk
|
36
|
+
executables: []
|
37
|
+
extensions: []
|
38
|
+
extra_rdoc_files: []
|
39
|
+
files:
|
40
|
+
- LICENSE
|
41
|
+
- README.md
|
42
|
+
- lib/capistrano/wordpress.rb
|
43
|
+
- lib/capistrano/wordpress/helpers/fixnum.rb
|
44
|
+
- lib/capistrano/wordpress/helpers/hash.rb
|
45
|
+
- lib/capistrano/wordpress/hooks.rb
|
46
|
+
- lib/capistrano/wordpress/tasks/binaries.rake
|
47
|
+
- lib/capistrano/wordpress/tasks/config.rake
|
48
|
+
- lib/capistrano/wordpress/tasks/database.rake
|
49
|
+
- lib/capistrano/wordpress/tasks/deploy.rake
|
50
|
+
- lib/capistrano/wordpress/tasks/htaccess.rake
|
51
|
+
- lib/capistrano/wordpress/tasks/maintenance.rake
|
52
|
+
- lib/capistrano/wordpress/tasks/robots.rake
|
53
|
+
- lib/capistrano/wordpress/tasks/uploads.rake
|
54
|
+
- lib/capistrano/wordpress/tasks/webroot.rake
|
55
|
+
- lib/capistrano/wordpress/tasks/wordpress.rake
|
56
|
+
- lib/wordpresstrano.rb
|
57
|
+
- wordpresstrano.gemspec
|
58
|
+
homepage: http://rubygems.org/gems/wordpresstrano
|
59
|
+
licenses:
|
60
|
+
- MIT
|
61
|
+
metadata: {}
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 2.0.0
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
requirements: []
|
77
|
+
rubyforge_project:
|
78
|
+
rubygems_version: 2.4.8
|
79
|
+
signing_key:
|
80
|
+
specification_version: 4
|
81
|
+
summary: Deploy WordPress sites to web servers using Capistrano
|
82
|
+
test_files: []
|