pulsar 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/README.md +282 -9
  4. data/circle.yml +56 -11
  5. data/lib/pulsar.rb +3 -1
  6. data/lib/pulsar/cli.rb +29 -4
  7. data/lib/pulsar/context_error.rb +7 -0
  8. data/lib/pulsar/interactors/add_applications.rb +5 -7
  9. data/lib/pulsar/interactors/cleanup.rb +1 -0
  10. data/lib/pulsar/interactors/clone_repository.rb +3 -8
  11. data/lib/pulsar/interactors/copy_environment_file.rb +15 -11
  12. data/lib/pulsar/interactors/copy_initial_repository.rb +2 -9
  13. data/lib/pulsar/interactors/create_capfile.rb +14 -9
  14. data/lib/pulsar/interactors/create_deploy_file.rb +3 -8
  15. data/lib/pulsar/interactors/create_run_dirs.rb +1 -0
  16. data/lib/pulsar/interactors/identify_repository_location.rb +2 -9
  17. data/lib/pulsar/interactors/identify_repository_type.rb +2 -8
  18. data/lib/pulsar/interactors/run_bundle_install.rb +3 -9
  19. data/lib/pulsar/interactors/run_capistrano.rb +4 -12
  20. data/lib/pulsar/organizers/{deploy.rb → task.rb} +1 -1
  21. data/lib/pulsar/validator.rb +33 -0
  22. data/lib/pulsar/version.rb +1 -1
  23. data/pulsar.gemspec +2 -2
  24. data/spec/features/task_spec.rb +187 -0
  25. data/spec/spec_helper.rb +1 -6
  26. data/spec/support/coverage_setup.rb +39 -0
  27. data/spec/units/cli/deploy_spec.rb +28 -6
  28. data/spec/units/cli/install_spec.rb +22 -0
  29. data/spec/units/cli/list_spec.rb +23 -1
  30. data/spec/units/cli/task_spec.rb +138 -0
  31. data/spec/units/cli/version_spec.rb +13 -0
  32. data/spec/units/interactors/copy_environment_file_spec.rb +25 -0
  33. data/spec/units/interactors/create_capfile_spec.rb +22 -0
  34. data/spec/units/interactors/run_capistrano_spec.rb +75 -15
  35. data/spec/units/organizers/{deploy_spec.rb → task_spec.rb} +1 -1
  36. data/spec/units/validator_spec.rb +31 -0
  37. metadata +40 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 49da97e3127c662682484d2c3339d873a2dc7cea
4
- data.tar.gz: ef831d3995741f3fdee35ff56a6c603f5095e649
3
+ metadata.gz: 7d2e3f41d33d1980ca08e0cfb6ad9a79fa74e8d0
4
+ data.tar.gz: e64cdb54592106c7f5690c71e67c435a260bc566
5
5
  SHA512:
6
- metadata.gz: cad9605fa0f1f5e8564e2aa0620d20dea1c50ca5c766a0d4ae524c370c0a7777137390d78b34e0f26d965cebe5637e3bcd6bec2c2cfeac1ee4d87b36625caac3
7
- data.tar.gz: 4cc0710f834e143f5e0b7969e42f03c76334a001ef5782d3d191e47e6c45be16bdcca89e3f338f938d752629045eb746761b6faf67ed5e99447b248ebb205a61
6
+ metadata.gz: 43c48f2e6c411fefc1650918c782ec4bfc78662743ec1ec3c33a69e7616acf9af4dafa9631af6a8280856b472ae85c8e24a310e725843a550a6b480d0afbf55d
7
+ data.tar.gz: 3c926574265223622a691920c39e86a4b02b9c9b6b6d77d456ee59290f5fdad2defb377ff820831943940a2f8bd72fd65593f28e0566a13ed38c0ba60e09f0fa
data/.gitignore CHANGED
@@ -17,3 +17,4 @@ test/tmp
17
17
  test/version_tmp
18
18
  tmp
19
19
  !tmp/.gitkeep
20
+ coverage/
data/README.md CHANGED
@@ -1,21 +1,294 @@
1
- # Pulsar
1
+ # Pulsar [![Gem Version](https://badge.fury.io/rb/pulsar.svg)](https://badge.fury.io/rb/pulsar) [![CircleCI](https://img.shields.io/circleci/project/github/nebulab/pulsar/master.png)](https://circleci.com/gh/nebulab/pulsar/tree/master) [![Coverage Status](https://coveralls.io/repos/github/nebulab/pulsar/badge.svg?branch=master)](https://coveralls.io/github/nebulab/pulsar?branch=master)
2
2
 
3
- The easy [Capistrano](https://rubygems.org/gems/capistrano) deploy and configuration manager.
3
+ The easy [Capistrano][cap-gem] deploy and configuration manager.
4
4
 
5
- Pulsar allows you to run capistrano tasks via a separate repository where all your deploy configurations are stored.
6
- Once you have your own repository, you can gradully add configurations and recipes so that you never have to duplicate code again.
5
+ Pulsar allows you to run Capistrano tasks via a separate repository where all
6
+ your deploy configurations are stored. Once you have your own repository, you
7
+ can gradually add configurations and recipes so that you never have to duplicate
8
+ code again.
7
9
 
8
- The way Pulsar works means that you can deploy without actually having the application on your local machine (and neither
9
- have all your application dependencies installed). This lets you integrate Pulsar with nearly any deploy strategy you can think of.
10
+ The way Pulsar works means that you can deploy without actually having the
11
+ application on your local machine (and neither have all your application
12
+ dependencies installed). This lets you integrate Pulsar with nearly any deploy
13
+ strategy you can think of.
10
14
 
11
15
  Some of the benefits of using Pulsar:
12
- * No capistrano configurations in the application code
16
+ * No Capistrano configurations in the application code
13
17
  * No need to have the application locally to deploy
14
18
  * Every recipe can be shared between all applications
15
19
  * Can easily be integrated with other tools
16
20
  * Write the least possible code to deploy
17
21
 
22
+ *DISCLAIMER*: Understanding Capistrano is strongly suggested before using
23
+ Pulsar.
24
+
18
25
  ## Capistrano support
19
26
 
20
- This version of Pulsar, version `1.0.0` only supports Capistrano v3. If you're looking for Capistrano v2 support you can
21
- use Pulsar version `0.3.5` but, take care, that version is not maintained anymore.
27
+ This version of Pulsar (version `>= 1.0.0`) only supports Capistrano v3. If
28
+ you're looking for Capistrano v2 support you can use Pulsar version `0.3.5` but,
29
+ take care, that version is not maintained anymore.
30
+
31
+ ## Installation
32
+
33
+ The most useful way of installing Pulsar is as a system gem:
34
+
35
+ ```bash
36
+ $ gem install pulsar
37
+ ```
38
+
39
+ This will install the `pulsar` command which will be used to for everything,
40
+ from running Capistrano to listing your configurations.
41
+
42
+ ---
43
+
44
+ The first thing you'll need to do is to create your own configuration repo:
45
+
46
+ ```bash
47
+ $ pulsar install ~/Desktop/pulsar-conf
48
+ ```
49
+
50
+ This will create a basic starting point for building your configuration
51
+ repository. As soon as you're done configuring you should consider transforming
52
+ this folder to a git repository.
53
+
54
+ You can have a look at how your repository should look like by browsing the
55
+ [Pulsar Conf Demo][pulsar-conf-demo].
56
+
57
+ **NOTE**: Pulsar only supports git.
58
+
59
+ ## Configuration
60
+
61
+ This is an example repository configuration layout:
62
+
63
+ ```bash
64
+ pulsar-conf/
65
+ |── Gemfile
66
+ ├── Gemfile.lock
67
+ ├── apps
68
+ │ ├── Capfile
69
+ │ ├── deploy.rb
70
+ │ └── my_application
71
+ │ ├── Capfile
72
+ │ ├── deploy.rb
73
+ │ ├── production.rb
74
+ │ └── staging.rb
75
+ └── recipes
76
+ ├── generic
77
+ │ ├── maintenance_mode.rake
78
+ │ ├── notify.rake
79
+ │ └── utils.rake
80
+ ├── rails
81
+ │ ├── passenger.rake
82
+ │ ├── repair_permissions.rake
83
+ │ ├── symlink_configs.rake
84
+ │ ├── unicorn.rake
85
+ │ └── whenever.rake
86
+ └── spree_1
87
+ └── symlink_assets.rake
88
+ ```
89
+
90
+ Pulsar uses these files to build Capistrano configurations on the fly, depending
91
+ on how you invoke the `pulsar` command. Since Pulsar it's basically a Capistrano
92
+ wrapper, the content of these files is plain old Capistrano syntax.
93
+
94
+ ### _apps_ directory
95
+
96
+ This directory contains your application configurations. You'll have one
97
+ directory per application.
98
+
99
+ * `Capfile` is the generic Capfile shared by all applications
100
+ * `deploy.rb` has configurations that are shared by all applications
101
+ * `my_application/Capfile` is the Capfile that will be used for this particular
102
+ application
103
+ * `my_application/deploy.rb` includes configuration shared by every stage of the
104
+ application
105
+ * `my_application/staging.rb` and `my_application/production.rb` files include
106
+ stage configurations
107
+
108
+ ### _recipes_ directory
109
+
110
+ This directory contains your recipes. You can create any number of directories
111
+ to organize your recipes. In Capistrano v3 fashion, all the files are plain old
112
+ rake tasks (make sure to name them with the `.rake` extension).
113
+
114
+ The recipes contained in this folder are **always included** in each stage for
115
+ each application.
116
+
117
+ ---
118
+
119
+ Another way to include your recipes is by using the `Gemfile`. Many gems already
120
+ include custom recipes for Capistrano so you just need to require those. An
121
+ example with [Whenever][whenever]:
122
+
123
+ ```ruby
124
+ #
125
+ # Inside Gemfile
126
+ #
127
+ gem 'whenever'
128
+
129
+ #
130
+ # Inside some Capfile (either generic or application specific)
131
+ #
132
+ require 'whenever/capistrano'
133
+
134
+ #
135
+ # Inside some .rb configuration file (either generic or application specific)
136
+ #
137
+ set :whenever_command, "bundle exec whenever"
138
+ ```
139
+
140
+ ### Loading the repository
141
+
142
+ Once the repository is ready, you'll need to tell Pulsar where it is. The
143
+ repository location can be specified either as a full git path or a GitHub
144
+ repository path (*i.e.* `gh-user/pulsar-conf`).
145
+
146
+ Since Pulsar requires the repository for everything, there are multiple ways to
147
+ store this information so that you don't have to type it everytime. You can also
148
+ use local repository, which is useful while developing your deployment.
149
+
150
+ You have three possibilities:
151
+
152
+ * `-c` command line option
153
+ * `PULSAR_CONF_REPO` environment variable
154
+ * `~/.pulsar/config` configuration file
155
+
156
+ The fastest way is probably the `.pulsar/config` file inside your home
157
+ directory:
158
+
159
+ ```bash
160
+ #
161
+ # Inside ~/.pulsar/config
162
+ #
163
+ PULSAR_CONF_REPO="gh-user/pulsar-conf"
164
+
165
+ #
166
+ # You can use local repository for development so you don't need to push changes
167
+ # every time
168
+ #
169
+ # PULSAR_CONF_REPO="/full/path/to/repository"
170
+
171
+ #
172
+ # Also supported
173
+ #
174
+ # PULSAR_CONF_REPO="git://github.com/gh-user/pulsar-conf.git"
175
+ ```
176
+
177
+ Pulsar will read this file and set the environment variables properly.
178
+
179
+ ---
180
+
181
+ If you don't want to add another file to your home directory you can export the
182
+ variables yourself:
183
+
184
+ ```bash
185
+ #
186
+ # Inside ~/.bash_profile or ~/.zshrc
187
+ #
188
+ export PULSAR_CONF_REPO="gh-user/pulsar-conf"
189
+ ```
190
+
191
+ ## Usage
192
+
193
+ After the repository is ready, running Pulsar is straightforward. You can either
194
+ list your applications or build a configuration and run Capistrano on it.
195
+
196
+ ### Deploy
197
+
198
+ Running the `deploy` command really means running Capistrano on a certain
199
+ configuration.
200
+
201
+ To deploy `my_application` to `production`:
202
+
203
+ ```bash
204
+ $ pulsar deploy my_application production
205
+ ```
206
+
207
+ The above command will fetch the Pulsar configuration repository, run
208
+ `bundle install`, combine the generic `Capfile` and `deploy.rb` files with the
209
+ `my_application` specific ones and add specific `production.rb` stage
210
+ configuration. At last it will run `cap deploy` on it.
211
+
212
+ Right now Pulsar does not support tasks other then deploy. Support for running
213
+ other Capistrano taks will come, state tuned!
214
+
215
+ ### Listing applications
216
+
217
+ Pulsar can fetch your configuration repository and list the application and
218
+ stages you can run deploys on:
219
+
220
+ ```bash
221
+ $ pulsar list
222
+ ```
223
+
224
+ This will fetch the Pulsar configuration repository and list everything that's
225
+ inside, like this:
226
+
227
+ ```
228
+ my_application: production, staging
229
+ awesome_startup: dev, production, staging
230
+ ```
231
+
232
+ ### Execute arbitrary Capistrano tasks
233
+
234
+ You can launch any Capistrano task via `task` command. You can also
235
+ pass arguments in _Rake style_ (i.e. via square brackets after task name)
236
+
237
+ ```
238
+ $ pulsar task mycustom:task[argumen1,argument2] my_application staging
239
+ ```
240
+
241
+ or via environment variables.
242
+
243
+ ```
244
+ $ TASK_ARG1=arg1 TASK_ARG2=arg2 pulsar task mycustom:task my_application staging
245
+ ```
246
+
247
+ ## Integrations
248
+
249
+ Pulsar is easy to integrate, you just need access to the configurations
250
+ repository and the ability to run a command.
251
+
252
+ Right now there are no integrations for Pulsar v1 but there are some built for
253
+ the old v0.3 version that can be used as an example.
254
+
255
+ ### Chat Bots
256
+
257
+ - https://gist.github.com/mtylty/5324075: a [hubot][hubot] script that runs
258
+ Pulsar via the command line
259
+ - [hubot-pulsar][hubot-pulsar]: a [hubot][hubot] plugin for integrating via
260
+ [Pulsar REST API][pulsar-rest-api]
261
+ - [lita-pulsar][lita-pulsar]: a [Lita][lita] plugin for integrating via the
262
+ command line
263
+
264
+
265
+ ### Pulsar REST API service
266
+
267
+ [Pulsar REST API][pulsar-rest-api] is a service to provide a REST API for
268
+ executing pulsar jobs.
269
+
270
+ Here is a [real-life example][pulsar-rest-api-blogpost] of how you can integrate
271
+ and simplify your Pulsar workflow.
272
+
273
+ ## About
274
+
275
+ [![Nebulab][nebulab-logo]][nebulab]
276
+
277
+ Pulsar is funded and maintained by the [Nebulab][nebulab] team.
278
+
279
+ We firmly believe in the power of open-source. [Contact us][contact-us] if you
280
+ like our work and you need help with your project design or development.
281
+
282
+ [license]: MIT-LICENSE
283
+ [cap-gem]: https://rubygems.org/gems/capistrano
284
+ [nebulab]: http://nebulab.it/
285
+ [nebulab-logo]: http://nebulab.it/assets/images/public/logo.svg
286
+ [contact-us]: http://nebulab.it/contact-us/
287
+ [pulsar-conf-demo]: http://github.com/nebulab/pulsar-conf-demo
288
+ [whenever]: https://github.com/javan/whenever
289
+ [hubot]: https://hubot.github.com
290
+ [hubot-pulsar]: https://github.com/cargomedia/hubot-pulsar
291
+ [pulsar-rest-api]: https://github.com/cargomedia/pulsar-rest-api
292
+ [pulsar-rest-api-blogpost]: http://www.cargomedia.ch/2015/06/23/pulsar-rest-api.html
293
+ [lita]: https://www.lita.io
294
+ [lita-pulsar]: http://github.com/nebulab/lita-pulsar
data/circle.yml CHANGED
@@ -1,16 +1,61 @@
1
+ machine:
2
+ post:
3
+ - |
4
+ if [[ -e ~/rvm_binaries/ruby-2.0.0-p648.tar.bz2 ]]
5
+ then
6
+ rvm mount ~/rvm_binaries/ruby-2.0.0-p648.tar.bz2
7
+ else
8
+ mkdir -p ~/rvm_binaries
9
+ rvm install 2.0.0 --disable-binary
10
+ cd ~/rvm_binaries && rvm prepare 2.0.0
11
+ fi
12
+ - |
13
+ if [[ -e ~/rvm_binaries/ruby-2.1.10.tar.bz2 ]]
14
+ then
15
+ rvm mount ~/rvm_binaries/ruby-2.1.10.tar.bz2
16
+ else
17
+ mkdir -p ~/rvm_binaries
18
+ rvm install 2.1.10 --disable-binary
19
+ cd ~/rvm_binaries && rvm prepare 2.1.10
20
+ fi
21
+ - |
22
+ if [[ -e ~/rvm_binaries/ruby-2.2.6.tar.bz2 ]]
23
+ then
24
+ rvm mount ~/rvm_binaries/ruby-2.2.6.tar.bz2
25
+ else
26
+ mkdir -p ~/rvm_binaries
27
+ rvm install 2.2.6 --disable-binary
28
+ cd ~/rvm_binaries && rvm prepare 2.2.6
29
+ fi
30
+ - |
31
+ if [[ -e ~/rvm_binaries/ruby-2.3.3.tar.bz2 ]]
32
+ then
33
+ rvm mount ~/rvm_binaries/ruby-2.3.3.tar.bz2
34
+ else
35
+ mkdir -p ~/rvm_binaries
36
+ rvm install 2.3.3 --disable-binary
37
+ cd ~/rvm_binaries && rvm prepare 2.3.3
38
+ fi
39
+ - |
40
+ if [[ -e ~/rvm_binaries/ruby-2.4.0.tar.bz2 ]]
41
+ then
42
+ rvm mount ~/rvm_binaries/ruby-2.4.0.tar.bz2
43
+ else
44
+ mkdir -p ~/rvm_binaries
45
+ rvm install 2.4.0 --disable-binary
46
+ cd ~/rvm_binaries && rvm prepare 2.4.0
47
+ fi
1
48
  dependencies:
49
+ cache_directories:
50
+ - ~/rvm_binaries
2
51
  pre:
3
- - rvm install 2.0.0
4
- - rvm install 2.1.10
5
- - rvm install 2.2.6
6
- - rvm install 2.3.3
7
- - rvm install 2.4.0
52
+ - mkdir $CIRCLE_ARTIFACTS/coverage
8
53
  override:
9
- - rvm-exec 2.0.0 bash -c "bundle check --path=vendor/bundle || bundle install --path=vendor/bundle"
10
- - rvm-exec 2.1.10 bash -c "bundle check --path=vendor/bundle || bundle install --path=vendor/bundle"
11
- - rvm-exec 2.2.6 bash -c "bundle check --path=vendor/bundle || bundle install --path=vendor/bundle"
12
- - rvm-exec 2.3.3 bash -c "bundle check --path=vendor/bundle || bundle install --path=vendor/bundle"
13
- - rvm-exec 2.4.0 bash -c "bundle check --path=vendor/bundle || bundle install --path=vendor/bundle"
54
+ - rvm-exec 2.0.0 bash -c "gem install bundler && (bundle check --path=vendor/bundle || bundle install --path=vendor/bundle)"
55
+ - rvm-exec 2.1.10 bash -c "gem install bundler && (bundle check --path=vendor/bundle || bundle install --path=vendor/bundle)"
56
+ - rvm-exec 2.2.6 bash -c "gem install bundler && (bundle check --path=vendor/bundle || bundle install --path=vendor/bundle)"
57
+ - rvm-exec 2.3.3 bash -c "gem install bundler && (bundle check --path=vendor/bundle || bundle install --path=vendor/bundle)"
58
+ - rvm-exec 2.4.0 bash -c "gem install bundler && (bundle check --path=vendor/bundle || bundle install --path=vendor/bundle)"
14
59
  test:
15
60
  pre:
16
61
  - git config --global user.email "circleci@nebulab.it" && git config --global user.name "Circle CI"
@@ -19,4 +64,4 @@ test:
19
64
  - rvm-exec 2.1.10 bash -c "bundle exec rspec --color --format documentation spec"
20
65
  - rvm-exec 2.2.6 bash -c "bundle exec rspec --color --format documentation spec"
21
66
  - rvm-exec 2.3.3 bash -c "bundle exec rspec --color --format documentation spec"
22
- - rvm-exec 2.4.0 bash -c "bundle exec rspec --color --format documentation spec"
67
+ - rvm-exec 2.4.0 bash -c "COVERAGE=true bundle exec rspec --color --format documentation spec"
@@ -8,6 +8,8 @@ module Pulsar
8
8
  require 'interactor'
9
9
  require 'fileutils'
10
10
 
11
+ require 'pulsar/context_error'
12
+ require 'pulsar/validator'
11
13
  require 'pulsar/interactors/cleanup'
12
14
  require 'pulsar/interactors/create_run_dirs'
13
15
  require 'pulsar/interactors/add_applications'
@@ -23,7 +25,7 @@ module Pulsar
23
25
 
24
26
  require 'pulsar/organizers/list'
25
27
  require 'pulsar/organizers/install'
26
- require 'pulsar/organizers/deploy'
28
+ require 'pulsar/organizers/task'
27
29
 
28
30
  require 'pulsar/constants'
29
31
  require 'pulsar/cli'
@@ -1,3 +1,8 @@
1
+ if ENV['COVERAGE']
2
+ ENV['FEATURE_TESTS'] = 'true'
3
+ require_relative '../../spec/support/coverage_setup'
4
+ end
5
+
1
6
  module Pulsar
2
7
  class CLI < Thor
3
8
  map %w[--version -v] => :__print_version
@@ -50,9 +55,10 @@ module Pulsar
50
55
  option :conf_repo, aliases: '-c'
51
56
  def deploy(application, environment)
52
57
  load_config
53
- result = Pulsar::Deploy.call(
58
+ result = Pulsar::Task.call(
54
59
  repository: load_option_or_env!(:conf_repo),
55
- application: application, environment: environment
60
+ application: application, environment: environment,
61
+ task: 'deploy'
56
62
  )
57
63
 
58
64
  if result.success?
@@ -63,6 +69,24 @@ module Pulsar
63
69
  end
64
70
  end
65
71
 
72
+ desc 'task APPLICATION ENVIRONMENT TASK', 'Run Capistrano task for APPLICATION on ENVIRONMENT'
73
+ option :conf_repo, aliases: '-c'
74
+ def task(application, environment, task)
75
+ load_config
76
+ result = Pulsar::Task.call(
77
+ repository: load_option_or_env!(:conf_repo),
78
+ application: application, environment: environment,
79
+ task: task
80
+ )
81
+
82
+ if result.success?
83
+ puts "Executed task #{task} for #{application} on #{environment}!"
84
+ else
85
+ puts "Failed to execute task #{task} for #{application} on #{environment}."
86
+ puts result.error
87
+ end
88
+ end
89
+
66
90
  desc "--version, -v", "print the version"
67
91
  def __print_version
68
92
  puts Pulsar::VERSION
@@ -71,6 +95,8 @@ module Pulsar
71
95
  private
72
96
 
73
97
  def load_config
98
+ return unless File.exist?(PULSAR_CONF) && File.stat(PULSAR_CONF).readable?
99
+
74
100
  Dotenv.load(PULSAR_CONF) # Load configurations for Pulsar
75
101
  end
76
102
 
@@ -81,8 +107,7 @@ module Pulsar
81
107
  option_value = options[option] || ENV[env_option]
82
108
 
83
109
  if option_value.nil? || option_value.empty?
84
- fail RequiredArgumentMissingError,
85
- exception_text
110
+ fail RequiredArgumentMissingError, exception_text
86
111
  end
87
112
 
88
113
  option_value