engineyard-hudson 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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: []