jenkins-capistrano 0.0.7 → 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.
Files changed (47) hide show
  1. data/.gitignore +73 -16
  2. data/Gemfile.lock +80 -0
  3. data/README.md +169 -56
  4. data/Vagrantfile +23 -0
  5. data/example/Gemfile +3 -1
  6. data/example/README.md +13 -17
  7. data/example/config/deploy.rb +8 -12
  8. data/example/config/deploy/develop.rb +5 -3
  9. data/example/config/deploy/production.rb +13 -3
  10. data/example/config/deploy/staging.rb +13 -4
  11. data/example/config/jenkins/nodes/develop/dev-slave01.xml.erb +33 -0
  12. data/example/config/jenkins/nodes/production/prod-slave01.xml.erb +33 -0
  13. data/example/config/jenkins/nodes/production/prod-slave02.xml.erb +33 -0
  14. data/example/config/jenkins/nodes/production/prod-slave03.xml.erb +33 -0
  15. data/example/config/jenkins/nodes/staging/stg-slave01.xml.erb +33 -0
  16. data/example/config/jenkins/nodes/staging/stg-slave02.xml.erb +33 -0
  17. data/example/config/jenkins/nodes/staging/stg-slave03.xml.erb +33 -0
  18. data/example/script/bootstrap +1 -2
  19. data/features/config_jobs.feature +162 -0
  20. data/features/config_nodes.feature +121 -0
  21. data/features/config_views.feature +136 -0
  22. data/features/help.feature +83 -0
  23. data/features/step_definitions/jenkins_steps.rb +19 -0
  24. data/features/support/env.rb +5 -0
  25. data/features/support/jenkins_helper.rb +113 -0
  26. data/jenkins-capistrano.gemspec +4 -3
  27. data/lib/jenkins-capistrano.rb +2 -215
  28. data/lib/jenkins-capistrano/configurator.rb +87 -0
  29. data/lib/jenkins-capistrano/tasks.rb +112 -0
  30. data/lib/jenkins-capistrano/template.rb +20 -0
  31. data/lib/jenkins-capistrano/version.rb +1 -1
  32. metadata +87 -41
  33. checksums.yaml +0 -7
  34. data/example/config/jenkins/jobs/.gitkeep +0 -0
  35. data/example/config/jenkins/nodes/develop/dev-slave01.json +0 -17
  36. data/example/config/jenkins/nodes/production/prod-slave01.json +0 -17
  37. data/example/config/jenkins/nodes/production/prod-slave02.json +0 -17
  38. data/example/config/jenkins/nodes/production/prod-slave03.json +0 -17
  39. data/example/config/jenkins/nodes/staging/stg-slave01.json +0 -17
  40. data/example/config/jenkins/nodes/staging/stg-slave02.json +0 -17
  41. data/example/config/jenkins/nodes/staging/stg-slave03.json +0 -17
  42. data/lib/jenkins-capistrano/client.rb +0 -66
  43. data/lib/jenkins-capistrano/client/job.rb +0 -47
  44. data/lib/jenkins-capistrano/client/node.rb +0 -103
  45. data/lib/jenkins-capistrano/client/plugin_manager.rb +0 -51
  46. data/lib/jenkins-capistrano/client/update_center.rb +0 -43
  47. data/lib/jenkins-capistrano/client/view.rb +0 -40
@@ -0,0 +1,121 @@
1
+ Feature: Configuring Nodes
2
+
3
+ Scenario: Configuring the new node
4
+ Given the plain Jenkins server
5
+ And a file named "Capfile" with:
6
+ """
7
+ require 'jenkins-capistrano'
8
+ load 'config/deploy'
9
+ """
10
+ And a file named "config/deploy.rb" with:
11
+ """
12
+ set :jenkins_host, 'http://localhost:8080'
13
+ """
14
+ And a file named "config/jenkins/nodes/node1.xml" with:
15
+ """
16
+ <?xml version="1.0" encoding="UTF-8"?>
17
+ <slave>
18
+ <name>node1</name>
19
+ <description>Created</description>
20
+ <remoteFS>/home/jenkins</remoteFS>
21
+ <numExecutors>5</numExecutors>
22
+ <mode>EXCLUSIVE</mode>
23
+ <retentionStrategy class="hudson.slaves.RetentionStrategy$Always"/>
24
+ <launcher class="hudson.plugins.sshslaves.SSHLauncher" plugin="ssh-slaves@1.5">
25
+ <host>node1.lan</host>
26
+ <port>22</port>
27
+ <credentialsId>credential</credentialsId>
28
+ </launcher>
29
+ <label/>
30
+ <nodeProperties/>
31
+ </slave>
32
+ """
33
+ When I successfully run `bundle exec cap jenkins:config_nodes`
34
+ Then the output should contain:
35
+ """
36
+ node node1 created.
37
+ """
38
+ And the Jenkins has following nodes:
39
+ | Name | Description |
40
+ | node1 | Created |
41
+
42
+ Scenario: Configuring the node already created
43
+ Given the Jenkins server has following nodes:
44
+ | Name | Description |
45
+ | node1 | Created |
46
+ And a file named "Capfile" with:
47
+ """
48
+ require 'jenkins-capistrano'
49
+ load 'config/deploy'
50
+ """
51
+ And a file named "config/deploy.rb" with:
52
+ """
53
+ set :jenkins_host, 'http://localhost:8080'
54
+ """
55
+ And a file named "config/jenkins/nodes/node1.xml" with:
56
+ """
57
+ <?xml version="1.0" encoding="UTF-8"?>
58
+ <slave>
59
+ <name>node1</name>
60
+ <description>Updated</description>
61
+ <remoteFS>/home/jenkins</remoteFS>
62
+ <numExecutors>5</numExecutors>
63
+ <mode>EXCLUSIVE</mode>
64
+ <retentionStrategy class="hudson.slaves.RetentionStrategy$Always"/>
65
+ <launcher class="hudson.plugins.sshslaves.SSHLauncher" plugin="ssh-slaves@1.5">
66
+ <host>node1.lan</host>
67
+ <port>22</port>
68
+ <credentialsId>credential</credentialsId>
69
+ </launcher>
70
+ <label/>
71
+ <nodeProperties/>
72
+ </slave>
73
+ """
74
+ When I successfully run `bundle exec cap jenkins:config_nodes`
75
+ Then the output should contain:
76
+ """
77
+ node node1 created.
78
+ """
79
+ And the Jenkins has following nodes:
80
+ | Name | Description |
81
+ | node1 | Updated |
82
+
83
+ Scenario: Configuring the nodes with teamplated config.xmls
84
+ Given the plain Jenkins server
85
+ And a file named "Capfile" with:
86
+ """
87
+ require 'jenkins-capistrano'
88
+ load 'config/deploy'
89
+ """
90
+ And a file named "config/deploy.rb" with:
91
+ """
92
+ set :jenkins_host, 'http://localhost:8080'
93
+ set :jenkins_template_vars, { :templated => 'Yay!!' }
94
+ """
95
+ And a file named "config/jenkins/nodes/node1.xml.erb" with:
96
+ """
97
+ <?xml version="1.0" encoding="UTF-8"?>
98
+ <slave>
99
+ <name>node1</name>
100
+ <description><%= @templated %></description>
101
+ <remoteFS>/home/jenkins</remoteFS>
102
+ <numExecutors>5</numExecutors>
103
+ <mode>EXCLUSIVE</mode>
104
+ <retentionStrategy class="hudson.slaves.RetentionStrategy$Always"/>
105
+ <launcher class="hudson.plugins.sshslaves.SSHLauncher" plugin="ssh-slaves@1.5">
106
+ <host>node1.lan</host>
107
+ <port>22</port>
108
+ <credentialsId>credential</credentialsId>
109
+ </launcher>
110
+ <label/>
111
+ <nodeProperties/>
112
+ </slave>
113
+ """
114
+ When I successfully run `bundle exec cap jenkins:config_nodes`
115
+ Then the Jenkins has following nodes:
116
+ | Name | Description |
117
+ | node1 | Yay!! |
118
+ And the output should contain:
119
+ """
120
+ node node1 created.
121
+ """
@@ -0,0 +1,136 @@
1
+ Feature: Configuring Views
2
+
3
+ Scenario: Configuring the new view
4
+ Given the plain Jenkins server
5
+ And a file named "Capfile" with:
6
+ """
7
+ require 'jenkins-capistrano'
8
+ load 'config/deploy'
9
+ """
10
+ And a file named "config/deploy.rb" with:
11
+ """
12
+ set :jenkins_host, 'http://localhost:8080'
13
+ """
14
+ And a file named "config/jenkins/views/view1.xml" with:
15
+ """
16
+ <listView>
17
+ <name>view1</name>
18
+ <description>Created</description>
19
+ <filterExecutors>false</filterExecutors>
20
+ <filterQueue>false</filterQueue>
21
+ <properties class="hudson.model.View$PropertyList"/>
22
+ <jobNames class="tree-set">
23
+ <comparator class="hudson.util.CaseInsensitiveComparator" reference="../../../hudson.plugins.view.dashboard.Dashboard/jobNames/comparator"/>
24
+ </jobNames>
25
+ <jobFilters/>
26
+ <columns>
27
+ <hudson.views.StatusColumn/>
28
+ <hudson.views.WeatherColumn/>
29
+ <hudson.views.JobColumn/>
30
+ <hudson.views.LastSuccessColumn/>
31
+ <hudson.views.LastFailureColumn/>
32
+ <hudson.views.LastDurationColumn/>
33
+ <hudson.views.BuildButtonColumn/>
34
+ </columns>
35
+ <includeRegex>.*</includeRegex>
36
+ </listView>
37
+ """
38
+ When I successfully run `bundle exec cap jenkins:config_views`
39
+ Then the output should contain:
40
+ """
41
+ view view1 created.
42
+ """
43
+ And the Jenkins has following views:
44
+ | Name | Description |
45
+ | view1 | Created |
46
+
47
+ Scenario: Configuring the view already created
48
+ Given the Jenkins server has following views:
49
+ | Name | Description |
50
+ | view1 | Created |
51
+ And a file named "Capfile" with:
52
+ """
53
+ require 'jenkins-capistrano'
54
+ load 'config/deploy'
55
+ """
56
+ And a file named "config/deploy.rb" with:
57
+ """
58
+ set :jenkins_host, 'http://localhost:8080'
59
+ """
60
+ And a file named "config/jenkins/views/view1.xml" with:
61
+ """
62
+ <listView>
63
+ <name>view1</name>
64
+ <description>Updated</description>
65
+ <filterExecutors>false</filterExecutors>
66
+ <filterQueue>false</filterQueue>
67
+ <properties class="hudson.model.View$PropertyList"/>
68
+ <jobNames class="tree-set">
69
+ <comparator class="hudson.util.CaseInsensitiveComparator" reference="../../../hudson.plugins.view.dashboard.Dashboard/jobNames/comparator"/>
70
+ </jobNames>
71
+ <jobFilters/>
72
+ <columns>
73
+ <hudson.views.StatusColumn/>
74
+ <hudson.views.WeatherColumn/>
75
+ <hudson.views.JobColumn/>
76
+ <hudson.views.LastSuccessColumn/>
77
+ <hudson.views.LastFailureColumn/>
78
+ <hudson.views.LastDurationColumn/>
79
+ <hudson.views.BuildButtonColumn/>
80
+ </columns>
81
+ <includeRegex>.*</includeRegex>
82
+ </listView>
83
+ """
84
+ When I successfully run `bundle exec cap jenkins:config_views`
85
+ Then the output should contain:
86
+ """
87
+ view view1 created.
88
+ """
89
+ And the Jenkins has following views:
90
+ | Name | Description |
91
+ | view1 | Updated |
92
+
93
+ Scenario: Configuring the views with teamplated config.xmls
94
+ Given the plain Jenkins server
95
+ And a file named "Capfile" with:
96
+ """
97
+ require 'jenkins-capistrano'
98
+ load 'config/deploy'
99
+ """
100
+ And a file named "config/deploy.rb" with:
101
+ """
102
+ set :jenkins_host, 'http://localhost:8080'
103
+ set :jenkins_template_vars, { :templated => 'Yay!!' }
104
+ """
105
+ And a file named "config/jenkins/views/view1.xml.erb" with:
106
+ """
107
+ <listView>
108
+ <name>view1</name>
109
+ <description><%= @templated %></description>
110
+ <filterExecutors>false</filterExecutors>
111
+ <filterQueue>false</filterQueue>
112
+ <properties class="hudson.model.View$PropertyList"/>
113
+ <jobNames class="tree-set">
114
+ <comparator class="hudson.util.CaseInsensitiveComparator" reference="../../../hudson.plugins.view.dashboard.Dashboard/jobNames/comparator"/>
115
+ </jobNames>
116
+ <jobFilters/>
117
+ <columns>
118
+ <hudson.views.StatusColumn/>
119
+ <hudson.views.WeatherColumn/>
120
+ <hudson.views.JobColumn/>
121
+ <hudson.views.LastSuccessColumn/>
122
+ <hudson.views.LastFailureColumn/>
123
+ <hudson.views.LastDurationColumn/>
124
+ <hudson.views.BuildButtonColumn/>
125
+ </columns>
126
+ <includeRegex>.*</includeRegex>
127
+ </listView>
128
+ """
129
+ When I successfully run `bundle exec cap jenkins:config_views`
130
+ Then the Jenkins has following views:
131
+ | Name | Description |
132
+ | view1 | Yay!! |
133
+ And the output should contain:
134
+ """
135
+ view view1 created.
136
+ """
@@ -0,0 +1,83 @@
1
+ Feature: Help
2
+
3
+ Scenario: Show help for all tasks
4
+ Given a file named "Capfile" with:
5
+ """
6
+ require 'jenkins-capistrano'
7
+ """
8
+ When I successfully run `bundle exec cap -T`
9
+ Then the output should contain:
10
+ """
11
+ cap invoke # Invoke a single command on the remote servers.
12
+ cap jenkins:config_jobs # Configure the jobs to Jenkins server.
13
+ cap jenkins:config_nodes # Configure the nodes to Jenkins server.
14
+ cap jenkins:config_views # Configure the views to Jenkins server.
15
+ cap jenkins:deploy_jobs # [DEPRECATED] Use jenkins:config_jobs instead.
16
+ cap shell # Begin an interactive Capistrano session.
17
+ """
18
+
19
+ Scenario: Show help for config_jobs
20
+ Given a file named "Capfile" with:
21
+ """
22
+ require 'jenkins-capistrano'
23
+ """
24
+ When I successfully run `bundle exec cap -e jenkins:config_jobs`
25
+ Then the output should contain:
26
+ """
27
+ Configure the jobs to Jenkins server.
28
+
29
+ Configuration
30
+ -------------
31
+ jenkins_job_config_dir
32
+ the directory path where the config.xml stored.
33
+ default: 'config/jenkins/jobs'
34
+
35
+ disabled_jobs
36
+ job names array which should be disabled after deployment.
37
+ default: []
38
+ """
39
+
40
+ Scenario: Show help for config_jobs
41
+ Given a file named "Capfile" with:
42
+ """
43
+ require 'jenkins-capistrano'
44
+ """
45
+ When I successfully run `bundle exec cap -e jenkins:deploy_jobs`
46
+ Then the output should contain:
47
+ """
48
+ [DEPRECATED] Use jenkins:config_jobs instead.
49
+ """
50
+
51
+ Scenario: Show help for config_nodes
52
+ Given a file named "Capfile" with:
53
+ """
54
+ require 'jenkins-capistrano'
55
+ """
56
+ When I successfully run `bundle exec cap -e jenkins:config_nodes`
57
+ Then the output should contain:
58
+ """
59
+ Configure the nodes to Jenkins server.
60
+
61
+ Configuration
62
+ -------------
63
+ jenkins_node_config_dir
64
+ the directory path where the node's configuration stored.
65
+ default: 'config/jenkins/nodes'
66
+ """
67
+
68
+ Scenario: Show help for config_views
69
+ Given a file named "Capfile" with:
70
+ """
71
+ require 'jenkins-capistrano'
72
+ """
73
+ When I successfully run `bundle exec cap -e jenkins:config_views`
74
+ Then the output should contain:
75
+ """
76
+ Configure the views to Jenkins server.
77
+
78
+ Configuration
79
+ -------------
80
+ jenkins_view_config_dir
81
+ the directory path where the view's configuration stored.
82
+ default: 'config/jenkins/views'
83
+ """
@@ -0,0 +1,19 @@
1
+
2
+ Given(/^the plain Jenkins server$/) do
3
+ %w(job node view).each {|t| api.send(t.to_sym).delete_all! }
4
+ end
5
+
6
+ Then(/^the Jenkins has following (job|node|view)s:$/) do |type, table|
7
+ jenkins_has_following_configs type, table
8
+ end
9
+
10
+ Given(/^the Jenkins server has following (job|node|view)s:$/) do |type, table|
11
+ step 'the plain Jenkins server'
12
+ table.hashes.each do |row|
13
+ args = [row['Name'], row['Description'], row['Disabled']].compact
14
+ send("create_#{type}".to_sym, *args)
15
+ end
16
+ # TODO want to call Then step with table inside of Given step, but have no idea.
17
+ # step "Given the Jenkins has following #{type}s:", table
18
+ jenkins_has_following_configs type, table
19
+ end
@@ -0,0 +1,5 @@
1
+ require 'pry'
2
+ require 'aruba/cucumber'
3
+ Before do
4
+ @aruba_timeout_seconds = 600
5
+ end
@@ -0,0 +1,113 @@
1
+ require 'jenkins_api_client'
2
+ require 'nokogiri'
3
+
4
+ module JenkinsHelper
5
+
6
+ def api
7
+ @api ||= JenkinsApi::Client.new(
8
+ :server_url => 'http://localhost:8080',
9
+ :log_location => '/dev/null'
10
+ )
11
+ end
12
+
13
+ def exists?(type, name)
14
+ return api.job.exists?(name) if type == 'job'
15
+ api.send(type.to_s).list.include? name
16
+ end
17
+
18
+ def config(type, name)
19
+ Nokogiri::XML(api.send(type.to_sym).get_config(name))
20
+ end
21
+
22
+ def description(type, name)
23
+ config(type, name).xpath('//description').text
24
+ end
25
+
26
+ def job_disabled?(name)
27
+ config(:job, name).xpath('//disabled').text
28
+ end
29
+
30
+ def jenkins_has_following_configs(type, table)
31
+ table.hashes.each do |row|
32
+ expect(exists?(type, row['Name'])).to eql true
33
+ expect(description(type, row['Name'])).to eql row['Description']
34
+ if disabled = row['Disabled'] # only for the jobs
35
+ expect(job_disabled?(row['Name'])).to eql disabled
36
+ end
37
+ end
38
+ end
39
+
40
+ def create_job(name, description, disabled)
41
+ api.job.create(name, <<-XML.gsub(/^ +/, ''))
42
+ <?xml version="1.0" encoding="UTF-8"?>
43
+ <project>
44
+ <actions/>
45
+ <description>#{description}</description>
46
+ <keepDependencies>false</keepDependencies>
47
+ <properties/>
48
+ <scm class="hudson.scm.NullSCM"/>
49
+ <canRoam>true</canRoam>
50
+ <disabled>#{disabled}</disabled>
51
+ <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
52
+ <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
53
+ <jdk>Default</jdk>
54
+ <triggers/>
55
+ <concurrentBuild>false</concurrentBuild>
56
+ <builders/>
57
+ <publishers/>
58
+ </project>
59
+ XML
60
+ end
61
+
62
+ def create_node(name, description)
63
+ params = { :name => name, :slave_host => 'dummy-by-jenkins-capistrano', :private_key_file => 'dummy' }
64
+ api.node.create_dumb_slave(params)
65
+ api.node.post_config(name, <<-XML.gsub(/^ +/, ''))
66
+ <?xml version="1.0" encoding="UTF-8"?>
67
+ <slave>
68
+ <name>#{name}</name>
69
+ <description>#{description}</description>
70
+ <remoteFS>/home/jenkins</remoteFS>
71
+ <numExecutors>5</numExecutors>
72
+ <mode>EXCLUSIVE</mode>
73
+ <retentionStrategy class="hudson.slaves.RetentionStrategy$Always"/>
74
+ <launcher class="hudson.plugins.sshslaves.SSHLauncher" plugin="ssh-slaves@1.5">
75
+ <host>node1.lan</host>
76
+ <port>22</port>
77
+ <credentialsId>credential</credentialsId>
78
+ </launcher>
79
+ <label/>
80
+ <nodeProperties/>
81
+ </slave>
82
+ XML
83
+ end
84
+
85
+ def create_view(name, description)
86
+ api.view.create name
87
+ api.view.post_config(name, <<-XML.gsub(/^ +/, ''))
88
+ <listView>
89
+ <name>#{name}</name>
90
+ <description>#{description}</description>
91
+ <filterExecutors>false</filterExecutors>
92
+ <filterQueue>false</filterQueue>
93
+ <properties class="hudson.model.View$PropertyList"/>
94
+ <jobNames class="tree-set">
95
+ <comparator class="hudson.util.CaseInsensitiveComparator" reference="../../../hudson.plugins.view.dashboard.Dashboard/jobNames/comparator"/>
96
+ </jobNames>
97
+ <jobFilters/>
98
+ <columns>
99
+ <hudson.views.StatusColumn/>
100
+ <hudson.views.WeatherColumn/>
101
+ <hudson.views.JobColumn/>
102
+ <hudson.views.LastSuccessColumn/>
103
+ <hudson.views.LastFailureColumn/>
104
+ <hudson.views.LastDurationColumn/>
105
+ <hudson.views.BuildButtonColumn/>
106
+ </columns>
107
+ <includeRegex>.*</includeRegex>
108
+ </listView>
109
+ XML
110
+ end
111
+
112
+ end
113
+ World(JenkinsHelper)