statistrano 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/changelog.md +161 -0
- data/doc/config/file-permissions.md +33 -0
- data/doc/config/log-files.md +32 -0
- data/doc/config/task-definitions.md +88 -0
- data/doc/getting-started.md +96 -0
- data/doc/strategies/base.md +38 -0
- data/doc/strategies/branches.md +82 -0
- data/doc/strategies/releases.md +110 -0
- data/doc/strategies.md +17 -0
- data/lib/statistrano/config/configurable.rb +53 -0
- data/lib/statistrano/config/rake_task_with_context_creation.rb +43 -0
- data/lib/statistrano/config.rb +52 -0
- data/lib/statistrano/deployment/log_file.rb +44 -0
- data/lib/statistrano/deployment/manifest.rb +88 -0
- data/lib/statistrano/deployment/rake_tasks.rb +74 -0
- data/lib/statistrano/deployment/registerable.rb +11 -0
- data/lib/statistrano/deployment/releaser/revisions.rb +163 -0
- data/lib/statistrano/deployment/releaser/single.rb +48 -0
- data/lib/statistrano/deployment/releaser.rb +2 -0
- data/lib/statistrano/deployment/strategy/base.rb +132 -0
- data/lib/statistrano/deployment/strategy/branches/index/template.html.erb +78 -0
- data/lib/statistrano/deployment/strategy/branches/index.rb +40 -0
- data/lib/statistrano/deployment/strategy/branches/release.rb +73 -0
- data/lib/statistrano/deployment/strategy/branches.rb +198 -0
- data/lib/statistrano/deployment/strategy/check_git.rb +43 -0
- data/lib/statistrano/deployment/strategy/invoke_tasks.rb +58 -0
- data/lib/statistrano/deployment/strategy/releases.rb +76 -0
- data/lib/statistrano/deployment/strategy.rb +37 -0
- data/lib/statistrano/deployment.rb +10 -0
- data/lib/statistrano/log/default_logger.rb +105 -0
- data/lib/statistrano/log.rb +33 -0
- data/lib/statistrano/remote/file.rb +79 -0
- data/lib/statistrano/remote.rb +111 -0
- data/lib/statistrano/shell.rb +17 -0
- data/lib/statistrano/util/file_permissions.rb +34 -0
- data/lib/statistrano/util.rb +27 -0
- data/lib/statistrano/version.rb +3 -0
- data/lib/statistrano.rb +55 -0
- data/readme.md +247 -0
- data/spec/integration_tests/base_integration_spec.rb +103 -0
- data/spec/integration_tests/branches_integration_spec.rb +189 -0
- data/spec/integration_tests/releases/deploy_integration_spec.rb +116 -0
- data/spec/integration_tests/releases/list_releases_integration_spec.rb +38 -0
- data/spec/integration_tests/releases/prune_releases_integration_spec.rb +86 -0
- data/spec/integration_tests/releases/rollback_release_integration_spec.rb +46 -0
- data/spec/lib/statistrano/config/configurable_spec.rb +88 -0
- data/spec/lib/statistrano/config/rake_task_with_context_creation_spec.rb +73 -0
- data/spec/lib/statistrano/config_spec.rb +34 -0
- data/spec/lib/statistrano/deployment/log_file_spec.rb +75 -0
- data/spec/lib/statistrano/deployment/manifest_spec.rb +171 -0
- data/spec/lib/statistrano/deployment/rake_tasks_spec.rb +107 -0
- data/spec/lib/statistrano/deployment/registerable_spec.rb +19 -0
- data/spec/lib/statistrano/deployment/releaser/revisions_spec.rb +486 -0
- data/spec/lib/statistrano/deployment/releaser/single_spec.rb +59 -0
- data/spec/lib/statistrano/deployment/strategy/base_spec.rb +158 -0
- data/spec/lib/statistrano/deployment/strategy/branches_spec.rb +19 -0
- data/spec/lib/statistrano/deployment/strategy/check_git_spec.rb +39 -0
- data/spec/lib/statistrano/deployment/strategy/invoke_tasks_spec.rb +66 -0
- data/spec/lib/statistrano/deployment/strategy/releases_spec.rb +257 -0
- data/spec/lib/statistrano/deployment/strategy_spec.rb +76 -0
- data/spec/lib/statistrano/deployment_spec.rb +4 -0
- data/spec/lib/statistrano/log/default_logger_spec.rb +172 -0
- data/spec/lib/statistrano/log_spec.rb +36 -0
- data/spec/lib/statistrano/remote/file_spec.rb +166 -0
- data/spec/lib/statistrano/remote_spec.rb +226 -0
- data/spec/lib/statistrano/util/file_permissions_spec.rb +25 -0
- data/spec/lib/statistrano/util_spec.rb +23 -0
- data/spec/lib/statistrano_spec.rb +52 -0
- data/spec/spec_helper.rb +86 -0
- data/spec/support/given.rb +39 -0
- metadata +223 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 01c39986ca62a7822f5408c54b6a8f26895b12e4
|
4
|
+
data.tar.gz: f936b3560996e755990ad64a302b5c4fb63f264a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f4d57e9c63c268d9c328eb4b9d43a1d2deb9a2a7311649149d3faa3065ba438b78a5cf0eaeb9f6ee2a79cedae595658380d6c4bf13ed436febf7cd0a1a88a604
|
7
|
+
data.tar.gz: 7428563bae6150a2d7de3afef2392bb8ca6725f3aa9fc62a6f188960288d500a2cc2c11fb7a4e92315cc3fea8f0eda430fbaf4763d0c88df55ccbe9965728270
|
data/changelog.md
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
# 1.2.0
|
2
|
+
- remote specific config is now tied directly to the remote through it's own config object. Internally this cleans up many checks, but causes [BREAKING] changes if you depended on the API of any of the internal classes. If you use config data in any of your tasks, it's now suggested that you do so inside your `remotes` iterators.
|
3
|
+
- get `Strategy::Branches` supporting multiple remotes. The stdout output of `list_releases` and `prune_releases` has changed, so if you depended on this it may be breaking.
|
4
|
+
- move `Strategy::Branches` custom behavior to a `post_deploy_task` so it uses the same `deploy` method inherited from `Strategy::Base`. This could cause [BREAKING] changes if you use a custom `post_deploy_task` with a `Branches` deploy type.
|
5
|
+
|
6
|
+
# 1.1.0
|
7
|
+
- `#persisted_releaser` is available on a deployment from rake tasks. this will be the same for tasks called during a deploy for example.
|
8
|
+
- addition of a `#current_release_data` method for the Revisions releaser. This pulls merged data from the manifest and the log file.
|
9
|
+
- add `log_file_path` and `log_file_entry` to config to setup a log file for all deploys
|
10
|
+
- [BREAKING] change interface of releasers to expect being able to pass a second argument (build data) to #create_release
|
11
|
+
- add task hook for before the symlink in the Revisions releaser. `pre_symlink_task` gets called with |releaser, remote| in a remote loop so it's run for each.
|
12
|
+
- add ability to create user rake tasks that have access to deployment information. see [the docs](doc/config/task-definitions.md) for more info
|
13
|
+
|
14
|
+
# 1.0.2
|
15
|
+
- make sure that Revisions#remove_untracked_revisions checks it against the "current" revision before removing it.
|
16
|
+
|
17
|
+
# 1.0.1
|
18
|
+
- add a second check to git after the build task to ensure build doesn't affect checked in files
|
19
|
+
|
20
|
+
# 1.0.0
|
21
|
+
- base includes a `deployment:build` and `deployment:post_deploy` task to allow direct triggering of these deployment steps
|
22
|
+
- add the `verbose` option for deployments
|
23
|
+
- fix bug in default logger to adjust for statuses that are too long
|
24
|
+
- create `Branches::Index` and render erb for the template
|
25
|
+
- move Branches specific ideas into the Branches namespace
|
26
|
+
- add `Deployment::Manifest#put` method to update manifest data for matching records
|
27
|
+
- remove `Statistrano::Deployment::Manifest` & `Statistrano::Deployment::Manifest::RemoteStore` in favor of using the same manifest as the Revisions releaser
|
28
|
+
- add option for rsync flags [b5a248be8d96d142ca94c076d80ad6deaa0fa69e]
|
29
|
+
- loosen rainbows dependency to work with old & new bananabin
|
30
|
+
- reorganize deployment types & releasers. now use a single remote object, and different "strategies" for base, releases, & branches and different "releasers" for single or revisions
|
31
|
+
- remote multi_target in favor of merging code paths w/ strategies & releasers
|
32
|
+
- can now access deployment info directly in build_tasks & post_deploy_tasks by giving arity [de05bb3a7d760fc51571b0f93f457065758fa772]
|
33
|
+
- rake tasks no manually registered (instead of on initialization) [ac72eb0a65681e472b21c486fa67f7f0dd635c02]
|
34
|
+
- add explicit setting for file & directory permissions on deploy [25ed930235e348fd6068cedbdc09b33e788fc3d5]
|
35
|
+
|
36
|
+
# 0.10.0
|
37
|
+
- tag release
|
38
|
+
|
39
|
+
# 0.10.0.rc3
|
40
|
+
- fix copy current release step, target needs to not exist
|
41
|
+
|
42
|
+
# 0.10.0.rc2
|
43
|
+
- copy current release to help reduce time spent rsyncing new build
|
44
|
+
|
45
|
+
# 0.10.0.rc1
|
46
|
+
- make dir with 775, so global (ngnx) can read them
|
47
|
+
|
48
|
+
# 0.10.0.beta3
|
49
|
+
- release dir created recursively, ensures permissions on releases dir
|
50
|
+
- add guard to not remove a currently symlinked release
|
51
|
+
|
52
|
+
# 0.10.0.beta2
|
53
|
+
- manifests check if they exist before trying to create themselves
|
54
|
+
- add Target#test_connection method to allow for early testing of remote connections
|
55
|
+
- MultiTarget post_deploy_task accepts blocks just like build_task
|
56
|
+
- add a "verbose" option to Target to log each command run
|
57
|
+
|
58
|
+
# 0.10.0.beta1
|
59
|
+
- add a "new architecture" MultiTarget deployment type
|
60
|
+
- fix Util::symbolize_hash_keys to work with nested hashes
|
61
|
+
- add a types cache and register methods for registering deployment types
|
62
|
+
- remove Git code (it wasn't being used)
|
63
|
+
|
64
|
+
# 0.9.1
|
65
|
+
- bump Asgit dependency to 0.1
|
66
|
+
|
67
|
+
# 0.9.0
|
68
|
+
- misc refactoring
|
69
|
+
- switch to Asgit for git status queries
|
70
|
+
- change the way ssh sessions are handled, now passed with the config
|
71
|
+
- using HereOrThere for running commands (has a consistent response object)
|
72
|
+
|
73
|
+
# 0.8.1
|
74
|
+
- fix nil error for manifest in branches
|
75
|
+
|
76
|
+
# 0.8.0
|
77
|
+
- re-architect configuration for deployment classes
|
78
|
+
- now suport a "sugar" dsl syntax for setting config while defining deployments
|
79
|
+
|
80
|
+
# 0.7.2
|
81
|
+
- fix bug where branch deployments would update timestamp on all branches in the manifest
|
82
|
+
|
83
|
+
# 0.7.1
|
84
|
+
- add an `open` rake task for Branches deployments to navigate to the url
|
85
|
+
|
86
|
+
# 0.7.0
|
87
|
+
- big refactoring to reduce complexity of the public methods
|
88
|
+
|
89
|
+
# 0.6.1
|
90
|
+
- fix a regression that caused Git.remote_up_to_date? to fail
|
91
|
+
|
92
|
+
# 0.6.0
|
93
|
+
- move a few setup methods
|
94
|
+
- add integration specs for the deployment modules
|
95
|
+
- add a spec for the git module
|
96
|
+
- rewrite Shell.run to use Open3 and improve output
|
97
|
+
|
98
|
+
# 0.5.3
|
99
|
+
- loosen all the dependencies
|
100
|
+
|
101
|
+
# 0.5.2
|
102
|
+
- loosen dependency on slugity
|
103
|
+
|
104
|
+
# 0.5.1
|
105
|
+
- add environment variable DEPLOYMENT_ENVIRONMENT set to the name of the deployment
|
106
|
+
|
107
|
+
# 0.5.0
|
108
|
+
- only create a single ssh connection for the deploy task (after_deploy creates a second)
|
109
|
+
- add exception handling to `invoke_build_task`, exit and log on an exception
|
110
|
+
|
111
|
+
# 0.4.1
|
112
|
+
- expose less of the statistrano namespace to help with conflicts of common names (like Log)
|
113
|
+
|
114
|
+
# 0.4.0
|
115
|
+
- now abort on errors
|
116
|
+
|
117
|
+
# 0.3.1
|
118
|
+
- add rake task descriptions
|
119
|
+
- add times for rsync task
|
120
|
+
|
121
|
+
# 0.3.0
|
122
|
+
- change rsync behavior, adds delete-after
|
123
|
+
- clone previous release first if it exits for release type deployments
|
124
|
+
|
125
|
+
# 0.2.2
|
126
|
+
- move setup to a `prepare_for_action` method, defer connection until needed
|
127
|
+
|
128
|
+
# 0.2.1
|
129
|
+
- regenerate index after pruning releases
|
130
|
+
|
131
|
+
# 0.2.0
|
132
|
+
- code overhaul
|
133
|
+
- new way to define deployments
|
134
|
+
- classes for different deployment types
|
135
|
+
- add pruning to branches deployments
|
136
|
+
|
137
|
+
# 0.1.3
|
138
|
+
- fix error with newlines in the current_git_commit
|
139
|
+
|
140
|
+
# 0.1.2
|
141
|
+
- updated apearance of index page
|
142
|
+
|
143
|
+
# 0.1.1
|
144
|
+
- add updated at to feature index page
|
145
|
+
|
146
|
+
# 0.1.0
|
147
|
+
- add post_deploy_task to servers
|
148
|
+
- add generate namespace, and generate:index task to rake tasks
|
149
|
+
|
150
|
+
# 0.0.4
|
151
|
+
- fix log order bug, standardize the printed output
|
152
|
+
|
153
|
+
# 0.0.3
|
154
|
+
- fixed bug with manifest for releases that have the same name
|
155
|
+
|
156
|
+
# 0.0.2
|
157
|
+
- fix manifest creation for feature releases
|
158
|
+
- add a releases:browse task
|
159
|
+
|
160
|
+
# 0.0.1
|
161
|
+
- initial gem creation
|
@@ -0,0 +1,33 @@
|
|
1
|
+
---
|
2
|
+
title: File Permissions
|
3
|
+
---
|
4
|
+
|
5
|
+
In some cases you may be deploying into an environment where the default chmod settings of 755 for directories and 644 for files isn't appropriate. Lucky for you, there's a setting for that :).
|
6
|
+
|
7
|
+
For example if we'd like to deploy to a server using different users that are part of the same group:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
define_deployment "example" do
|
11
|
+
|
12
|
+
# set the permissions directories will be
|
13
|
+
# created with
|
14
|
+
dir_permissions 775
|
15
|
+
|
16
|
+
# set the permissions files will be
|
17
|
+
# created with
|
18
|
+
file_permissions 664
|
19
|
+
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
Using `775` and `664` is ok if the deployment members are part of the same group, but unless you're using the `releases` deployment strategy you'll run into trouble when rsync tries to update the timestamps on directories. You *must* be the owner of the directory to do that. Getting around that little caveat we can configure the rsync flags to skip updating timestamps:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
define_deployment "example" do
|
27
|
+
|
28
|
+
rsync_flags "-aqz " + # archive, quiet, & compress
|
29
|
+
"-O " + # omit timestamp updates from directories
|
30
|
+
"--delete-after" # remove orphaned files *after* the sync is complete
|
31
|
+
|
32
|
+
end
|
33
|
+
```
|
@@ -0,0 +1,32 @@
|
|
1
|
+
---
|
2
|
+
title: Log Files
|
3
|
+
---
|
4
|
+
|
5
|
+
You can specify a log file to store a record of every deploy. These logs could eventually get pretty large, so it's suggested you point logrotate at the log files to keep them in check.
|
6
|
+
|
7
|
+
The data that is stored for each release is completely up to you, and definable with the `log_file_content` method. It will accept an argument for the `deployment`, `releaser`, `build_data`, and `post_deploy_data` and expects a hash to be returned (or an object with to_json).
|
8
|
+
|
9
|
+
Here we'll use [Asgit](https://github.com/stevenosloan/asgit) to create a model of our projects repo urls. Lets pretend our project is called `caesar` on github.
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
|
13
|
+
repo = Asgit::Project.new service: :github,
|
14
|
+
organization: 'mailchimp',
|
15
|
+
project: 'caesar',
|
16
|
+
default_branch: 'master'
|
17
|
+
|
18
|
+
|
19
|
+
define_deployment "caesar" do
|
20
|
+
|
21
|
+
log_file_path "/var/log/caesar.deploy.log"
|
22
|
+
log_file_entry do |deployment, releaser, build_data, post_deploy_data|
|
23
|
+
{
|
24
|
+
time: releaser.release_name,
|
25
|
+
deployer: `whoami`,
|
26
|
+
commit: Asgit.current_commit,
|
27
|
+
diff_url: repo.urls.compare( Asgit.current_commit,
|
28
|
+
deployment.log_file.last_entry[:commit] )
|
29
|
+
}.merge(build_data)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
---
|
2
|
+
title: Task Definitions
|
3
|
+
---
|
4
|
+
|
5
|
+
These are the `build_task` and `post_deploy_task` setup in a deployment's config. They are flexible allowing you to set them as a block or a string to call a rake task.
|
6
|
+
|
7
|
+
You can also create your own tasks that have access to the Statistrano deployment & remotes.
|
8
|
+
|
9
|
+
|
10
|
+
### Call a Rake Task
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
define_deployment "example" do
|
14
|
+
|
15
|
+
build_task "base:build"
|
16
|
+
# this will call `Rake::Task['base:build'].invoke`
|
17
|
+
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
|
22
|
+
### Run a Block
|
23
|
+
|
24
|
+
Without any need for deployment context:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
define_deployment "example" do
|
28
|
+
|
29
|
+
build_task do
|
30
|
+
# run our block of code
|
31
|
+
BuildScript("example")
|
32
|
+
# => { foo: "bar", wu: "tang" }
|
33
|
+
|
34
|
+
# if we return a hash, depending on the deployment
|
35
|
+
# strategy it may use that build metadata
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
If we need the deployment object for context:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
define_deployment "example" do
|
45
|
+
|
46
|
+
build_task do |deployment|
|
47
|
+
# by giving the task arity we can access the
|
48
|
+
# deployment object
|
49
|
+
|
50
|
+
deployment.name
|
51
|
+
# => example
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
### Define Your Own Tasks
|
58
|
+
|
59
|
+
For this we have two methods usable in the configuration blog, `namespace` and `task`.
|
60
|
+
|
61
|
+
`namespace` wraps any tasks (or other namespaces) you define to allow creating a sane structure to your new tasks.
|
62
|
+
|
63
|
+
`task` creates a new task with name & description. Like the `build_task` and `post_deploy_task` if you give your block arity you'll be able to access the deployment.
|
64
|
+
|
65
|
+
An example:
|
66
|
+
```ruby
|
67
|
+
example = define_deployment "example" do
|
68
|
+
task :test_connections, 'test connection to the remotes' do |deployment|
|
69
|
+
deployment.remotes.each(&:test_connection)
|
70
|
+
end
|
71
|
+
|
72
|
+
namespace :php do
|
73
|
+
task :restart, 'restart php-fpm on each remote' do |deployment|
|
74
|
+
deployment.remotes.each do |r|
|
75
|
+
r.run "sudo php-fpm restart"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
example.register_tasks
|
81
|
+
```
|
82
|
+
|
83
|
+
This will give you tasks that look like this:
|
84
|
+
```bash
|
85
|
+
$ rake -T
|
86
|
+
example:test_connections # test connection to the remotes
|
87
|
+
example:php:restart # restart php-fpm on each remote
|
88
|
+
```
|
@@ -0,0 +1,96 @@
|
|
1
|
+
---
|
2
|
+
title: Getting Started
|
3
|
+
---
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add to your Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem "statistrano", git: "git@github.com:mailchimp/statistrano.git",
|
11
|
+
tag: "1.0.0"
|
12
|
+
```
|
13
|
+
|
14
|
+
Bundle:
|
15
|
+
|
16
|
+
```bash
|
17
|
+
$ bundle install
|
18
|
+
```
|
19
|
+
|
20
|
+
|
21
|
+
## Setting up a deployment
|
22
|
+
|
23
|
+
In a Rakefile (typically `tasks/deploy.rake`) we'll require statistrano then define an example deployment.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# tasks/deploy.rake
|
27
|
+
require 'statistrano'
|
28
|
+
|
29
|
+
example = define_deployment "example", :base do
|
30
|
+
|
31
|
+
# first we setup the host we deploy to,
|
32
|
+
# we will have set this up in ~/.ssh/config so we
|
33
|
+
# can ssh to it using a pubkey as auth
|
34
|
+
hostname 'digitalocean'
|
35
|
+
|
36
|
+
# now we'll configure the source and target directories
|
37
|
+
local_dir 'build'
|
38
|
+
remote_dir '/opt/example'
|
39
|
+
|
40
|
+
# we have access to two task hooks, the build_task
|
41
|
+
# and the post_deploy_task. they can work in two different ways:
|
42
|
+
# 1. if given a string, they call a rake task
|
43
|
+
# 2. if given a block they run that block when called,
|
44
|
+
# see the build task guide for more information
|
45
|
+
#
|
46
|
+
# in this case we'll run the block
|
47
|
+
build_task do |deployment|
|
48
|
+
# it's good to check if your connections are all valid
|
49
|
+
deployment.remotes.each(&:test_connection)
|
50
|
+
|
51
|
+
ENV['BUILD_ENV'] = "example"
|
52
|
+
Rake::Task['middleman:build'].invoke
|
53
|
+
end
|
54
|
+
# and just call the rake task here
|
55
|
+
post_deploy_task 'middleman:cleanup'
|
56
|
+
|
57
|
+
# statistrano can guard agains errant deploys that aren't
|
58
|
+
# checked into version control. we just have to give it the
|
59
|
+
# branch we want to check against
|
60
|
+
check_git true
|
61
|
+
git_branch 'master'
|
62
|
+
|
63
|
+
# there is support for deploying to multiple remotes
|
64
|
+
# simultaniously, any config option can be overriden for an
|
65
|
+
# individual remote in it's option hash
|
66
|
+
remotes [
|
67
|
+
{ hostname: 'remote01', remote_dir: '/var/www/mailchimp01' },
|
68
|
+
{ hostname: 'remote02', remote_dir: '/var/www/mailchimp02' }
|
69
|
+
]
|
70
|
+
end
|
71
|
+
```
|
72
|
+
|
73
|
+
We don't have any rake tasks set up now though, as they aren't registered by default. Calling the `register_tasks` method on the deployment will set up the default ones.
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
example.register_tasks
|
77
|
+
```
|
78
|
+
|
79
|
+
Though in some cases you may want to skip that and register them manually (like if you need to set specific env variables).
|
80
|
+
|
81
|
+
Now to deploy you'd run `rake example:deploy`.
|
82
|
+
|
83
|
+
For more information on specific, check out the guides below.
|
84
|
+
|
85
|
+
## Strategies
|
86
|
+
|
87
|
+
- [Base](/doc/strategies/base.md)
|
88
|
+
- [Revisions](/doc/strategies/revisions.md)
|
89
|
+
- [Branches](/doc/strategies/branches.md)
|
90
|
+
|
91
|
+
|
92
|
+
## Configuration
|
93
|
+
|
94
|
+
- [Task Definitions](/doc/config/task-definitions.md)
|
95
|
+
- [File Permissions](/doc/config/file-permissions.md)
|
96
|
+
- [Log Files](/doc/config/log-files.md)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
---
|
2
|
+
title: Base Strategy
|
3
|
+
---
|
4
|
+
|
5
|
+
As it's name would imply, the `base` strategy is just that, a base. Each of the other strategies build off of it, that doesn't mean it's not useful though. It can still move your code to a target location on multiple remotes.
|
6
|
+
|
7
|
+
This strategy will take the contents of the defined `local_dir` and sync them to the `remote_dir` on your remotes.
|
8
|
+
|
9
|
+
### Example:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
# tasks/deploy.rake
|
13
|
+
require 'statistrano'
|
14
|
+
|
15
|
+
example = define_deployment "example", :base do
|
16
|
+
|
17
|
+
hostname 'digitalocean'
|
18
|
+
|
19
|
+
local_dir 'build'
|
20
|
+
remote_dir '/opt/example'
|
21
|
+
|
22
|
+
build_task do |deployment|
|
23
|
+
deployment.remotes.each(&:test_connection)
|
24
|
+
Rake::Task['middleman:build'].invoke
|
25
|
+
end
|
26
|
+
|
27
|
+
post_deploy_task 'middleman:cleanup'
|
28
|
+
|
29
|
+
check_git true
|
30
|
+
git_branch 'master'
|
31
|
+
|
32
|
+
remotes [
|
33
|
+
{ hostname: 'remote01', remote_dir: '/var/www/mailchimp01' },
|
34
|
+
{ hostname: 'remote02', remote_dir: '/var/www/mailchimp02' }
|
35
|
+
]
|
36
|
+
|
37
|
+
end
|
38
|
+
```
|
@@ -0,0 +1,82 @@
|
|
1
|
+
---
|
2
|
+
title: Branches Strategy
|
3
|
+
---
|
4
|
+
|
5
|
+
Inspired by layervault's [Divergence](http://cosmos.layervault.com/divergence.html), the Branches strategy is special built for staging all the things. It will do a base deploy to a subdirectory based on the current git branch, then generate and index w/ all of the currently staged branches. With the correct bit of nginx (or apache) setup each branch is accessible from a subdomain.
|
6
|
+
|
7
|
+
### Example
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
deployment = define_deployment "branches", :branches do
|
11
|
+
|
12
|
+
# in addition to the "base" options
|
13
|
+
|
14
|
+
# the allow the generated index properly create links to the
|
15
|
+
# subdomains, we need to give it a base to work off of
|
16
|
+
base_domain "mailchimp.com"
|
17
|
+
|
18
|
+
# the public_dir is the subdir under remote_dir where the site
|
19
|
+
# will be deployed, for branch based locations *don't* touch this
|
20
|
+
# but if we want to mount a different project we can manually manipulate this
|
21
|
+
public_dir "current_branch"
|
22
|
+
|
23
|
+
# the post deploy task defaults to generating the index file
|
24
|
+
# and adding the current_release to the manifest
|
25
|
+
# so if you touch this keep that in mind as you may want to
|
26
|
+
# generate that as well
|
27
|
+
post_deploy_task do |deployment|
|
28
|
+
d.push_current_release_to_manifest
|
29
|
+
d.generate_index
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
Like base deployments, we need to register the rake tasks if we'd like the defaults to be available.
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
deployment.register_tasks
|
39
|
+
```
|
40
|
+
|
41
|
+
`rake branches:deploy`
|
42
|
+
deploys local_dir to the remote named for the current git branch, and generates an index page
|
43
|
+
|
44
|
+
`rake branches:list`
|
45
|
+
lists all the currently deployed branches
|
46
|
+
|
47
|
+
`rake branches:open`
|
48
|
+
If you have set a base_domain, opens the branch in your default browser
|
49
|
+
|
50
|
+
`rake branches:prune`
|
51
|
+
shows list of currently deployed branches to pick from and remove
|
52
|
+
|
53
|
+
`rake branches:generate_index`
|
54
|
+
manually kicks of index generation, typically you shouldn't need to do this
|
55
|
+
|
56
|
+
|
57
|
+
### NGINX configs
|
58
|
+
|
59
|
+
Set up your configs to pass the subdomain down as the docroots, here's some relavent configs:
|
60
|
+
|
61
|
+
```nginx
|
62
|
+
server {
|
63
|
+
listen 80;
|
64
|
+
server_name ~^(?<subdomain>.*)\.yourdomain.com;
|
65
|
+
|
66
|
+
# use the subdomain captured above in the docroot
|
67
|
+
root /var/www/branches.yourdomain.com/$subdomain;
|
68
|
+
index index.html index.htm index.php;
|
69
|
+
|
70
|
+
# pass the subdomain to fastcgi as well
|
71
|
+
location ~ \.php$ {
|
72
|
+
#fastcgi_pass 127.0.0.1:9000;
|
73
|
+
# With php5-fpm:
|
74
|
+
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
75
|
+
fastcgi_index index.php;
|
76
|
+
include fastcgi_params;
|
77
|
+
fastcgi_param SCRIPT_FILENAME /var/www/branches.yourdomain.com/$subdomain$fastcgi_script_name;
|
78
|
+
}
|
79
|
+
|
80
|
+
# other nginx stuf ..
|
81
|
+
}
|
82
|
+
```
|
@@ -0,0 +1,110 @@
|
|
1
|
+
---
|
2
|
+
title: Releases Strategy
|
3
|
+
---
|
4
|
+
|
5
|
+
The Releases strategy is really made for production environments. If you are familiar with the way [Capistrano](https://github.com/capistrano/capistrano) works, it is very similar. Deploys work by creating a new "release" directory with fresh code, then symlinking that to the "current" directory. It's a little different from Capistrano in that it doesn't really care about the remote environment, it just runs the commands you give it.
|
6
|
+
|
7
|
+
Did you botch a release? No big deal™. You can rollback to the previous state while you fix the mistake. This strategy also provides a facility for storing a little bit of metadata about each release. (more on that later).
|
8
|
+
|
9
|
+
### Example:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
# tasks/deploy.rake
|
13
|
+
require 'statistrano'
|
14
|
+
|
15
|
+
deployment = define_deployment "production", :releases do
|
16
|
+
|
17
|
+
# in addition to the "base" config options, there
|
18
|
+
# are some (all defaulted) options specific for releases
|
19
|
+
|
20
|
+
# the release_count defines how many releases to store in
|
21
|
+
# history, more releases gives you more history to rollback
|
22
|
+
# but takes up more space
|
23
|
+
release_count 5
|
24
|
+
|
25
|
+
# each release creates it's own directory inside the
|
26
|
+
# release_dir so it's full path would be:
|
27
|
+
# /#{remote_dir}/releases/#{release_number}
|
28
|
+
release_dir "releases"
|
29
|
+
|
30
|
+
# combined with the `remote_dir`, `public_dir` defines the
|
31
|
+
# the directory that gets symlinked to, point your docroot here:
|
32
|
+
# #{remote_dir}/#{public_dir}
|
33
|
+
public_dir "current"
|
34
|
+
|
35
|
+
# allows a task to run before the symlink gets updated
|
36
|
+
# you might use this to run tests on the target servers
|
37
|
+
#
|
38
|
+
# if you return false or raise an exception, the deploy
|
39
|
+
# will cease, leaving the rsynced directories for inspection.
|
40
|
+
# it is suggested that you log an error with an explaination
|
41
|
+
#
|
42
|
+
# unlike other tasks, this is called in the remotes loop
|
43
|
+
# so is run for each remote
|
44
|
+
pre_symlink_task do |releaser, remote|
|
45
|
+
release_path = File.join remote.config.remote_dir, remote.config.release_dir, releaser.release_name
|
46
|
+
unless remote.run("#{release_path}/bin/test_something").success?
|
47
|
+
Statistrano::Log.error :"#{remote.config.hostname}", "failed to pass test"
|
48
|
+
false # returning false stops the deploy
|
49
|
+
else
|
50
|
+
true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
Like base deployments, we need to register the rake tasks if we'd like the defaults to be available.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
deployment.register_tasks
|
61
|
+
```
|
62
|
+
|
63
|
+
In addition to `deploy` we get a few more utilities for managing releases.
|
64
|
+
|
65
|
+
`rake production:rollback`
|
66
|
+
rolls back to the previous release.
|
67
|
+
|
68
|
+
`rake production:prune`
|
69
|
+
manually removes old releases beyond the release count
|
70
|
+
|
71
|
+
`rake production:list`
|
72
|
+
lists all the currently deployed releases
|
73
|
+
|
74
|
+
|
75
|
+
### Build Metadata
|
76
|
+
|
77
|
+
Releases are managed using a manifest on the remote, and there is a facility to add more data to this manifest for each release. If your build_task returns a hash, it will be merged in to be stored with the release.
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
define_deployment "production", :releases do
|
81
|
+
|
82
|
+
# other config ...
|
83
|
+
|
84
|
+
build_task do
|
85
|
+
BuildScript("production")
|
86
|
+
# => { time: 60, css: "145kb", whoami: 'freddie' }
|
87
|
+
end
|
88
|
+
|
89
|
+
# now on deploy, along with the release name,
|
90
|
+
# the time, css, and whoami keys will be stored
|
91
|
+
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
### With PHP
|
96
|
+
|
97
|
+
PHP has [been known to have problems](http://stackoverflow.com/questions/18450076/capistrano-symlinks-being-cached) updating to newer symlinks. So it's a good idea to "kick the tires" in a `post_deploy_task` if this may be a problem for you. In this case, reloading php with fpm.
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
define_deployment "production", :releases do
|
101
|
+
|
102
|
+
post_deploy_task do |deployment|
|
103
|
+
deployment.remotes.each do |remote|
|
104
|
+
remote.run "service php-fpm reload"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# other config...
|
109
|
+
end
|
110
|
+
```
|
data/doc/strategies.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
title: Strategies
|
3
|
+
---
|
4
|
+
|
5
|
+
Give the strategy as the second argument to `define_deployment`. For example to use a `releases` strategy:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
define_deployment "example", :releases do
|
9
|
+
# configuration
|
10
|
+
end
|
11
|
+
```
|
12
|
+
|
13
|
+
For more specifics about each strategy:
|
14
|
+
|
15
|
+
- [Base](/doc/strategies/base.md)
|
16
|
+
- [Releases](/doc/strategies/releases.md)
|
17
|
+
- [Branches](/doc/strategies/branches.md)
|