engineyard-hudson 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +47 -0
- data/History.md +6 -0
- data/README.md +74 -0
- data/Rakefile +19 -0
- data/bin/ey-hudson +7 -0
- data/engineyard-hudson.gemspec +29 -0
- data/features/install.feature +57 -0
- data/features/server.feature +12 -0
- data/features/step_definitions/common_steps.rb +191 -0
- data/features/step_definitions/fixture_project_steps.rb +14 -0
- data/features/step_definitions/hudson_steps.rb +3 -0
- data/features/support/common.rb +37 -0
- data/features/support/env.rb +13 -0
- data/features/support/matchers.rb +10 -0
- data/fixtures/cookbooks/main/recipes/default.rb +1 -0
- data/fixtures/cookbooks/redis/recipes/default.rb +0 -0
- data/fixtures/projects/rails/Gemfile +3 -0
- data/fixtures/projects/rails/Gemfile.lock +10 -0
- data/fixtures/projects/rails/Rakefile +4 -0
- data/lib/engineyard-hudson.rb +4 -0
- data/lib/engineyard-hudson/cli.rb +44 -0
- data/lib/engineyard-hudson/cli/install.rb +62 -0
- data/lib/engineyard-hudson/cli/install/templates/attributes.rb.erb +17 -0
- data/lib/engineyard-hudson/cli/install/templates/cookbooks/main/attributes/recipe.rb +3 -0
- data/lib/engineyard-hudson/cli/install/templates/cookbooks/main/definitions/ey_cloud_report.rb +6 -0
- data/lib/engineyard-hudson/cli/install/templates/cookbooks/main/libraries/ruby_block.rb +40 -0
- data/lib/engineyard-hudson/cli/install/templates/cookbooks/main/libraries/run_for_app.rb +12 -0
- data/lib/engineyard-hudson/cli/install/templates/recipes.rb +83 -0
- metadata +213 -0
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            PATH
         | 
| 2 | 
            +
              remote: .
         | 
| 3 | 
            +
              specs:
         | 
| 4 | 
            +
                engineyard-hudson (0.0.1)
         | 
| 5 | 
            +
                  thor (~> 0.14.3)
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            GEM
         | 
| 8 | 
            +
              remote: http://rubygems.org/
         | 
| 9 | 
            +
              specs:
         | 
| 10 | 
            +
                awesome_print (0.2.1)
         | 
| 11 | 
            +
                builder (2.1.2)
         | 
| 12 | 
            +
                cucumber (0.9.3)
         | 
| 13 | 
            +
                  builder (~> 2.1.2)
         | 
| 14 | 
            +
                  diff-lcs (~> 1.1.2)
         | 
| 15 | 
            +
                  gherkin (~> 2.2.9)
         | 
| 16 | 
            +
                  json (~> 1.4.6)
         | 
| 17 | 
            +
                  term-ansicolor (~> 1.0.5)
         | 
| 18 | 
            +
                diff-lcs (1.1.2)
         | 
| 19 | 
            +
                gherkin (2.2.9)
         | 
| 20 | 
            +
                  json (~> 1.4.6)
         | 
| 21 | 
            +
                  term-ansicolor (~> 1.0.5)
         | 
| 22 | 
            +
                json (1.4.6)
         | 
| 23 | 
            +
                rake (0.8.7)
         | 
| 24 | 
            +
                rspec (2.0.1)
         | 
| 25 | 
            +
                  rspec-core (~> 2.0.1)
         | 
| 26 | 
            +
                  rspec-expectations (~> 2.0.1)
         | 
| 27 | 
            +
                  rspec-mocks (~> 2.0.1)
         | 
| 28 | 
            +
                rspec-core (2.0.1)
         | 
| 29 | 
            +
                rspec-expectations (2.0.1)
         | 
| 30 | 
            +
                  diff-lcs (>= 1.1.2)
         | 
| 31 | 
            +
                rspec-mocks (2.0.1)
         | 
| 32 | 
            +
                  rspec-core (~> 2.0.1)
         | 
| 33 | 
            +
                  rspec-expectations (~> 2.0.1)
         | 
| 34 | 
            +
                term-ansicolor (1.0.5)
         | 
| 35 | 
            +
                thor (0.14.3)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            PLATFORMS
         | 
| 38 | 
            +
              ruby
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            DEPENDENCIES
         | 
| 41 | 
            +
              awesome_print
         | 
| 42 | 
            +
              cucumber (~> 0.9.3)
         | 
| 43 | 
            +
              engineyard-hudson!
         | 
| 44 | 
            +
              json (~> 1.4.0)
         | 
| 45 | 
            +
              rake (~> 0.8.7)
         | 
| 46 | 
            +
              rspec (~> 2.0.1)
         | 
| 47 | 
            +
              thor (~> 0.14.3)
         | 
    
        data/History.md
    ADDED
    
    
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,74 @@ | |
| 1 | 
            +
            # Easier to do CI than not to.
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Run your continuous integration (CI) tests against your Engine Yard AppCloud environments - the exact same configuration you are using in production!
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            You're developing on OS X or Windows, deploying to Engine Yard AppCloud (Gentoo/Linux), and you're running your CI on your local machine or a spare Ubuntu machine in the corner of the office, or ... you're not running CI at all?
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            It's a nightmare. It was for me. [Hudson CI](http://hudson-ci.org/), `engineyard-hudson` and the [hudson](http://github.com/cowboyd/hudson.rb) CLI projects now make CI easier to do than not to. A few commands and your Rails applications' tests are automatically running, no additional setup, and its the same environment you are deploying your Rails applications (Engine Yard AppCloud). Sweet.
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            ## Installation
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                gem install engineyard-hudson
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            ## Assumptions
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            It is assumed you are familiar with the `engineyard` CLI gem.
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            You **do not** need to be familiar with custom chef recipes. Just follow the simple commands. Easy peasy.
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            ## Warning
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            In the very first release of `engineyard-hudson`, there is no support for authentication/authorization of Hudson CI.
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            ## Hosting Hudson CI on Engine Yard AppCloud
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            Instructions *coming soon*.
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            Hosting Hudson CI on Engine Yard AppCloud is optional. It can be hosted anywhere. You need the following information about your Hudson CI:
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            * Hudson CI host (& port)
         | 
| 30 | 
            +
            * Hudson CI's user's public key (probably at /home/hudson/.ssh/id_rsa.pub)
         | 
| 31 | 
            +
            * Hudson CI's user's private key path (probably /home/hudson/.ssh/id_rsa)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            ## Running your tests in Hudson against Engine Yard AppCloud
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            After a couple manual steps, you will have your applications tests running.
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                $ cd /my/project
         | 
| 38 | 
            +
                $ ey-hudson install .
         | 
| 39 | 
            +
                
         | 
| 40 | 
            +
                Finally:
         | 
| 41 | 
            +
                * edit cookbooks/hudson_slave/attributes/default.rb as necessary.
         | 
| 42 | 
            +
                * run: ey recipes upload # use --environment(-e) & --account(-c)
         | 
| 43 | 
            +
                * run: ey recipes apply  #   to select environment
         | 
| 44 | 
            +
                * Boot your environment if not already booted.
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            Done! Either visit your Hudson CI site or use `hudson list` to see the status of your projects being tested.
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            ## Automatically triggering job builds
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            In Hudson CI, a "job" is one of your projects. Each time it runs your tests, it is called a "build".
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            It is often desirable to have your SCM trigger Hudson CI to run your job build whenever you push new code.
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            ### GitHub Service Hooks
         | 
| 55 | 
            +
             | 
| 56 | 
            +
            * Go to the "Admin" section of your GitHub project
         | 
| 57 | 
            +
            * Click "Service Hooks"
         | 
| 58 | 
            +
            * Click "Post-Receive URLs"
         | 
| 59 | 
            +
            * Enter the URL `http://HUDSON-CI-URL/job/APP-NAME/build`
         | 
| 60 | 
            +
            * Click "Update Settings"
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            You can also use the "Test Hook" link to test this is wired up correctly.
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            ### CLI
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            Using the `hudson` CLI:
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                hudson build APP-NAME
         | 
| 69 | 
            +
             | 
| 70 | 
            +
            ### Curl
         | 
| 71 | 
            +
             | 
| 72 | 
            +
            You are triggering the build via a GET call to an URL endpoint. So you can also use `curl`:
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                curl http://HUDSON-CI-URL/job/APP-NAME/build
         | 
    
        data/Rakefile
    ADDED
    
    | @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            require 'bundler'
         | 
| 2 | 
            +
            Bundler::GemHelper.install_tasks
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            namespace :cucumber do
         | 
| 5 | 
            +
              require 'cucumber/rake/task'
         | 
| 6 | 
            +
              Cucumber::Rake::Task.new(:wip, 'Run features that are being worked on') do |t|
         | 
| 7 | 
            +
                t.cucumber_opts = "--tags @wip"
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
              Cucumber::Rake::Task.new(:ok, 'Run features that should be working') do |t|
         | 
| 10 | 
            +
                t.cucumber_opts = "--tags ~@wip"
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
              task :all => [:ok, :wip]
         | 
| 13 | 
            +
            end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            desc 'Alias for cucumber:ok'
         | 
| 16 | 
            +
            task :cucumber => 'cucumber:ok'
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            desc "Start test server; Run cucumber:ok; Kill Test Server;"
         | 
| 19 | 
            +
            task :default => ["cucumber"]
         | 
    
        data/bin/ey-hudson
    ADDED
    
    
| @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            # -*- encoding: utf-8 -*-
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Gem::Specification.new do |s|
         | 
| 4 | 
            +
              s.name        = "engineyard-hudson"
         | 
| 5 | 
            +
              s.version     = '0.1.0'
         | 
| 6 | 
            +
              s.platform    = Gem::Platform::RUBY
         | 
| 7 | 
            +
              s.authors     = ["Dr Nic Williams"]
         | 
| 8 | 
            +
              s.email       = ["drnicwilliams@gmail.com"]
         | 
| 9 | 
            +
              s.homepage    = "http://github.com/engineyard/engineyard-hudson"
         | 
| 10 | 
            +
              s.summary     = %q{Easier to do CI than not to. Use Hudson CI on Engine Yard AppCloud.}
         | 
| 11 | 
            +
              s.description = %q{Run your continuous integration (CI) tests against your Engine Yard AppCloud environments - the exact same configuration you are using in production!}
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              s.rubyforge_project = "engineyard-hudson"
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              s.files         = `git ls-files`.split("\n")
         | 
| 16 | 
            +
              s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         | 
| 17 | 
            +
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         | 
| 18 | 
            +
              s.require_paths = ["lib"]
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              s.add_dependency("thor", ["~> 0.14.3"])
         | 
| 21 | 
            +
              s.add_dependency("engineyard", ["~> 1.3.3"])
         | 
| 22 | 
            +
              # s.add_dependency("hudson", ["~> 0.3.0.beta"])
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              s.add_development_dependency("rake", ["~> 0.8.7"])
         | 
| 25 | 
            +
              s.add_development_dependency("cucumber", ["~> 0.9.3"])
         | 
| 26 | 
            +
              s.add_development_dependency("rspec", ["~> 2.0.1"])
         | 
| 27 | 
            +
              s.add_development_dependency("json", ["~>1.4.0"])
         | 
| 28 | 
            +
              s.add_development_dependency("awesome_print")
         | 
| 29 | 
            +
            end
         | 
| @@ -0,0 +1,57 @@ | |
| 1 | 
            +
            Feature: Managing a rails project as a Hudson CI job on AppCloud
         | 
| 2 | 
            +
              I want to build/test my project in the same environment I run in Engine Yard AppCloud
         | 
| 3 | 
            +
              
         | 
| 4 | 
            +
              Scenario: Setup first project as a slave for Hudson
         | 
| 5 | 
            +
                Given I have an environment "hudson" on account "drnic" on AppCloud
         | 
| 6 | 
            +
                And I have an environment "my_app_ci" on account "drnic" on AppCloud
         | 
| 7 | 
            +
                And I am in the "rails" project folder
         | 
| 8 | 
            +
                When I run local executable "ey-hudson" with arguments "install ."
         | 
| 9 | 
            +
                Then file "cookbooks/hudson_slave/attributes/default.rb" is created
         | 
| 10 | 
            +
                And file "cookbooks/hudson_slave/recipes/default.rb" is created
         | 
| 11 | 
            +
                And file "cookbooks/main/recipes/default.rb" is created
         | 
| 12 | 
            +
                And file "cookbooks/main/libraries/ruby_block.rb" is created
         | 
| 13 | 
            +
                And I should see exactly
         | 
| 14 | 
            +
                  """
         | 
| 15 | 
            +
                        create  cookbooks
         | 
| 16 | 
            +
                        create  cookbooks/main/attributes/recipe.rb
         | 
| 17 | 
            +
                        create  cookbooks/main/definitions/ey_cloud_report.rb
         | 
| 18 | 
            +
                        create  cookbooks/main/libraries/ruby_block.rb
         | 
| 19 | 
            +
                        create  cookbooks/main/libraries/run_for_app.rb
         | 
| 20 | 
            +
                        create  cookbooks/hudson_slave/attributes/default.rb
         | 
| 21 | 
            +
                        create  cookbooks/hudson_slave/recipes/default.rb
         | 
| 22 | 
            +
                        create  cookbooks/main/recipes/default.rb
         | 
| 23 | 
            +
                  
         | 
| 24 | 
            +
                  Finally:
         | 
| 25 | 
            +
                  * edit cookbooks/hudson_slave/attributes/default.rb as necessary.
         | 
| 26 | 
            +
                  * run: ey recipes upload # use --environment(-e) & --account(-c)
         | 
| 27 | 
            +
                  * run: ey recipes apply  #   to select environment
         | 
| 28 | 
            +
                  * Boot your environment if not already booted.
         | 
| 29 | 
            +
                  When the recipe completes, your project will commence its first build on Hudson CI.
         | 
| 30 | 
            +
                  """
         | 
| 31 | 
            +
              
         | 
| 32 | 
            +
              Scenario: Setup project with existing cookbooks as a slave for Hudson
         | 
| 33 | 
            +
                Given I have an environment "hudson" on account "drnic" on AppCloud
         | 
| 34 | 
            +
                And I have an environment "my_app_ci" on account "drnic" on AppCloud
         | 
| 35 | 
            +
                And I am in the "rails" project folder
         | 
| 36 | 
            +
                And I already have cookbooks installed
         | 
| 37 | 
            +
                When I run local executable "ey-hudson" with arguments "install ."
         | 
| 38 | 
            +
                Then file "cookbooks/hudson_slave/attributes/default.rb" is created
         | 
| 39 | 
            +
                And file "cookbooks/hudson_slave/recipes/default.rb" is created
         | 
| 40 | 
            +
                And file "cookbooks/main/recipes/default.rb" is created
         | 
| 41 | 
            +
                And file "cookbooks/redis/recipes/default.rb" is created
         | 
| 42 | 
            +
                And I should see exactly
         | 
| 43 | 
            +
                  """
         | 
| 44 | 
            +
                        create  cookbooks/hudson_slave/attributes/default.rb
         | 
| 45 | 
            +
                        create  cookbooks/hudson_slave/recipes/default.rb
         | 
| 46 | 
            +
                        append  cookbooks/main/recipes/default.rb
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  Finally:
         | 
| 49 | 
            +
                  * edit cookbooks/hudson_slave/attributes/default.rb as necessary.
         | 
| 50 | 
            +
                  * run: ey recipes upload # use --environment(-e) & --account(-c)
         | 
| 51 | 
            +
                  * run: ey recipes apply  #   to select environment
         | 
| 52 | 
            +
                  * Boot your environment if not already booted.
         | 
| 53 | 
            +
                  When the recipe completes, your project will commence its first build on Hudson CI.
         | 
| 54 | 
            +
                  """
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              
         | 
| 57 | 
            +
              
         | 
| @@ -0,0 +1,12 @@ | |
| 1 | 
            +
            @wip
         | 
| 2 | 
            +
            Feature: Managing ey hudson server
         | 
| 3 | 
            +
              I want to setup and manage a Hudson CI server hosted on Engine Yard AppCloud
         | 
| 4 | 
            +
              
         | 
| 5 | 
            +
              Scenario: Setup new Hudson CI server on AppCloud
         | 
| 6 | 
            +
                Given I have an environment "hudson" on account "drnic" on AppCloud
         | 
| 7 | 
            +
                And I am in the "rails" project folder
         | 
| 8 | 
            +
                When I run local executable "ey-hudson" with arguments "server -e hudson -c drnic"
         | 
| 9 | 
            +
                Then I should see "Hudson CI server recipe installed."
         | 
| 10 | 
            +
              
         | 
| 11 | 
            +
              
         | 
| 12 | 
            +
              
         | 
| @@ -0,0 +1,191 @@ | |
| 1 | 
            +
            Given /^this project is active project folder/ do
         | 
| 2 | 
            +
              @active_project_folder = File.expand_path(File.dirname(__FILE__) + "/../..")
         | 
| 3 | 
            +
            end
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Given /^env variable \$([\w_]+) set to( project path|) "(.*)"/ do |env_var, path, value|
         | 
| 6 | 
            +
              in_project_folder {
         | 
| 7 | 
            +
                value = File.expand_path(value)
         | 
| 8 | 
            +
              } unless path.empty?
         | 
| 9 | 
            +
              ENV[env_var] = value
         | 
| 10 | 
            +
            end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            Given /"(.*)" folder is deleted/ do |folder|
         | 
| 13 | 
            +
              in_project_folder { FileUtils.rm_rf folder }
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            When /^I invoke "(.*)" generator with arguments "(.*)"$/ do |generator, arguments|
         | 
| 17 | 
            +
              @stdout = StringIO.new
         | 
| 18 | 
            +
              in_project_folder do
         | 
| 19 | 
            +
                if Object.const_defined?("APP_ROOT")
         | 
| 20 | 
            +
                  APP_ROOT.replace(FileUtils.pwd)
         | 
| 21 | 
            +
                else
         | 
| 22 | 
            +
                  APP_ROOT = FileUtils.pwd
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
                run_generator(generator, arguments.split(' '), SOURCES, :stdout => @stdout)
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
              File.open(File.join(@tmp_root, "generator.out"), "w") do |f|
         | 
| 27 | 
            +
                @stdout.rewind
         | 
| 28 | 
            +
                f << @stdout.read
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            When /^I run executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
         | 
| 33 | 
            +
              @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
         | 
| 34 | 
            +
              in_project_folder do
         | 
| 35 | 
            +
                system "#{executable.inspect} #{arguments} > #{@stdout.inspect} 2> #{@stdout.inspect}"
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            When /^I run project executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
         | 
| 40 | 
            +
              @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
         | 
| 41 | 
            +
              in_project_folder do
         | 
| 42 | 
            +
                system "ruby -rubygems #{executable.inspect} #{arguments} > #{@stdout.inspect} 2> #{@stdout.inspect}"
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
            end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            When /^I run local executable "(.*)" with arguments "(.*)"/ do |executable, arguments|
         | 
| 47 | 
            +
              @stdout = File.expand_path(File.join(@tmp_root, "executable.out"))
         | 
| 48 | 
            +
              executable = File.expand_path(File.join(File.dirname(__FILE__), "/../../bin", executable))
         | 
| 49 | 
            +
              in_project_folder do
         | 
| 50 | 
            +
                system "ruby -rubygems #{executable.inspect} #{arguments} > #{@stdout.inspect} 2> #{@stdout.inspect}"
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
            end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            When /^I invoke task "rake (.*)"/ do |task|
         | 
| 55 | 
            +
              @stdout = File.expand_path(File.join(@tmp_root, "tests.out"))
         | 
| 56 | 
            +
              in_project_folder do
         | 
| 57 | 
            +
                system "bundle exec rake #{task} --trace > #{@stdout.inspect} 2> #{@stdout.inspect}"
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
            end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            Then /^folder "(.*)" (is|is not) created/ do |folder, is|
         | 
| 62 | 
            +
              in_project_folder do
         | 
| 63 | 
            +
                File.exists?(folder).should(is == 'is' ? be_true : be_false)
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
            end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            Then /^file "(.*)" (is|is not) created/ do |file, is|
         | 
| 68 | 
            +
              in_project_folder do
         | 
| 69 | 
            +
                File.exists?(file).should(is == 'is' ? be_true : be_false)
         | 
| 70 | 
            +
              end
         | 
| 71 | 
            +
            end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            Then /^file with name matching "(.*)" is created/ do |pattern|
         | 
| 74 | 
            +
              in_project_folder do
         | 
| 75 | 
            +
                Dir[pattern].should_not be_empty
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
            end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
            Then /^file "(.*)" contents (does|does not) match \/(.*)\// do |file, does, regex|
         | 
| 80 | 
            +
              in_project_folder do
         | 
| 81 | 
            +
                actual_output = File.read(file)
         | 
| 82 | 
            +
                (does == 'does') ?
         | 
| 83 | 
            +
                  actual_output.should(match(/#{regex}/)) :
         | 
| 84 | 
            +
                  actual_output.should_not(match(/#{regex}/))
         | 
| 85 | 
            +
              end
         | 
| 86 | 
            +
            end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
            Then /gem file "(.*)" and generated file "(.*)" should be the same/ do |gem_file, project_file|
         | 
| 89 | 
            +
              File.exists?(gem_file).should be_true
         | 
| 90 | 
            +
              File.exists?(project_file).should be_true
         | 
| 91 | 
            +
              gem_file_contents = File.read(File.dirname(__FILE__) + "/../../#{gem_file}")
         | 
| 92 | 
            +
              project_file_contents = File.read(File.join(@active_project_folder, project_file))
         | 
| 93 | 
            +
              project_file_contents.should == gem_file_contents
         | 
| 94 | 
            +
            end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
            Then /^(does|does not) invoke generator "(.*)"$/ do |does_invoke, generator|
         | 
| 97 | 
            +
              actual_output = get_command_output
         | 
| 98 | 
            +
              does_invoke == "does" ?
         | 
| 99 | 
            +
                actual_output.should(match(/dependency\s+#{generator}/)) :
         | 
| 100 | 
            +
                actual_output.should_not(match(/dependency\s+#{generator}/))
         | 
| 101 | 
            +
            end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
            Then /help options "(.*)" and "(.*)" are displayed/ do |opt1, opt2|
         | 
| 104 | 
            +
              actual_output = get_command_output
         | 
| 105 | 
            +
              actual_output.should match(/#{opt1}/)
         | 
| 106 | 
            +
              actual_output.should match(/#{opt2}/)
         | 
| 107 | 
            +
            end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
            Then /^I should see "([^\"]*)"$/ do |text|
         | 
| 110 | 
            +
              actual_output = get_command_output
         | 
| 111 | 
            +
              actual_output.should contain(text)
         | 
| 112 | 
            +
            end
         | 
| 113 | 
            +
             | 
| 114 | 
            +
            Then /^I should not see "([^\"]*)"$/ do |text|
         | 
| 115 | 
            +
              actual_output =
         | 
| 116 | 
            +
              actual_output.should_not contain(text)
         | 
| 117 | 
            +
            end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
            Then /^I should see$/ do |text|
         | 
| 120 | 
            +
              actual_output = get_command_output
         | 
| 121 | 
            +
              actual_output.should contain(text)
         | 
| 122 | 
            +
            end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
            Then /^I should not see$/ do |text|
         | 
| 125 | 
            +
              actual_output = get_command_output
         | 
| 126 | 
            +
              actual_output.should_not contain(text)
         | 
| 127 | 
            +
            end
         | 
| 128 | 
            +
             | 
| 129 | 
            +
            Then /^I should see exactly$/ do |text|
         | 
| 130 | 
            +
              actual_output = get_command_output
         | 
| 131 | 
            +
              actual_output.should == text
         | 
| 132 | 
            +
            end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
            Then /^I should see all (\d+) tests pass/ do |expected_test_count|
         | 
| 135 | 
            +
              expected = %r{^#{expected_test_count} tests, \d+ assertions, 0 failures, 0 errors}
         | 
| 136 | 
            +
              actual_output = get_command_output
         | 
| 137 | 
            +
              actual_output.should match(expected)
         | 
| 138 | 
            +
            end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
            Then /^I should see all (\d+) examples pass/ do |expected_test_count|
         | 
| 141 | 
            +
              expected = %r{^#{expected_test_count} examples?, 0 failures}
         | 
| 142 | 
            +
              actual_output = get_command_output
         | 
| 143 | 
            +
              actual_output.should match(expected)
         | 
| 144 | 
            +
            end
         | 
| 145 | 
            +
             | 
| 146 | 
            +
            Then /^yaml file "(.*)" contains (\{.*\})/ do |file, yaml|
         | 
| 147 | 
            +
              in_project_folder do
         | 
| 148 | 
            +
                yaml = eval yaml
         | 
| 149 | 
            +
                YAML.load(File.read(file)).should == yaml
         | 
| 150 | 
            +
              end
         | 
| 151 | 
            +
            end
         | 
| 152 | 
            +
             | 
| 153 | 
            +
            Then /^Rakefile can display tasks successfully/ do
         | 
| 154 | 
            +
              @stdout = File.expand_path(File.join(@tmp_root, "rakefile.out"))
         | 
| 155 | 
            +
              in_project_folder do
         | 
| 156 | 
            +
                system "rake -T > #{@stdout.inspect} 2> #{@stdout.inspect}"
         | 
| 157 | 
            +
              end
         | 
| 158 | 
            +
              actual_output = get_command_output
         | 
| 159 | 
            +
              actual_output.should match(/^rake\s+\w+\s+#\s.*/)
         | 
| 160 | 
            +
            end
         | 
| 161 | 
            +
             | 
| 162 | 
            +
            Then /^task "rake (.*)" is executed successfully/ do |task|
         | 
| 163 | 
            +
              @stdout.should_not be_nil
         | 
| 164 | 
            +
              actual_output = get_command_output
         | 
| 165 | 
            +
              actual_output.should_not match(/^Don't know how to build task '#{task}'/)
         | 
| 166 | 
            +
              actual_output.should_not match(/Error/i)
         | 
| 167 | 
            +
            end
         | 
| 168 | 
            +
             | 
| 169 | 
            +
            Then /^gem spec key "(.*)" contains \/(.*)\// do |key, regex|
         | 
| 170 | 
            +
              in_project_folder do
         | 
| 171 | 
            +
                gem_file = Dir["pkg/*.gem"].first
         | 
| 172 | 
            +
                gem_spec = Gem::Specification.from_yaml(`gem spec #{gem_file}`)
         | 
| 173 | 
            +
                spec_value = gem_spec.send(key.to_sym)
         | 
| 174 | 
            +
                spec_value.to_s.should match(/#{regex}/)
         | 
| 175 | 
            +
              end
         | 
| 176 | 
            +
            end
         | 
| 177 | 
            +
             | 
| 178 | 
            +
            Then /^the file "([^\"]*)" is a valid gemspec$/ do |filename|
         | 
| 179 | 
            +
              spec = eval(File.read(filename))
         | 
| 180 | 
            +
              spec.validate
         | 
| 181 | 
            +
            end
         | 
| 182 | 
            +
             | 
| 183 | 
            +
            When /^I create a new node with the following options on "http:\/\/(.+?):(\d+)":$/ do |host, port, table|
         | 
| 184 | 
            +
              options = table.raw.inject({}) do |options, (key, value)|
         | 
| 185 | 
            +
                options[(key.to_sym rescue key) || key] = value
         | 
| 186 | 
            +
                options
         | 
| 187 | 
            +
              end
         | 
| 188 | 
            +
             | 
| 189 | 
            +
              Hudson::Api.setup_base_url(:host => host, :port => port.to_i)
         | 
| 190 | 
            +
              Hudson::Api.add_node(options)
         | 
| 191 | 
            +
            end
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            Given /^I am in the "([^\"]*)" project folder$/ do |project|
         | 
| 2 | 
            +
              project_folder = File.expand_path(File.join(@fixtures_path, "projects", project))
         | 
| 3 | 
            +
              in_tmp_folder do
         | 
| 4 | 
            +
                FileUtils.cp_r(project_folder, project)
         | 
| 5 | 
            +
                setup_active_project_folder(project)
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
            end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            Given /^I already have cookbooks installed$/ do
         | 
| 10 | 
            +
              cookbooks_folder = File.expand_path(File.join(@fixtures_path, "cookbooks"))
         | 
| 11 | 
            +
              in_project_folder do
         | 
| 12 | 
            +
                FileUtils.cp_r(cookbooks_folder, ".")
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            module CommonHelpers
         | 
| 2 | 
            +
              def get_command_output
         | 
| 3 | 
            +
                strip_color_codes(File.read(@stdout)).chomp
         | 
| 4 | 
            +
              end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              def strip_color_codes(text)
         | 
| 7 | 
            +
                text.gsub(/\e\[\d+m/, '')
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              def in_tmp_folder(&block)
         | 
| 11 | 
            +
                FileUtils.chdir(@tmp_root, &block)
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              def in_project_folder(&block)
         | 
| 15 | 
            +
                project_folder = @active_project_folder || @tmp_root
         | 
| 16 | 
            +
                FileUtils.chdir(project_folder, &block)
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              def in_home_folder(&block)
         | 
| 20 | 
            +
                FileUtils.chdir(@home_path, &block)
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              def force_local_lib_override(project_name = @project_name)
         | 
| 24 | 
            +
                rakefile = File.read(File.join(project_name, 'Rakefile'))
         | 
| 25 | 
            +
                File.open(File.join(project_name, 'Rakefile'), "w+") do |f|
         | 
| 26 | 
            +
                  f << "$:.unshift('#{@lib_path}')\n"
         | 
| 27 | 
            +
                  f << rakefile
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              def setup_active_project_folder project_name
         | 
| 32 | 
            +
                @active_project_folder = File.join(@tmp_root, project_name)
         | 
| 33 | 
            +
                @project_name = project_name
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            World(CommonHelpers)
         | 
| @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../../lib'))
         | 
| 2 | 
            +
            require 'engineyard-hudson'
         | 
| 3 | 
            +
            require 'bundler/setup'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Before do
         | 
| 6 | 
            +
              @tmp_root      = File.dirname(__FILE__) + "/../../tmp"
         | 
| 7 | 
            +
              @home_path     = File.expand_path(File.join(@tmp_root, "home"))
         | 
| 8 | 
            +
              @lib_path      = File.expand_path(File.dirname(__FILE__) + "/../../lib")
         | 
| 9 | 
            +
              @fixtures_path = File.expand_path(File.dirname(__FILE__) + "/../../fixtures")
         | 
| 10 | 
            +
              FileUtils.rm_rf   @tmp_root
         | 
| 11 | 
            +
              FileUtils.mkdir_p @home_path
         | 
| 12 | 
            +
              ENV['HOME'] = @home_path
         | 
| 13 | 
            +
            end
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            require_recipe 'redis'
         | 
| 
            File without changes
         | 
| @@ -0,0 +1,44 @@ | |
| 1 | 
            +
            require 'thor'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Engineyard
         | 
| 4 | 
            +
              module Hudson
         | 
| 5 | 
            +
                class CLI < Thor
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                  def self.common_options
         | 
| 8 | 
            +
                    method_option :environment, :type => :string, :aliases => %w(-e), 
         | 
| 9 | 
            +
                      :desc => "Environment in which to deploy this application", :required => true
         | 
| 10 | 
            +
                    method_option :account, :type => :string, :aliases => %w(-c), 
         | 
| 11 | 
            +
                      :desc => "Name of the account you want to deploy in"
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                  
         | 
| 14 | 
            +
                  desc "install PROJECT_PATH", "Install Hudson node/slave recipes into your project."
         | 
| 15 | 
            +
                  def install(project_path)
         | 
| 16 | 
            +
                    require 'engineyard-hudson/cli/install'
         | 
| 17 | 
            +
                    Engineyard::Hudson::Install.start(ARGV[1..-1])
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                  
         | 
| 20 | 
            +
                  desc "server", "Setup a Hudson CI server on AppCloud."
         | 
| 21 | 
            +
                  def server
         | 
| 22 | 
            +
                    shell.say "Coming soon!", :green
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                  
         | 
| 25 | 
            +
                  desc "version", "show version information"
         | 
| 26 | 
            +
                  def version
         | 
| 27 | 
            +
                    shell.say Engineyard::Hudson::VERSION
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  map "-v" => :version, "--version" => :version, "-h" => :help, "--help" => :help
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  private
         | 
| 33 | 
            +
                  def display(text)
         | 
| 34 | 
            +
                    shell.say text
         | 
| 35 | 
            +
                    exit
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  def error(text)
         | 
| 39 | 
            +
                    shell.say "ERROR: #{text}", :red
         | 
| 40 | 
            +
                    exit
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
            end
         | 
| @@ -0,0 +1,62 @@ | |
| 1 | 
            +
            require 'thor/group'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Engineyard
         | 
| 4 | 
            +
              module Hudson
         | 
| 5 | 
            +
                class Install < Thor::Group
         | 
| 6 | 
            +
                  include Thor::Actions
         | 
| 7 | 
            +
                  
         | 
| 8 | 
            +
                  argument :project_path
         | 
| 9 | 
            +
                  
         | 
| 10 | 
            +
                  def self.source_root
         | 
| 11 | 
            +
                    File.join(File.dirname(__FILE__), "install", "templates")
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                  
         | 
| 14 | 
            +
                  def install_cookbooks
         | 
| 15 | 
            +
                    file       = "cookbooks/main/recipes/default.rb"
         | 
| 16 | 
            +
                    unless File.exists?(File.join(destination_root, "cookbooks/main/recipes/default.rb"))
         | 
| 17 | 
            +
                      directory "cookbooks"
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                  
         | 
| 21 | 
            +
                  def attributes
         | 
| 22 | 
            +
                    template "attributes.rb.erb", "cookbooks/hudson_slave/attributes/default.rb"
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                  
         | 
| 25 | 
            +
                  def recipe
         | 
| 26 | 
            +
                    copy_file "recipes.rb", "cookbooks/hudson_slave/recipes/default.rb"
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                  
         | 
| 29 | 
            +
                  def enable_recipe
         | 
| 30 | 
            +
                    file       = "cookbooks/main/recipes/default.rb"
         | 
| 31 | 
            +
                    enable_cmd = "\nrequire_recipe 'hudson_slave'"
         | 
| 32 | 
            +
                    if File.exists?(file_path = File.join(destination_root, file))
         | 
| 33 | 
            +
                      append_file file, enable_cmd
         | 
| 34 | 
            +
                    else
         | 
| 35 | 
            +
                      create_file file, enable_cmd
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                  
         | 
| 39 | 
            +
                  # README:
         | 
| 40 | 
            +
                  #   Finally:
         | 
| 41 | 
            +
                  #   * edit cookbooks/hudson_slave/attributes/default.rb as necessary
         | 
| 42 | 
            +
                  #   * run: ey recipes upload
         | 
| 43 | 
            +
                  #   * run: ey recipes apply
         | 
| 44 | 
            +
                  #   * Boot your environment if not already booted.
         | 
| 45 | 
            +
                  #   When the recipe completes, your project will commence its first build on Hudson CI.
         | 
| 46 | 
            +
                  def readme
         | 
| 47 | 
            +
                    say ""
         | 
| 48 | 
            +
                    say "Finally:"
         | 
| 49 | 
            +
                    say "* edit "; say "cookbooks/hudson_slave/attributes/default.rb ", :yellow; say "as necessary."
         | 
| 50 | 
            +
                    say "* run: "; say "ey recipes upload ", :green; say "# use --environment(-e) & --account(-c)"
         | 
| 51 | 
            +
                    say "* run: "; say "ey recipes apply  ", :green; say "#   to select environment"
         | 
| 52 | 
            +
                    say "* "; say "Boot your environment ", :yellow; say "if not already booted."
         | 
| 53 | 
            +
                    say "When the recipe completes, your project will commence its first build on Hudson CI."
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                  
         | 
| 56 | 
            +
                  private
         | 
| 57 | 
            +
                  def say(msg, color = nil)
         | 
| 58 | 
            +
                    color ? shell.say(msg, color) : shell.say(msg)
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
            end
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            #
         | 
| 2 | 
            +
            # Cookbook Name:: hudson_slave
         | 
| 3 | 
            +
            # Recipe:: default
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            hudson_slave({
         | 
| 7 | 
            +
              :master => {
         | 
| 8 | 
            +
                :host => "ec2-174-129-24-134.compute-1.amazonaws.com",
         | 
| 9 | 
            +
                :port => 80,
         | 
| 10 | 
            +
                :public_key => "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6AWDDDJcsIrY0KA99KPg+UmSjxjPz7+Eu9mO5GaSNn0vvVdsgrgjkh+35AS9k8Gn/DPaQJoNih+DpY5ZHsuY1zlvnvvk+hsCUHOATngARNs6yQMf2IrQqf38SlBPJ/xjt4oopLyqZuZ59xbFMFa0Yr/B7cCpxNpeIMCbwmc8YOtztOG1ZazlxB6eMTwp1V25TxFPh3PqUz9s37NmBEhkRiEyiJzlDSrKwz2y+77VWztQByM30lYAEXc5GwJD1LTaQwlv/thjhwveAzKLIpxzC5TbUjii7L+4iJF/JrjtXAEYmkegXj6lGBpRIdwXTYWMm3jG6gG+MV2nfWmocDzg3Q==",
         | 
| 11 | 
            +
                :master_key_location => "/home/hudson/.ssh/id_rsa"
         | 
| 12 | 
            +
              },
         | 
| 13 | 
            +
              :gem => {
         | 
| 14 | 
            +
                :install => "hudson --pre",
         | 
| 15 | 
            +
                :version => "hudson-0.3.0.beta.13"
         | 
| 16 | 
            +
              }
         | 
| 17 | 
            +
            })
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
             | 
| 2 | 
            +
            class Chef
         | 
| 3 | 
            +
              class Resource
         | 
| 4 | 
            +
                class RubyBlock < Chef::Resource
         | 
| 5 | 
            +
                  def initialize(name, collection=nil, node=nil)
         | 
| 6 | 
            +
                    super(name, collection, node)
         | 
| 7 | 
            +
                    @resource_name = :ruby_block
         | 
| 8 | 
            +
                    @action = :create
         | 
| 9 | 
            +
                    @allowed_actions.push(:create)
         | 
| 10 | 
            +
                  end
         | 
| 11 | 
            +
             
         | 
| 12 | 
            +
                  def block(&block)
         | 
| 13 | 
            +
                    if block
         | 
| 14 | 
            +
                      @block = block
         | 
| 15 | 
            +
                    else
         | 
| 16 | 
            +
                      @block
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
             | 
| 24 | 
            +
            class Chef
         | 
| 25 | 
            +
              class Provider
         | 
| 26 | 
            +
                class RubyBlock < Chef::Provider
         | 
| 27 | 
            +
                  def load_current_resource
         | 
| 28 | 
            +
                    Chef::Log.debug(@new_resource.inspect)
         | 
| 29 | 
            +
                    true
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             
         | 
| 32 | 
            +
                  def action_create
         | 
| 33 | 
            +
                    @new_resource.block.call
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            Chef::Platform.platforms[:default].merge! :ruby_block => Chef::Provider::RubyBlock
         | 
| 40 | 
            +
             | 
| @@ -0,0 +1,83 @@ | |
| 1 | 
            +
            #
         | 
| 2 | 
            +
            # Cookbook Name:: hudson_slave
         | 
| 3 | 
            +
            # Recipe:: default
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            env_name = node[:environment][:name]
         | 
| 7 | 
            +
            username = node[:users].first[:username]
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            if ['solo','app_master'].include?(node[:instance_role]) && env_name =~ /_(ci|hudson_slave)$/
         | 
| 10 | 
            +
              # gem_package "hudson" do
         | 
| 11 | 
            +
              #   source "http://gemcutter.org"
         | 
| 12 | 
            +
              #   version "0.3.0.beta.3"
         | 
| 13 | 
            +
              #   action :install
         | 
| 14 | 
            +
              # end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              execute "install_hudson_in_resin" do
         | 
| 17 | 
            +
                command "/usr/local/ey_resin/ruby/bin/gem install #{node[:hudson_slave][:gem][:install]}"
         | 
| 18 | 
            +
                not_if { FileTest.directory?("/usr/local/ey_resin/ruby/gems/1.8/gems/#{node[:hudson_slave][:gem][:version]}") }
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
              
         | 
| 21 | 
            +
              ruby_block "authorize_hudson_master_key" do
         | 
| 22 | 
            +
                authorized_keys = "/home/#{node[:users].first[:username]}/.ssh/authorized_keys"
         | 
| 23 | 
            +
                block do
         | 
| 24 | 
            +
                  File.open(authorized_keys, "a") do |f|
         | 
| 25 | 
            +
                    f.puts node[:hudson_slave][:master][:public_key]
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
                not_if "grep '#{node[:hudson_slave][:master][:public_key]}' #{authorized_keys}"
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
              
         | 
| 31 | 
            +
              execute "setup-git-config-for-tagging" do
         | 
| 32 | 
            +
                command %Q{ sudo su #{username} -c "git config --global user.email 'you@example.com' && git config --global user.name 'You are Special'" }
         | 
| 33 | 
            +
                not_if  %Q{ sudo su #{username} -c "git config user.email" }
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
              
         | 
| 36 | 
            +
              ruby_block "add-slave-to-master" do
         | 
| 37 | 
            +
                block do
         | 
| 38 | 
            +
                  Gem.clear_paths
         | 
| 39 | 
            +
                  require "hudson"
         | 
| 40 | 
            +
                  require "hudson/config"
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  Hudson::Api.setup_base_url(node[:hudson_slave][:master])
         | 
| 43 | 
            +
                  
         | 
| 44 | 
            +
                  # Tell master about this slave
         | 
| 45 | 
            +
                  Hudson::Api.add_node(
         | 
| 46 | 
            +
                    :name        => env_name,
         | 
| 47 | 
            +
                    :description => "Automatically added by Engine Yard AppCloud for environment #{env_name}",
         | 
| 48 | 
            +
                    :slave_host  => node[:engineyard][:environment][:instances].first[:public_hostname],
         | 
| 49 | 
            +
                    :slave_user  => username,
         | 
| 50 | 
            +
                    :executors   => [node[:applications].size, 1].max,
         | 
| 51 | 
            +
                    :label       => node[:applications].keys.join(" ")
         | 
| 52 | 
            +
                  )
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
                action :create
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              ruby_block "tell-master-about-new-jobs" do
         | 
| 58 | 
            +
                block do
         | 
| 59 | 
            +
                  begin
         | 
| 60 | 
            +
                    job_names   = Hudson::Api.summary["jobs"].map {|job| job["name"]} # TODO Hudson::Api.job_names
         | 
| 61 | 
            +
                    app_names   = node[:applications].keys
         | 
| 62 | 
            +
                    apps_to_add = app_names - job_names
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    # Tell server about each application
         | 
| 65 | 
            +
                    apps_to_add.each do |app_name|
         | 
| 66 | 
            +
                      data = node[:applications][app_name]
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                      job_config = Hudson::JobConfigBuilder.new("rails") do |c|
         | 
| 69 | 
            +
                        c.scm           = data[:repository_name]
         | 
| 70 | 
            +
                        c.assigned_node = app_name
         | 
| 71 | 
            +
                      end
         | 
| 72 | 
            +
                    
         | 
| 73 | 
            +
                      Hudson::Api.create_job(app_name, job_config)
         | 
| 74 | 
            +
                      Hudson::Api.build_job(app_name)
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
                  rescue Errno::ECONNREFUSED, Errno::EAFNOSUPPORT
         | 
| 77 | 
            +
                    raise Exception, "No connection available to the Hudson server (#{Hudson::Api.base_uri})."
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
                action :create
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,213 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification 
         | 
| 2 | 
            +
            name: engineyard-hudson
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            +
              hash: 27
         | 
| 5 | 
            +
              prerelease: false
         | 
| 6 | 
            +
              segments: 
         | 
| 7 | 
            +
              - 0
         | 
| 8 | 
            +
              - 1
         | 
| 9 | 
            +
              - 0
         | 
| 10 | 
            +
              version: 0.1.0
         | 
| 11 | 
            +
            platform: ruby
         | 
| 12 | 
            +
            authors: 
         | 
| 13 | 
            +
            - Dr Nic Williams
         | 
| 14 | 
            +
            autorequire: 
         | 
| 15 | 
            +
            bindir: bin
         | 
| 16 | 
            +
            cert_chain: []
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            date: 2010-10-30 00:00:00 -07:00
         | 
| 19 | 
            +
            default_executable: 
         | 
| 20 | 
            +
            dependencies: 
         | 
| 21 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 22 | 
            +
              name: thor
         | 
| 23 | 
            +
              prerelease: false
         | 
| 24 | 
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         | 
| 25 | 
            +
                none: false
         | 
| 26 | 
            +
                requirements: 
         | 
| 27 | 
            +
                - - ~>
         | 
| 28 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 29 | 
            +
                    hash: 33
         | 
| 30 | 
            +
                    segments: 
         | 
| 31 | 
            +
                    - 0
         | 
| 32 | 
            +
                    - 14
         | 
| 33 | 
            +
                    - 3
         | 
| 34 | 
            +
                    version: 0.14.3
         | 
| 35 | 
            +
              type: :runtime
         | 
| 36 | 
            +
              version_requirements: *id001
         | 
| 37 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 38 | 
            +
              name: engineyard
         | 
| 39 | 
            +
              prerelease: false
         | 
| 40 | 
            +
              requirement: &id002 !ruby/object:Gem::Requirement 
         | 
| 41 | 
            +
                none: false
         | 
| 42 | 
            +
                requirements: 
         | 
| 43 | 
            +
                - - ~>
         | 
| 44 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 45 | 
            +
                    hash: 29
         | 
| 46 | 
            +
                    segments: 
         | 
| 47 | 
            +
                    - 1
         | 
| 48 | 
            +
                    - 3
         | 
| 49 | 
            +
                    - 3
         | 
| 50 | 
            +
                    version: 1.3.3
         | 
| 51 | 
            +
              type: :runtime
         | 
| 52 | 
            +
              version_requirements: *id002
         | 
| 53 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 54 | 
            +
              name: rake
         | 
| 55 | 
            +
              prerelease: false
         | 
| 56 | 
            +
              requirement: &id003 !ruby/object:Gem::Requirement 
         | 
| 57 | 
            +
                none: false
         | 
| 58 | 
            +
                requirements: 
         | 
| 59 | 
            +
                - - ~>
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 61 | 
            +
                    hash: 49
         | 
| 62 | 
            +
                    segments: 
         | 
| 63 | 
            +
                    - 0
         | 
| 64 | 
            +
                    - 8
         | 
| 65 | 
            +
                    - 7
         | 
| 66 | 
            +
                    version: 0.8.7
         | 
| 67 | 
            +
              type: :development
         | 
| 68 | 
            +
              version_requirements: *id003
         | 
| 69 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 70 | 
            +
              name: cucumber
         | 
| 71 | 
            +
              prerelease: false
         | 
| 72 | 
            +
              requirement: &id004 !ruby/object:Gem::Requirement 
         | 
| 73 | 
            +
                none: false
         | 
| 74 | 
            +
                requirements: 
         | 
| 75 | 
            +
                - - ~>
         | 
| 76 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 77 | 
            +
                    hash: 61
         | 
| 78 | 
            +
                    segments: 
         | 
| 79 | 
            +
                    - 0
         | 
| 80 | 
            +
                    - 9
         | 
| 81 | 
            +
                    - 3
         | 
| 82 | 
            +
                    version: 0.9.3
         | 
| 83 | 
            +
              type: :development
         | 
| 84 | 
            +
              version_requirements: *id004
         | 
| 85 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 86 | 
            +
              name: rspec
         | 
| 87 | 
            +
              prerelease: false
         | 
| 88 | 
            +
              requirement: &id005 !ruby/object:Gem::Requirement 
         | 
| 89 | 
            +
                none: false
         | 
| 90 | 
            +
                requirements: 
         | 
| 91 | 
            +
                - - ~>
         | 
| 92 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 93 | 
            +
                    hash: 13
         | 
| 94 | 
            +
                    segments: 
         | 
| 95 | 
            +
                    - 2
         | 
| 96 | 
            +
                    - 0
         | 
| 97 | 
            +
                    - 1
         | 
| 98 | 
            +
                    version: 2.0.1
         | 
| 99 | 
            +
              type: :development
         | 
| 100 | 
            +
              version_requirements: *id005
         | 
| 101 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 102 | 
            +
              name: json
         | 
| 103 | 
            +
              prerelease: false
         | 
| 104 | 
            +
              requirement: &id006 !ruby/object:Gem::Requirement 
         | 
| 105 | 
            +
                none: false
         | 
| 106 | 
            +
                requirements: 
         | 
| 107 | 
            +
                - - ~>
         | 
| 108 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 109 | 
            +
                    hash: 7
         | 
| 110 | 
            +
                    segments: 
         | 
| 111 | 
            +
                    - 1
         | 
| 112 | 
            +
                    - 4
         | 
| 113 | 
            +
                    - 0
         | 
| 114 | 
            +
                    version: 1.4.0
         | 
| 115 | 
            +
              type: :development
         | 
| 116 | 
            +
              version_requirements: *id006
         | 
| 117 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 118 | 
            +
              name: awesome_print
         | 
| 119 | 
            +
              prerelease: false
         | 
| 120 | 
            +
              requirement: &id007 !ruby/object:Gem::Requirement 
         | 
| 121 | 
            +
                none: false
         | 
| 122 | 
            +
                requirements: 
         | 
| 123 | 
            +
                - - ">="
         | 
| 124 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 125 | 
            +
                    hash: 3
         | 
| 126 | 
            +
                    segments: 
         | 
| 127 | 
            +
                    - 0
         | 
| 128 | 
            +
                    version: "0"
         | 
| 129 | 
            +
              type: :development
         | 
| 130 | 
            +
              version_requirements: *id007
         | 
| 131 | 
            +
            description: Run your continuous integration (CI) tests against your Engine Yard AppCloud environments - the exact same configuration you are using in production!
         | 
| 132 | 
            +
            email: 
         | 
| 133 | 
            +
            - drnicwilliams@gmail.com
         | 
| 134 | 
            +
            executables: 
         | 
| 135 | 
            +
            - ey-hudson
         | 
| 136 | 
            +
            extensions: []
         | 
| 137 | 
            +
             | 
| 138 | 
            +
            extra_rdoc_files: []
         | 
| 139 | 
            +
             | 
| 140 | 
            +
            files: 
         | 
| 141 | 
            +
            - .gitignore
         | 
| 142 | 
            +
            - Gemfile
         | 
| 143 | 
            +
            - Gemfile.lock
         | 
| 144 | 
            +
            - History.md
         | 
| 145 | 
            +
            - README.md
         | 
| 146 | 
            +
            - Rakefile
         | 
| 147 | 
            +
            - bin/ey-hudson
         | 
| 148 | 
            +
            - engineyard-hudson.gemspec
         | 
| 149 | 
            +
            - features/install.feature
         | 
| 150 | 
            +
            - features/server.feature
         | 
| 151 | 
            +
            - features/step_definitions/common_steps.rb
         | 
| 152 | 
            +
            - features/step_definitions/fixture_project_steps.rb
         | 
| 153 | 
            +
            - features/step_definitions/hudson_steps.rb
         | 
| 154 | 
            +
            - features/support/common.rb
         | 
| 155 | 
            +
            - features/support/env.rb
         | 
| 156 | 
            +
            - features/support/matchers.rb
         | 
| 157 | 
            +
            - fixtures/cookbooks/main/recipes/default.rb
         | 
| 158 | 
            +
            - fixtures/cookbooks/redis/recipes/default.rb
         | 
| 159 | 
            +
            - fixtures/projects/rails/Gemfile
         | 
| 160 | 
            +
            - fixtures/projects/rails/Gemfile.lock
         | 
| 161 | 
            +
            - fixtures/projects/rails/Rakefile
         | 
| 162 | 
            +
            - lib/engineyard-hudson.rb
         | 
| 163 | 
            +
            - lib/engineyard-hudson/cli.rb
         | 
| 164 | 
            +
            - lib/engineyard-hudson/cli/install.rb
         | 
| 165 | 
            +
            - lib/engineyard-hudson/cli/install/templates/attributes.rb.erb
         | 
| 166 | 
            +
            - lib/engineyard-hudson/cli/install/templates/cookbooks/main/attributes/recipe.rb
         | 
| 167 | 
            +
            - lib/engineyard-hudson/cli/install/templates/cookbooks/main/definitions/ey_cloud_report.rb
         | 
| 168 | 
            +
            - lib/engineyard-hudson/cli/install/templates/cookbooks/main/libraries/ruby_block.rb
         | 
| 169 | 
            +
            - lib/engineyard-hudson/cli/install/templates/cookbooks/main/libraries/run_for_app.rb
         | 
| 170 | 
            +
            - lib/engineyard-hudson/cli/install/templates/recipes.rb
         | 
| 171 | 
            +
            has_rdoc: true
         | 
| 172 | 
            +
            homepage: http://github.com/engineyard/engineyard-hudson
         | 
| 173 | 
            +
            licenses: []
         | 
| 174 | 
            +
             | 
| 175 | 
            +
            post_install_message: 
         | 
| 176 | 
            +
            rdoc_options: []
         | 
| 177 | 
            +
             | 
| 178 | 
            +
            require_paths: 
         | 
| 179 | 
            +
            - lib
         | 
| 180 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         | 
| 181 | 
            +
              none: false
         | 
| 182 | 
            +
              requirements: 
         | 
| 183 | 
            +
              - - ">="
         | 
| 184 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 185 | 
            +
                  hash: 3
         | 
| 186 | 
            +
                  segments: 
         | 
| 187 | 
            +
                  - 0
         | 
| 188 | 
            +
                  version: "0"
         | 
| 189 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 190 | 
            +
              none: false
         | 
| 191 | 
            +
              requirements: 
         | 
| 192 | 
            +
              - - ">="
         | 
| 193 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 194 | 
            +
                  hash: 3
         | 
| 195 | 
            +
                  segments: 
         | 
| 196 | 
            +
                  - 0
         | 
| 197 | 
            +
                  version: "0"
         | 
| 198 | 
            +
            requirements: []
         | 
| 199 | 
            +
             | 
| 200 | 
            +
            rubyforge_project: engineyard-hudson
         | 
| 201 | 
            +
            rubygems_version: 1.3.7
         | 
| 202 | 
            +
            signing_key: 
         | 
| 203 | 
            +
            specification_version: 3
         | 
| 204 | 
            +
            summary: Easier to do CI than not to. Use Hudson CI on Engine Yard AppCloud.
         | 
| 205 | 
            +
            test_files: 
         | 
| 206 | 
            +
            - features/install.feature
         | 
| 207 | 
            +
            - features/server.feature
         | 
| 208 | 
            +
            - features/step_definitions/common_steps.rb
         | 
| 209 | 
            +
            - features/step_definitions/fixture_project_steps.rb
         | 
| 210 | 
            +
            - features/step_definitions/hudson_steps.rb
         | 
| 211 | 
            +
            - features/support/common.rb
         | 
| 212 | 
            +
            - features/support/env.rb
         | 
| 213 | 
            +
            - features/support/matchers.rb
         |