statistrano 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/changelog.md +161 -0
  3. data/doc/config/file-permissions.md +33 -0
  4. data/doc/config/log-files.md +32 -0
  5. data/doc/config/task-definitions.md +88 -0
  6. data/doc/getting-started.md +96 -0
  7. data/doc/strategies/base.md +38 -0
  8. data/doc/strategies/branches.md +82 -0
  9. data/doc/strategies/releases.md +110 -0
  10. data/doc/strategies.md +17 -0
  11. data/lib/statistrano/config/configurable.rb +53 -0
  12. data/lib/statistrano/config/rake_task_with_context_creation.rb +43 -0
  13. data/lib/statistrano/config.rb +52 -0
  14. data/lib/statistrano/deployment/log_file.rb +44 -0
  15. data/lib/statistrano/deployment/manifest.rb +88 -0
  16. data/lib/statistrano/deployment/rake_tasks.rb +74 -0
  17. data/lib/statistrano/deployment/registerable.rb +11 -0
  18. data/lib/statistrano/deployment/releaser/revisions.rb +163 -0
  19. data/lib/statistrano/deployment/releaser/single.rb +48 -0
  20. data/lib/statistrano/deployment/releaser.rb +2 -0
  21. data/lib/statistrano/deployment/strategy/base.rb +132 -0
  22. data/lib/statistrano/deployment/strategy/branches/index/template.html.erb +78 -0
  23. data/lib/statistrano/deployment/strategy/branches/index.rb +40 -0
  24. data/lib/statistrano/deployment/strategy/branches/release.rb +73 -0
  25. data/lib/statistrano/deployment/strategy/branches.rb +198 -0
  26. data/lib/statistrano/deployment/strategy/check_git.rb +43 -0
  27. data/lib/statistrano/deployment/strategy/invoke_tasks.rb +58 -0
  28. data/lib/statistrano/deployment/strategy/releases.rb +76 -0
  29. data/lib/statistrano/deployment/strategy.rb +37 -0
  30. data/lib/statistrano/deployment.rb +10 -0
  31. data/lib/statistrano/log/default_logger.rb +105 -0
  32. data/lib/statistrano/log.rb +33 -0
  33. data/lib/statistrano/remote/file.rb +79 -0
  34. data/lib/statistrano/remote.rb +111 -0
  35. data/lib/statistrano/shell.rb +17 -0
  36. data/lib/statistrano/util/file_permissions.rb +34 -0
  37. data/lib/statistrano/util.rb +27 -0
  38. data/lib/statistrano/version.rb +3 -0
  39. data/lib/statistrano.rb +55 -0
  40. data/readme.md +247 -0
  41. data/spec/integration_tests/base_integration_spec.rb +103 -0
  42. data/spec/integration_tests/branches_integration_spec.rb +189 -0
  43. data/spec/integration_tests/releases/deploy_integration_spec.rb +116 -0
  44. data/spec/integration_tests/releases/list_releases_integration_spec.rb +38 -0
  45. data/spec/integration_tests/releases/prune_releases_integration_spec.rb +86 -0
  46. data/spec/integration_tests/releases/rollback_release_integration_spec.rb +46 -0
  47. data/spec/lib/statistrano/config/configurable_spec.rb +88 -0
  48. data/spec/lib/statistrano/config/rake_task_with_context_creation_spec.rb +73 -0
  49. data/spec/lib/statistrano/config_spec.rb +34 -0
  50. data/spec/lib/statistrano/deployment/log_file_spec.rb +75 -0
  51. data/spec/lib/statistrano/deployment/manifest_spec.rb +171 -0
  52. data/spec/lib/statistrano/deployment/rake_tasks_spec.rb +107 -0
  53. data/spec/lib/statistrano/deployment/registerable_spec.rb +19 -0
  54. data/spec/lib/statistrano/deployment/releaser/revisions_spec.rb +486 -0
  55. data/spec/lib/statistrano/deployment/releaser/single_spec.rb +59 -0
  56. data/spec/lib/statistrano/deployment/strategy/base_spec.rb +158 -0
  57. data/spec/lib/statistrano/deployment/strategy/branches_spec.rb +19 -0
  58. data/spec/lib/statistrano/deployment/strategy/check_git_spec.rb +39 -0
  59. data/spec/lib/statistrano/deployment/strategy/invoke_tasks_spec.rb +66 -0
  60. data/spec/lib/statistrano/deployment/strategy/releases_spec.rb +257 -0
  61. data/spec/lib/statistrano/deployment/strategy_spec.rb +76 -0
  62. data/spec/lib/statistrano/deployment_spec.rb +4 -0
  63. data/spec/lib/statistrano/log/default_logger_spec.rb +172 -0
  64. data/spec/lib/statistrano/log_spec.rb +36 -0
  65. data/spec/lib/statistrano/remote/file_spec.rb +166 -0
  66. data/spec/lib/statistrano/remote_spec.rb +226 -0
  67. data/spec/lib/statistrano/util/file_permissions_spec.rb +25 -0
  68. data/spec/lib/statistrano/util_spec.rb +23 -0
  69. data/spec/lib/statistrano_spec.rb +52 -0
  70. data/spec/spec_helper.rb +86 -0
  71. data/spec/support/given.rb +39 -0
  72. 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)