engineyard-hudson 0.2.0 → 0.2.1

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/README.md CHANGED
@@ -4,7 +4,7 @@ Run your continuous integration (CI) tests against your Engine Yard AppCloud env
4
4
 
5
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
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.
7
+ It's a nightmare. It was for me. [Hudson CI](http://hudson-ci.org/), the [hudson](http://github.com/cowboyd/hudson.rb) CLI project, and **engineyard-hudson** now make CI easier to do than not to. A few quick 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
8
 
9
9
  ## Installation
10
10
 
@@ -24,9 +24,8 @@ You **do not** need to be familiar with custom chef recipes. Just follow the sim
24
24
 
25
25
  In the very first release of `engineyard-hudson`:
26
26
 
27
- * there is no support for authentication/authorization of Hudson CI.
28
- * git URLs are converted to public `git://` urls on Hudson; until deploy key support is added
29
- * no mail server configured for Hudson CI build failure notifications
27
+ * There is no support for authentication/authorization of Hudson CI. It _will_ use the deploy keys already installed on your AppCloud instance, as described in engineyard-serverside [#set_up_git_ssh](http://github.com/engineyard/engineyard-serverside/blob/master/lib/engineyard-serverside/strategies/git.rb#L106-134)
28
+ * No mail server configured for Hudson CI build failure notifications.
30
29
 
31
30
  That is, its really only useful - at this very "alpha" instant in time - to Open Source Rails projects. But that's just me being brutally honest.
32
31
 
@@ -50,6 +49,8 @@ Just a few steps and you will have your own Hudson CI:
50
49
 
51
50
  Do those steps and you're done! Now, you either visit your Hudson CI site or use `hudson list` to see the status of your projects being tested.
52
51
 
52
+ Note: the Hudson CI environment in Engine Yard AppCloud must be a single instance "solo".
53
+
53
54
  ### Hosting elsewhere
54
55
 
55
56
  You need the following information about your Hudson CI:
@@ -60,6 +61,8 @@ You need the following information about your Hudson CI:
60
61
 
61
62
  ## Running your tests in Hudson against Engine Yard AppCloud
62
63
 
64
+ This is the exciting part - ensuring that your CI tests are being run in the same environment as your production applications. In this case, on Engine Yard AppCloud.
65
+
63
66
  Just a few steps and you will have your applications' tests running.
64
67
 
65
68
  $ cd /my/project
@@ -73,6 +76,54 @@ Just a few steps and you will have your applications' tests running.
73
76
 
74
77
  Do those steps and you're done! Now, you either visit your Hudson CI site or use `hudson list` to see the status of your projects being tested.
75
78
 
79
+ ### Conventions/Requirements
80
+
81
+ * Do not use your production environment as your Hudson CI slave. There are no guarantees what will happen. I expect bad things.
82
+ * You must name your CI environment with a suffix of `_ci` or `_hudson_slave`.
83
+ * You should not name any other environments with a suffix of `_ci` or `_hudson_slave`; lest they offer themselves to your Hudson CI as slave nodes.
84
+ * Keep your production and CI environments exactly the same. Use the same Ruby implementation/version, same database, and include the same RubyGems and Unix packages. Why? This is the entire point of the exercise: to run your CI tests in the same environment as your production application runs.
85
+
86
+ For example, note the naming convention of the two CI environments below (one ends in `_hudson_slave` and the other `_ci`).
87
+
88
+ <img src="http://img.skitch.com/20101031-dxnk7hbn32yce9rum1ctwjwt1w.png" style="width: 100%">
89
+
90
+ ### What happens?
91
+
92
+ When you boot your Engine Yard AppCloud CI environments, each resulting EC2 instance executes a special "hudson_slave" recipe (see `cookbooks/hudson_slave/recipes/default.rb` in your project). This does three things:
93
+
94
+ * Adds this instance to your Hudson CI server as a slave
95
+ * Adds each Rails/Rack application for the AppCloud environment into your Hudson CI as a "job".
96
+ * Commences the first build of any newly added job.
97
+
98
+ If your CI instances have already been booted and you re-apply the recipes over and over (`ey recipes apply`), nothing good or bad will happen. The instances will stay registered as slaves and the applications will stay registered as Hudson CI jobs.
99
+
100
+ If a new application is on the instance, then a new job will be created on Hudson CI.
101
+
102
+ To delete a job from Hudson CI, you should also delete it from your AppCloud CI environment to ensure it isn't re-added the next time you re-apply or re-build or terminate/boot your CI environment. (To delete a job, use the Hudson CI UI or `hudson remove APP-NAME` from the CLI.)
103
+
104
+ In essence, to add new Rails/Rack applications into your Hudson CI server you:
105
+
106
+ * Add them to one of your Engine Yard AppCloud CI environments (the one that matches the production environment where the application will be hosted)
107
+ * Rebuild the environment or re-apply the custom recipes (`ey recipes apply`)
108
+
109
+ ### Applications are run in their respective CI environment
110
+
111
+ Thusly demonstrated below: the application/job "ci_demo_app" is in the middle of a build on its target slave "ci_demo_app_ci". See the AppCloud UI example above to see the relationship between the application/job names and the environment/slave names.
112
+
113
+ <img src="http://img.skitch.com/20101031-tga2f23wems1acpad1ua41qdmb.png" style="width: 100%">
114
+
115
+ ### Can I add applications/jobs to Hudson CI other ways?
116
+
117
+ Yes. There are three simple ways to get Hudson CI to run tests for your application ("create a job to run builds"). Above is the first: all "applications" on the Engine Yard AppCloud CI environment will automatically become Hudson CI jobs. The alternates are:
118
+
119
+ * Use the `hudson create .` command from the [hudson](http://github.com/cowboyd/hudson.rb) CLI.
120
+
121
+ Pass the `--assigned_node xyz` flag to make the project's test be executed on a specific slave node. "xyz" is the name of another application on your AppCloud account; your tests will be executed on the same instance, with the same version of Ruby etc.
122
+
123
+ * Use the Hudson CI UI to create a new job. As above, you can make sure the tests are run on a specific Engine Yard AppCloud instance by setting the assigned node label to be the same as another AppCloud application in your account that is being tested.
124
+
125
+ Specifically, Hudson CI uses "labels" to match jobs to slaves. A common example usage is to label a Windows slave as "windows". A job could then be restricted to only running on slaves with label "windows". We are using this same mechanism.
126
+
76
127
  ## Automatically triggering job builds
77
128
 
78
129
  In Hudson CI, a "job" is one of your projects. Each time it runs your tests, it is called a "build".
@@ -97,7 +148,7 @@ You can also use the "Test Hook" link to test this is wired up correctly.
97
148
 
98
149
  Using the `hudson` CLI:
99
150
 
100
- hudson build APP-NAME
151
+ hudson build path/to/APP-NAME
101
152
 
102
153
  ### Curl
103
154
 
@@ -107,8 +158,8 @@ You are triggering the build via a GET call to an URL endpoint. So you can also
107
158
 
108
159
  ## Contributions
109
160
 
110
- * Dr Nic Williams
111
- * Bo Jeanes - initial chef recipes for Hudson server + slave
161
+ * Dr Nic Williams ([drnic](http://github.com/drnic))
162
+ * Bodaniel Jeanes ([bjeanes](http://github.com/bjeanes)) - initial chef recipes for [Hudson server + slave](http://github.com/bjeanes/ey-cloud-recipes)
112
163
 
113
164
  ## License
114
165
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "engineyard-hudson"
5
- s.version = '0.2.0'
5
+ s.version = '0.2.1'
6
6
  s.platform = Gem::Platform::RUBY
7
7
  s.authors = ["Dr Nic Williams"]
8
8
  s.email = ["drnicwilliams@gmail.com"]
@@ -6,7 +6,7 @@ Feature: Managing ey hudson server
6
6
  When I run local executable "ey-hudson" with arguments "server ."
7
7
  Then file "cookbooks/main/recipes/default.rb" is created
8
8
  And file "cookbooks/hudson_master/recipes/default.rb" is created
9
- And file "cookbooks/hudson_master/attributes/default.rb" contains ":plugins => %w[git github rake ruby greenballs]"
9
+ And file "cookbooks/hudson_master/attributes/default.rb" contains ":plugins => %w[git github rake ruby greenballs envfile]"
10
10
  And I should see exactly
11
11
  """
12
12
  create cookbooks
@@ -33,7 +33,7 @@ Feature: Managing ey hudson server
33
33
  When I run local executable "ey-hudson" with arguments "server . -p ' chucknorris , googleanalytics '"
34
34
  Then file "cookbooks/main/recipes/default.rb" is created
35
35
  And file "cookbooks/hudson_master/recipes/default.rb" is created
36
- And file "cookbooks/hudson_master/attributes/default.rb" contains ":plugins => %w[git github rake ruby greenballs chucknorris googleanalytics]"
36
+ And file "cookbooks/hudson_master/attributes/default.rb" contains ":plugins => %w[git github rake ruby greenballs envfile chucknorris googleanalytics]"
37
37
 
38
38
 
39
39
 
@@ -5,13 +5,6 @@ module Engineyard
5
5
  module Hudson
6
6
  class CLI < Thor
7
7
 
8
- def self.common_options
9
- method_option :environment, :type => :string, :aliases => %w(-e),
10
- :desc => "Environment in which to deploy this application", :required => true
11
- method_option :account, :type => :string, :aliases => %w(-c),
12
- :desc => "Name of the account you want to deploy in"
13
- end
14
-
15
8
  desc "install PROJECT_PATH", "Install Hudson node/slave recipes into your project."
16
9
  def install(project_path)
17
10
  require 'engineyard-hudson/cli/install'
@@ -26,6 +19,7 @@ module Engineyard
26
19
 
27
20
  desc "version", "show version information"
28
21
  def version
22
+ require 'engineyard-hudson/version'
29
23
  shell.say Engineyard::Hudson::VERSION
30
24
  end
31
25
 
@@ -8,10 +8,10 @@ hudson_slave({
8
8
  :host => "ec2-174-129-24-134.compute-1.amazonaws.com",
9
9
  :port => 80,
10
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"
11
+ :master_key_location => "/home/deploy/.ssh/id_rsa"
12
12
  },
13
13
  :gem => {
14
14
  :install => "hudson --pre",
15
- :version => "hudson-0.3.0.beta.13"
15
+ :version => "hudson-0.3.0.beta.16"
16
16
  }
17
17
  })
@@ -3,15 +3,14 @@
3
3
  # Recipe:: default
4
4
  #
5
5
 
6
- env_name = node[:environment][:name]
7
- username = node[:users].first[:username]
6
+ env_name = node[:environment][:name]
7
+ framework_env = node[:environment][:framework_env]
8
+ username = node[:users].first[:username]
8
9
 
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
10
+ if ['solo','app_master'].include?(node[:instance_role]) && env_name =~ /(ci|hudson_slave)$/
11
+ gem_package "bundler" do
12
+ action :install
13
+ end
15
14
 
16
15
  execute "install_hudson_in_resin" do
17
16
  command "/usr/local/ey_resin/ruby/bin/gem install #{node[:hudson_slave][:gem][:install]}"
@@ -41,6 +40,8 @@ if ['solo','app_master'].include?(node[:instance_role]) && env_name =~ /_(ci|hud
41
40
 
42
41
  Hudson::Api.setup_base_url(node[:hudson_slave][:master])
43
42
 
43
+ Hudson::Api.delete_node(env_name)
44
+
44
45
  # Tell master about this slave
45
46
  Hudson::Api.add_node(
46
47
  :name => env_name,
@@ -57,7 +58,7 @@ if ['solo','app_master'].include?(node[:instance_role]) && env_name =~ /_(ci|hud
57
58
  ruby_block "tell-master-about-new-jobs" do
58
59
  block do
59
60
  begin
60
- job_names = Hudson::Api.summary["jobs"].map {|job| job["name"]} # TODO Hudson::Api.job_names
61
+ job_names = Hudson::Api.job_names
61
62
  app_names = node[:applications].keys
62
63
  apps_to_add = app_names - job_names
63
64
 
@@ -65,9 +66,20 @@ if ['solo','app_master'].include?(node[:instance_role]) && env_name =~ /_(ci|hud
65
66
  apps_to_add.each do |app_name|
66
67
  data = node[:applications][app_name]
67
68
 
68
- job_config = Hudson::JobConfigBuilder.new("rails") do |c|
69
+ # job_config = Hudson::JobConfigBuilder.new("rails") do |c|
70
+ job_config = Hudson::JobConfigBuilder.new do |c|
69
71
  c.scm = data[:repository_name]
70
72
  c.assigned_node = app_name
73
+ c.envfile = "/data/#{app_name}/shared/config/git-env"
74
+ c.steps = [
75
+ [:build_shell_step, "bundle install"],
76
+ [:build_ruby_step, <<-RUBY.gsub(/^ /, '')],
77
+ appcloud_database = "/data/#{app_name}/shared/config/database.yml"
78
+ FileUtils.cp appcloud_database, "config/database.yml"
79
+ RUBY
80
+ [:build_shell_step, "bundle exec rake db:schema:load RAILS_ENV=#{framework_env} RACK_ENV=#{framework_env}"],
81
+ [:build_shell_step, "bundle exec rake RAILS_ENV=#{framework_env} RACK_ENV=#{framework_env}"]
82
+ ]
71
83
  end
72
84
 
73
85
  Hudson::Api.create_job(app_name, job_config)
@@ -18,7 +18,7 @@ module Engineyard
18
18
  end
19
19
 
20
20
  def attributes
21
- @plugins = %w[git github rake ruby greenballs] + (options[:plugins] || '').strip.split(/\s*,\s*/)
21
+ @plugins = %w[git github rake ruby greenballs envfile] + (options[:plugins] || '').strip.split(/\s*,\s*/)
22
22
  template "attributes.rb.tt", "cookbooks/hudson_master/attributes/default.rb"
23
23
  end
24
24
 
@@ -0,0 +1,5 @@
1
+ module Engineyard
2
+ module Hudson
3
+ VERSION = '0.2.1'
4
+ end
5
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: engineyard-hudson
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 0
10
- version: 0.2.0
9
+ - 1
10
+ version: 0.2.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Dr Nic Williams
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-30 00:00:00 -07:00
18
+ date: 2010-11-03 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -179,6 +179,7 @@ files:
179
179
  - lib/engineyard-hudson/cli/server/templates/cookbooks/main/libraries/run_for_app.rb
180
180
  - lib/engineyard-hudson/cli/server/templates/cookbooks/main/recipes/default.rb
181
181
  - lib/engineyard-hudson/thor-ext/actions/directory.rb
182
+ - lib/engineyard-hudson/version.rb
182
183
  has_rdoc: true
183
184
  homepage: http://github.com/engineyard/engineyard-hudson
184
185
  licenses: []