heroku_hatchet 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cbe186a27b0018f41b0ab9338925c09acdf9a52b
4
- data.tar.gz: b7dcdd7fdf884f4e6773e6ae5c34fc731b615876
3
+ metadata.gz: b3de8693165cadd85b33f59521ea5c1a7d5bf7a5
4
+ data.tar.gz: fe8f0f5783ceb61174f907cd19039760789aa248
5
5
  SHA512:
6
- metadata.gz: 66ae54f148dfde98f77515fedc1401aee42820084de8846d0dae3c1a350f0b3e19393033ecac347e14096b945adc5c7f84d3f0c26d1e72cbde78fbfd0b3b114a
7
- data.tar.gz: 8f2fc16b6a0aaa668eed1efd53b1807bbbceb15afc4a298bf8a081086bcb53c7e2afe3bb1539d605d943368ff7926d46dfa4678e36b292366e0f06f3949e41c2
6
+ metadata.gz: a3075c645dd0ecbfa932e610f0522746945b33c6fd12749a9a6b37dfd51f016b528f0e1f1a97320a7f1550b1e5b19bd6d9eb201479d1d97bcacd314e46e980bd
7
+ data.tar.gz: 526de86c2aaf5e1e4b8bb0d5ddafa35d35f33f38dcbdbddf2506bbeb47f21344d29e568364510b5cbfd476fee4332882098809221dbf2629085c644da82c809a
data/.travis.yml CHANGED
@@ -9,6 +9,7 @@ after_script: bundle exec rake hatchet:teardown_travis
9
9
  env:
10
10
  global:
11
11
  - HATCHET_RETRIES=3
12
+ - HATCHET_BUILDPACK_BRANCH=master
12
13
  - secure: |-
13
14
  SfUgPagZILPjm4rjkYlEck76PUE47dimpNZgUtUf7wTAbe6EE83QmnRl6uDT
14
15
  eSdxuY9uNFoTwNLC0J+mRiDAJtAQxBsst8wFoc3diK2o8Ojnor5yd3cxddBv
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## HEAD
2
2
 
3
+ ## 1.1.0
4
+
5
+ - Added `Hatchet::Runner` which can dynamically swap the backend (anvil/git) depending on the value of ENV['HATCHET_DEPLOY_STRATEGY'] you can use 'anvil' or 'git'.
6
+
3
7
  ## 1.0.0
4
8
 
5
9
  - Move remote console running code to https://github.com/schneems/repl_runner
data/README.md CHANGED
@@ -79,7 +79,7 @@ test/
79
79
  Now in your test you can reference one of these applications by using it's git name:
80
80
 
81
81
  ```ruby
82
- Hatchet::AnvilApp.new('no_lockfile')
82
+ Hatchet::Runner.new('no_lockfile')
83
83
  ```
84
84
 
85
85
  If you have conflicting names, use full paths.
@@ -99,30 +99,50 @@ is in your best interest to not change them or your tests may
99
99
  spontaneously fail. In the future we may create a hatchet.lockfile or
100
100
  something to declare the commit
101
101
 
102
+
103
+ ## Deployments: Anvil vs. Git
104
+
105
+ Before you start testing a buildpack, understand that there are two different ways to deploy to Heroku. The first you are likely familiar with Git, requires a `git push heroku master`. You can configure the buildpack of an app being deployed in this way through the `BUILDPACK_URL` environment variable of the app. The buildpack url must be publicaly available.
106
+
107
+ The second method is by [Anvil](https://github.com/ddollar/anvil-cli) . In this method the build is performed as a service. This service takes an app to be built as well as a buildpack. When using Anvil, you do not need to put your buildpack anywhere publicly available.
108
+
109
+ When developing local features you will likely wish to use Anvil since it does not require a publicly available URL and you can iterate faster. When testing for regression you will almost always want to use Git, since it is the closest approximation to real world deployment. For this reason Hatchet provides a globally configurable way to toggle between the two deployment modes `Hatchet::Runner`
110
+
111
+
102
112
  ## Deploying apps
103
113
 
104
- Now that you've got your apps locally you can have hatchet deploy them for you. Hatchet can deploy using one of two ways Anvil and Git. A `Hatchet::AnvilApp` will deploy using Anvil against the current directory. This means that the buildpack you have locally will be used when deploying, due to this we recommend using Anvil to run your tests.
114
+ Now that you've got your apps locally you can have hatchet deploy them for you. Hatchet can deploy using one of two ways Anvil and Git. To specify one or the other set your `HATCHET_DEPLOY_STRATEGY` environment variable to `anvil` or `git`. The default is `anvil`. In production, you should always test against `git`
115
+
105
116
 
106
- A `Hatchet::GitApp` will deploy using the standard `git push heroku master`, if you use this option you need to have a publicly accessible copy of your buildpack. Using Git to test your buildpack may be slow and require you to frequently push your buildpack to a public git repo. For this reason we recommend using Anvil to run your tests:
117
+ A `Hatchet::GitApp` will deploy using the standard `git push heroku master` and is not configurable, if you use this option you need to have a publicly accessible copy of your buildpack. Using Git to test your buildpack may be slow and require you to frequently push your buildpack to a public git repo. For this reason we recommend using Anvil to run your tests locally:
107
118
 
108
119
  ```ruby
109
- Hatchet::AnvilApp.new("rails3_mri_193").deploy do |app|
120
+ Hatchet::Runner.new("rails3_mri_193").deploy do |app|
110
121
 
111
122
  end
112
123
  ```
113
124
 
125
+ If you are using GIT, you can specify the location of your public buildpack url in an environment variable:
126
+
127
+ ```sh
128
+ HATCHET_BUILDPACK_BASE=https://github.com/heroku/heroku-buildpack-ruby.git
129
+ HATCHET_BUILDPACK_BRANCH=master
130
+ ```
131
+
132
+ If you do not specify `HATCHET_BUILDPACK_URL` the default Ruby buildpack will be used. If you do not specify a `HATCHET_BUILDPACK_BRANCH` the current branch you are on will be used.
133
+
114
134
  Deploys are expected to work, if the `ENV['HATCHET_RETRIES']` is set, then deploys will be automatically retried that number of times. Due to testing using a network and random Anvil failures, setting this value to `3` retries seems to work well. If an app cannot be deployed within its allotted number of retries an error will be raised.
115
135
 
116
136
  If you are testing an app that is supposed to fail deployment you can set the `allow_failure: true` flag when creating the app:
117
137
 
118
138
  ```ruby
119
- Hatchet::AnvilApp.new("no_lockfile", allow_failure: true).deploy do |app|
139
+ Hatchet::Runner.new("no_lockfile", allow_failure: true).deploy do |app|
120
140
  ```
121
141
 
122
142
  After the block finishes your app will be removed from heroku. If you are investigating a deploy, you can add the `debug: true` flag to your app:
123
143
 
124
144
  ```ruby
125
- Hatchet::AnvilApp.new("rails3_mri_193", debug: true).deploy do |app|
145
+ Hatchet::Runner.new("rails3_mri_193", debug: true).deploy do |app|
126
146
  ```
127
147
 
128
148
  Now after Hatchet is done deploying your app it will remain on Heroku. It will also output the name of the app into your test logs so that you can `heroku run bash` into it for detailed postmortem.
@@ -130,7 +150,7 @@ Now after Hatchet is done deploying your app it will remain on Heroku. It will a
130
150
  If you are wanting to run a test against a specific app without deploying to it, you can set the app name like this:
131
151
 
132
152
  ```ruby
133
- app = Hatchet::AnvilApp.new("rails3_mri_193", name: "testapp")
153
+ app = Hatchet::Runner.new("rails3_mri_193", name: "testapp")
134
154
  ```
135
155
 
136
156
  Deploying the app takes a few minutes, so you may want to skip that part to make debugging a problem easier since you're iterating much faster.
@@ -143,7 +163,7 @@ If you need to deploy using a buildpack that is not in the root of your director
143
163
  buildpack_path = File.expand_path 'test/fixtures/buildpacks/heroku-buildpack-ruby'
144
164
 
145
165
  def test_deploy
146
- Hatchet::AnvilApp.new("rails3_mri_193", buildpack: buildpack_path).deploy do |app|
166
+ Hatchet::GitApp.new("rails3_mri_193", buildpack: buildpack_path).deploy do |app|
147
167
  # ...
148
168
  ```
149
169
 
@@ -155,7 +175,7 @@ If you are using a `Hatchet::GitApp` this is where you specify the publicly avai
155
175
  After Hatchet deploys your app you can get the output by using `app.output`
156
176
 
157
177
  ```ruby
158
- Hatchet::AnvilApp.new("rails3_mri_193").deploy do |app|
178
+ Hatchet::Runner.new("rails3_mri_193").deploy do |app|
159
179
  puts app.output
160
180
  end
161
181
  ```
@@ -163,7 +183,7 @@ end
163
183
  If you told Hatchet to `allow_failure: true` then the full output of the failed build will be in `app.output` even though the app was not deployed. It is a good idea to test against the output for text that should be present. Using a testing framework such as `Test::Unit` a failed test output may look like this
164
184
 
165
185
  ```ruby
166
- Hatchet::AnvilApp.new("no_lockfile", allow_failure: true).deploy do |app|
186
+ Hatchet::Runner.new("no_lockfile", allow_failure: true).deploy do |app|
167
187
  assert_match "Gemfile.lock required", app.output
168
188
  end
169
189
  ```
@@ -175,14 +195,14 @@ Since an error will be raised on failed deploys you don't need to check for a de
175
195
  Often times asserting output of a build can only get you so far, and you will need to actually run a task on the dyno. To run a non-interactive command such as `heroku run ls` you can do this using the `app.run()` command and do not pass it a block
176
196
 
177
197
  ```ruby
178
- Hatchet::AnvilApp.new("rails3_mri_193").deploy do |app|
198
+ Hatchet::Runner.new("rails3_mri_193").deploy do |app|
179
199
  assert_match "applications.css", app.run("ls public/assets")
180
200
  ```
181
201
 
182
202
  This is useful for checking the existence of generated files such as assets. If you need to run an interactive session such as `heroku run bash` or `heroku run rails console` you can use the run command and pass a block:
183
203
 
184
204
  ```ruby
185
- Hatchet::AnvilApp.new("rails3_mri_193").deploy do |app|
205
+ Hatchet::Runner.new("rails3_mri_193").deploy do |app|
186
206
  app.run("bash") do |bash|
187
207
  bash.run("ls") {|result| assert_match "Gemfile.lock", result }
188
208
  bash.run("cat Procfile") {|result| assert_match "web:", result }
@@ -193,7 +213,7 @@ end
193
213
  or
194
214
 
195
215
  ```ruby
196
- Hatchet::AnvilApp.new("rails3_mri_193").deploy do |app|
216
+ Hatchet::Runner.new("rails3_mri_193").deploy do |app|
197
217
  app.run("rails console") do |console|
198
218
  console.run("a = 1 + 2") {|result| assert_match "3", result }
199
219
  console.run("'foo' * a") {|result| assert_match "foofoofoo", result }
@@ -227,6 +247,8 @@ If you're unfamiliar with the ruby testing eco-system or want some help with boi
227
247
 
228
248
  Once you've got your tests working locally, you'll likely want to get them running on Travis because a) CI is awesome, and b) you can use pull requests to run your all your tests in parallel without having to kill your network connection.
229
249
 
250
+ You will want to set the `HATCHET_DEPLOY_STRATEGY` to `git`.
251
+
230
252
  To run on travis you will need to configure your `.travis.yml` to run the appropriate commands and to set up encrypted data so you can run tests against a valid heroku user.
231
253
 
232
254
  For reference see the `.travis.yml` from [hatchet](https://github.com/heroku/hatchet/blob/master/.travis.yml) and the [heroku-ruby-buildpack](https://github.com/heroku/heroku-buildpack-ruby/blob/master/.travis.yml). To make running on travis easier there is a rake task in Hatchet that can be run before your tests are executed
@@ -258,5 +280,8 @@ the command by going to the source code directory and running:
258
280
  $ ./bin/hatchet --help
259
281
 
260
282
 
283
+ ## License
284
+
285
+ MIT
261
286
 
262
287
 
data/lib/hatchet.rb CHANGED
@@ -11,10 +11,26 @@ require 'stringio'
11
11
 
12
12
 
13
13
  module Hatchet
14
- RETRIES = Integer(ENV['HATCHET_RETRIES'] || 1)
14
+ RETRIES = Integer(ENV['HATCHET_RETRIES'] || 1)
15
15
 
16
16
  class App
17
17
  end
18
+
19
+ def self.git_branch
20
+ `git describe --contains --all HEAD`.strip
21
+ end
22
+
23
+ def self.set_deploy_strategy!
24
+ deploy_strat = (ENV['HATCHET_DEPLOY_STRATEGY'] || :anvil).to_sym
25
+ case Hatchet::const_set("DEPLOY_STRATEGY", deploy_strat)
26
+ when :anvil
27
+ Hatchet.const_set("Runner", Hatchet::AnvilApp)
28
+ when :git
29
+ Hatchet.const_set("Runner", Hatchet::GitApp)
30
+ else
31
+ raise "unknown deploy strategy #{Hatchet::DEPLOY_STRATEGY}, expected 'anvil', 'git'"
32
+ end
33
+ end
18
34
  end
19
35
 
20
36
  require 'hatchet/version'
@@ -22,3 +38,6 @@ require 'hatchet/app'
22
38
  require 'hatchet/anvil_app'
23
39
  require 'hatchet/git_app'
24
40
  require 'hatchet/config'
41
+
42
+
43
+ Hatchet.set_deploy_strategy!
@@ -1,10 +1,12 @@
1
1
  module Hatchet
2
2
  # used for deploying a test app to heroku via git
3
3
  class GitApp < App
4
+ HATCHET_BUILDPACK_BASE = (ENV['HATCHET_BUILDPACK_BASE'] || "https://github.com/heroku/heroku-buildpack-ruby.git")
5
+ HATCHET_BUILDPACK_BRANCH = (ENV['HATCHET_BUILDPACK_BRANCH'] || Hatchet.git_branch)
4
6
  BUILDPACK_URL = "https://github.com/heroku/heroku-buildpack-ruby.git"
5
7
 
6
8
  def initialize(directory, options = {})
7
- @buildpack = options[:buildpack] || options[:buildpack_url] || BUILDPACK_URL
9
+ @buildpack = options[:buildpack] || options[:buildpack_url] || [HATCHET_BUILDPACK_BASE, HATCHET_BUILDPACK_BRANCH].join("#")
8
10
  super
9
11
  end
10
12
 
@@ -20,7 +22,7 @@ module Hatchet
20
22
  def push!
21
23
  output = `git push #{git_repo} master 2>&1`
22
24
  if !$?.success?
23
- raise FailedDeploy.new(self, output) unless @allow_failure
25
+ raise FailedDeploy.new(self, "Buildpack: #{@buildpack.inspect}\n#{output}") unless @allow_failure
24
26
  end
25
27
  return output
26
28
  end
@@ -1,3 +1,3 @@
1
1
  module Hatchet
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+
3
+ class HatchetRunnerTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @default = ENV['HATCHET_DEPLOY_STRATEGY']
7
+ end
8
+
9
+ def teardown
10
+ ENV['HATCHET_DEPLOY_STRATEGY'] = @default
11
+ Hatchet.set_deploy_strategy!
12
+ end
13
+
14
+ def test_defaults
15
+ assert_equal nil, ENV['HATCHET_DEPLOY_STRATEGY']
16
+ assert_equal :anvil, Hatchet::DEPLOY_STRATEGY
17
+ assert_equal Hatchet::AnvilApp, Hatchet::Runner
18
+ end
19
+
20
+ def test_change_deploy_strat
21
+ ENV['HATCHET_DEPLOY_STRATEGY'] = "git"
22
+ Hatchet.set_deploy_strategy!
23
+ assert_equal :git, Hatchet::DEPLOY_STRATEGY
24
+ assert_equal Hatchet::GitApp, Hatchet::Runner
25
+
26
+ ENV['HATCHET_DEPLOY_STRATEGY'] = "anvil"
27
+ Hatchet.set_deploy_strategy!
28
+ assert_equal :anvil, Hatchet::DEPLOY_STRATEGY
29
+ assert_equal Hatchet::AnvilApp, Hatchet::Runner
30
+ end
31
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heroku_hatchet
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Schneeman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-26 00:00:00.000000000 Z
11
+ date: 2013-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: heroku-api
@@ -217,6 +217,7 @@ files:
217
217
  - test/hatchet/config_test.rb
218
218
  - test/hatchet/git_test.rb
219
219
  - test/hatchet/multi_cmd_runner_test.rb
220
+ - test/hatchet/runner_test.rb
220
221
  - test/test_helper.rb
221
222
  homepage: https://github.com/heroku/hatchet
222
223
  licenses:
@@ -238,7 +239,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
238
239
  version: '0'
239
240
  requirements: []
240
241
  rubyforge_project:
241
- rubygems_version: 2.0.2
242
+ rubygems_version: 2.0.3
242
243
  signing_key:
243
244
  specification_version: 4
244
245
  summary: Hatchet is a an integration testing library for developing Heroku buildpacks.
@@ -285,4 +286,5 @@ test_files:
285
286
  - test/hatchet/config_test.rb
286
287
  - test/hatchet/git_test.rb
287
288
  - test/hatchet/multi_cmd_runner_test.rb
289
+ - test/hatchet/runner_test.rb
288
290
  - test/test_helper.rb