autoproj-jenkins 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +41 -0
  6. data/Rakefile +11 -0
  7. data/autoproj-jenkins.gemspec +28 -0
  8. data/lib/autoproj/cli/jenkins.rb +100 -0
  9. data/lib/autoproj/cli/main_jenkins.rb +123 -0
  10. data/lib/autoproj/cli/test_postprocessing.rb +85 -0
  11. data/lib/autoproj/jenkins/credentials.rb +67 -0
  12. data/lib/autoproj/jenkins/exceptions.rb +7 -0
  13. data/lib/autoproj/jenkins/relativize.rb +74 -0
  14. data/lib/autoproj/jenkins/render_template.rb +92 -0
  15. data/lib/autoproj/jenkins/server.rb +79 -0
  16. data/lib/autoproj/jenkins/templates/abort-if-upstream-failed.pipeline.erb +18 -0
  17. data/lib/autoproj/jenkins/templates/bootstrap.pipeline.erb +27 -0
  18. data/lib/autoproj/jenkins/templates/buildconf-Gemfile +3 -0
  19. data/lib/autoproj/jenkins/templates/buildconf-config.yml.erb +12 -0
  20. data/lib/autoproj/jenkins/templates/buildconf-vagrant-Gemfile +4 -0
  21. data/lib/autoproj/jenkins/templates/buildconf.pipeline.erb +43 -0
  22. data/lib/autoproj/jenkins/templates/buildconf.xml.erb +24 -0
  23. data/lib/autoproj/jenkins/templates/handle-downstream.pipeline.erb +20 -0
  24. data/lib/autoproj/jenkins/templates/import-archive.pipeline.erb +2 -0
  25. data/lib/autoproj/jenkins/templates/import-git.pipeline.erb +16 -0
  26. data/lib/autoproj/jenkins/templates/import-svn.pipeline.erb +13 -0
  27. data/lib/autoproj/jenkins/templates/jenkins_dependency_overrides.rb.erb +5 -0
  28. data/lib/autoproj/jenkins/templates/package-Gemfile +2 -0
  29. data/lib/autoproj/jenkins/templates/package.pipeline.erb +102 -0
  30. data/lib/autoproj/jenkins/templates/package.xml.erb +23 -0
  31. data/lib/autoproj/jenkins/templates/setup-git-credentials.pipeline.erb +8 -0
  32. data/lib/autoproj/jenkins/templates/wait-upstream.pipeline.erb +160 -0
  33. data/lib/autoproj/jenkins/test_format_converters/boost-test.xsl +347 -0
  34. data/lib/autoproj/jenkins/updater.rb +214 -0
  35. data/lib/autoproj/jenkins/version.rb +5 -0
  36. data/lib/autoproj/jenkins.rb +19 -0
  37. data/lib/autoproj-jenkins.rb +8 -0
  38. metadata +179 -0
@@ -0,0 +1,214 @@
1
+ module Autoproj::Jenkins
2
+ # Returns true if the given VCS type is supported
3
+ #
4
+ # @param [#to_s] vcs the VCS type (e.g. 'git')
5
+ def self.vcs_supported?(vcs)
6
+ Autoproj::Jenkins.has_template?("import-#{vcs}.pipeline")
7
+ end
8
+
9
+ # Update a jenkins server configuration from an autoproj workspace
10
+ class Updater
11
+ # The autoproj workspace
12
+ #
13
+ # @return [Autoproj::Workspace]
14
+ attr_reader :ws
15
+
16
+ # The server we have to update
17
+ #
18
+ # @return [Server]
19
+ attr_reader :server
20
+
21
+ # A string that is prefixed to all job names
22
+ #
23
+ # @return [String]
24
+ attr_reader :job_prefix
25
+
26
+ # Create a new updater context for an autoproj workspace and Jenkins
27
+ # server
28
+ #
29
+ # @param [Autoproj::Workspace] ws
30
+ # @param [Server] server
31
+ # @param [String] job_prefix a string that should be prefixed to all job
32
+ # names
33
+ def initialize(ws, server, job_prefix: '')
34
+ @ws = ws
35
+ @server = server
36
+ @job_prefix = job_prefix
37
+ end
38
+
39
+ # Create the master buildconf job
40
+ #
41
+ # @return [void]
42
+ def create_buildconf_job(force: false, quiet_period: 5)
43
+ if force
44
+ server.delete_job("#{job_prefix}buildconf")
45
+ end
46
+ server.create_job("#{job_prefix}buildconf", 'buildconf.xml', quiet_period: quiet_period)
47
+ end
48
+
49
+ # Update the buildconf pipeline
50
+ #
51
+ # @param [String] jenkins_url the URL of the jenkins server from the
52
+ # point of view of the job's execution
53
+ # @param [String] gemfile the gemfile template that should be used for
54
+ # the autoproj bootstrap. Mostly used for autoproj-jenkins development
55
+ # within VMs
56
+ # @param [String] autoproj_install_path a path local to the jenkins
57
+ # workspace where the autoproj_install script will be. If unset,
58
+ # downloads it from github.com
59
+ # @param [Boolean] dev whether the packages pipelines should be updated
60
+ # with --dev or not
61
+ # @param [Array<Autoproj::PackageDefinition>] packages if non-empty,
62
+ # restrict operations to these packages and their dependencies
63
+ def update_buildconf_pipeline(*package_names, gemfile: 'buildconf-Gemfile', autoproj_install_path: nil, dev: false, credentials_id: nil, vcs_credentials: Credentials.new)
64
+ manifest_vcs = ws.manifest.vcs
65
+ if manifest_vcs.local? || manifest_vcs.none?
66
+ raise ArgumentError, "cannot use Jenkins to build an autoproj buildconf that is not on a remotely acessible VCS"
67
+ end
68
+
69
+ server.update_job_pipeline("#{job_prefix}buildconf", 'buildconf.pipeline',
70
+ vcs: manifest_vcs,
71
+ package_names: package_names,
72
+ gemfile: gemfile,
73
+ autoproj_install_path: autoproj_install_path,
74
+ job_prefix: job_prefix,
75
+ credentials_id: credentials_id,
76
+ vcs_credentials: vcs_credentials,
77
+ dev: dev)
78
+ end
79
+
80
+ # Create or update the buildconf (master) job
81
+ #
82
+ # @param [Array<Autoproj::PackageDefinition>] packages if non-empty,
83
+ # restrict operations to these packages and their dependencies
84
+ # @param [String] gemfile the gemfile template that should be used for
85
+ # the autoproj bootstrap. Mostly used for autoproj-jenkins development
86
+ # within VMs
87
+ # @param [Integer] quiet_period the job's quiet period, in seconds.
88
+ # Mostly used within autoproj-jenkins tests
89
+ def create_or_update_buildconf_job(*packages, gemfile: 'buildconf-Gemfile', autoproj_install_path: nil, dev: false, quiet_period: 5, credentials_id: nil, vcs_credentials: Credentials.new)
90
+ job_name = "#{job_prefix}buildconf"
91
+ if !server.has_job?(job_name)
92
+ create_buildconf_job(quiet_period: quiet_period)
93
+ end
94
+ update_buildconf_pipeline(
95
+ *packages,
96
+ gemfile: gemfile,
97
+ autoproj_install_path: autoproj_install_path,
98
+ credentials_id: credentials_id,
99
+ vcs_credentials: vcs_credentials,
100
+ dev: dev)
101
+ end
102
+
103
+ # Returns the job name of a given package
104
+ #
105
+ # @param [String] package_name
106
+ # @return [String]
107
+ def job_name_from_package_name(package_name)
108
+ "#{job_prefix}#{package_name.gsub('/', '-')}"
109
+ end
110
+
111
+ # Create a job for a package
112
+ #
113
+ # @return [void]
114
+ def create_package_job(package, job_name: job_name_from_package_name(package.name), force: false, quiet_period: 5)
115
+ job_name = job_name_from_package_name(package.name)
116
+ if force
117
+ server.delete_job(job_name)
118
+ end
119
+
120
+ server.create_job(job_name, 'package.xml', quiet_period: quiet_period)
121
+ end
122
+
123
+ # Resolve a package by its name
124
+ def package_by_name(package_name)
125
+ package = ws.manifest.find_package_definition(package_name)
126
+ if !package
127
+ raise ArgumentError, "no package called #{package_name}"
128
+ end
129
+ end
130
+
131
+ def compute_upstream_packages(package)
132
+ upstream_packages = package.autobuild.dependencies.inject(Set.new) do |all, pkg_name|
133
+ all << pkg_name
134
+ ws.manifest.find_autobuild_package(pkg_name).all_dependencies(all)
135
+ end
136
+ upstream_packages.delete(package.name)
137
+ upstream_packages
138
+ end
139
+
140
+ def compute_downstream_packages(package, reverse_dependencies)
141
+ queue = [package.name]
142
+ results = Set.new
143
+ while !queue.empty?
144
+ p_name = queue.shift
145
+ if !results.include?(p_name)
146
+ results << p_name
147
+ queue.concat(reverse_dependencies[p_name].to_a)
148
+ end
149
+ end
150
+ results.delete(package.name)
151
+ results
152
+ end
153
+
154
+ def compute_job_to_package_map(package_names, included_package_names)
155
+ result = Hash.new
156
+ package_names.each do |pkg_name|
157
+ if included_package_names.include?(pkg_name)
158
+ job_name = job_name_from_package_name(pkg_name)
159
+ result[job_name] = pkg_name
160
+ end
161
+ end
162
+ result
163
+ end
164
+
165
+ # Create jobs and dependencies to handle the given set of packages
166
+ #
167
+ # @return [Array<String>] the list of names of the jobs that have been
168
+ # created/updated
169
+ def update(*packages, quiet_period: 5, gemfile: 'buildconf-Gemfile', autoproj_install_path: nil, vcs_credentials: Credentials.new)
170
+ reverse_dependencies = ws.manifest.compute_revdeps
171
+
172
+ packages.each do |package|
173
+ job_name = job_name_from_package_name(package.name)
174
+ if !server.has_job?(job_name)
175
+ create_package_job(package, job_name: job_name, quiet_period: quiet_period)
176
+ end
177
+ end
178
+
179
+ package_names = packages.map(&:name).to_set
180
+ packages.map do |package|
181
+ job_name = job_name_from_package_name(package.name)
182
+ if !Autoproj::Jenkins.vcs_supported?(package.vcs.type)
183
+ raise UnhandledVCS, "the #{package.vcs.type} importer, used by #{package.name}, is not supported by autoproj-jenkins"
184
+ end
185
+
186
+ upstream_jobs = compute_job_to_package_map(compute_upstream_packages(package), package_names)
187
+ downstream_jobs = compute_job_to_package_map(compute_downstream_packages(package, reverse_dependencies), package_names)
188
+
189
+ prefix_relative_path =
190
+ if package.autobuild.srcdir == package.autobuild.prefix
191
+ Pathname.new(package.autobuild.srcdir).
192
+ relative_path_from(Pathname.new(ws.root_dir)).to_s
193
+ else
194
+ "install/#{package.name}"
195
+ end
196
+
197
+ server.update_job_pipeline(job_name, 'package.pipeline',
198
+ buildconf_vcs: ws.manifest.vcs,
199
+ vcs: package.vcs,
200
+ package_name: package.name,
201
+ package_dir: Pathname.new(package.autobuild.srcdir).relative_path_from(Pathname.new(ws.root_dir)).to_s,
202
+ artifact_glob: "**/*",
203
+ job_name: job_name,
204
+ upstream_jobs: upstream_jobs,
205
+ downstream_jobs: downstream_jobs,
206
+ gemfile: gemfile,
207
+ autoproj_install_path: autoproj_install_path,
208
+ vcs_credentials: vcs_credentials)
209
+
210
+ job_name
211
+ end
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,5 @@
1
+ module Autoproj
2
+ module Jenkins
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,19 @@
1
+ require 'find'
2
+ require 'pathname'
3
+ require 'set'
4
+ require 'jenkins_api_client'
5
+ require "autoproj"
6
+ require "autoproj/autobuild"
7
+ require "autoproj/jenkins/version"
8
+ require "autoproj/jenkins/exceptions"
9
+ require "autoproj/jenkins/render_template"
10
+ require "autoproj/jenkins/server"
11
+ require "autoproj/jenkins/updater"
12
+ require "autoproj/jenkins/relativize"
13
+ require "autoproj/jenkins/credentials"
14
+
15
+ module Autoproj
16
+ module Jenkins
17
+ # Your code goes here...
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ require 'autoproj/cli/main_jenkins'
2
+
3
+ class Autoproj::CLI::Main
4
+ desc 'jenkins', 'jenkins-specific functionality'
5
+ subcommand 'jenkins', Autoproj::CLI::MainJenkins
6
+ end
7
+
8
+
metadata ADDED
@@ -0,0 +1,179 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: autoproj-jenkins
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sylvain Joyeux
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-09-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jenkins_api_client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: autoproj
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.0.rc20
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 2.0.0.rc20
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.12'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '11.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '11.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: flexmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description:
112
+ email:
113
+ - sylvain.joyeux@m4x.org
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - Gemfile
120
+ - LICENSE.txt
121
+ - README.md
122
+ - Rakefile
123
+ - autoproj-jenkins.gemspec
124
+ - lib/autoproj-jenkins.rb
125
+ - lib/autoproj/cli/jenkins.rb
126
+ - lib/autoproj/cli/main_jenkins.rb
127
+ - lib/autoproj/cli/test_postprocessing.rb
128
+ - lib/autoproj/jenkins.rb
129
+ - lib/autoproj/jenkins/credentials.rb
130
+ - lib/autoproj/jenkins/exceptions.rb
131
+ - lib/autoproj/jenkins/relativize.rb
132
+ - lib/autoproj/jenkins/render_template.rb
133
+ - lib/autoproj/jenkins/server.rb
134
+ - lib/autoproj/jenkins/templates/abort-if-upstream-failed.pipeline.erb
135
+ - lib/autoproj/jenkins/templates/bootstrap.pipeline.erb
136
+ - lib/autoproj/jenkins/templates/buildconf-Gemfile
137
+ - lib/autoproj/jenkins/templates/buildconf-config.yml.erb
138
+ - lib/autoproj/jenkins/templates/buildconf-vagrant-Gemfile
139
+ - lib/autoproj/jenkins/templates/buildconf.pipeline.erb
140
+ - lib/autoproj/jenkins/templates/buildconf.xml.erb
141
+ - lib/autoproj/jenkins/templates/handle-downstream.pipeline.erb
142
+ - lib/autoproj/jenkins/templates/import-archive.pipeline.erb
143
+ - lib/autoproj/jenkins/templates/import-git.pipeline.erb
144
+ - lib/autoproj/jenkins/templates/import-svn.pipeline.erb
145
+ - lib/autoproj/jenkins/templates/jenkins_dependency_overrides.rb.erb
146
+ - lib/autoproj/jenkins/templates/package-Gemfile
147
+ - lib/autoproj/jenkins/templates/package.pipeline.erb
148
+ - lib/autoproj/jenkins/templates/package.xml.erb
149
+ - lib/autoproj/jenkins/templates/setup-git-credentials.pipeline.erb
150
+ - lib/autoproj/jenkins/templates/wait-upstream.pipeline.erb
151
+ - lib/autoproj/jenkins/test_format_converters/boost-test.xsl
152
+ - lib/autoproj/jenkins/updater.rb
153
+ - lib/autoproj/jenkins/version.rb
154
+ homepage: https://github.com/doudou/autoproj-jenkins
155
+ licenses:
156
+ - MIT
157
+ metadata: {}
158
+ post_install_message:
159
+ rdoc_options: []
160
+ require_paths:
161
+ - lib
162
+ required_ruby_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ required_rubygems_version: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - ">="
170
+ - !ruby/object:Gem::Version
171
+ version: '0'
172
+ requirements: []
173
+ rubyforge_project:
174
+ rubygems_version: 2.5.1
175
+ signing_key:
176
+ specification_version: 4
177
+ summary: Exporting an autoproj build to a jenkins server
178
+ test_files: []
179
+ has_rdoc: