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,92 @@
1
+ module Autoproj::Jenkins
2
+ class UnusedTemplateParameters < ArgumentError; end
3
+ class UnknownTemplateParameter < ArgumentError; end
4
+
5
+ # @api private
6
+ #
7
+ # A rendering context for ERB templates
8
+ #
9
+ # It ensures that the templates are restricted to use the parameters that
10
+ # are provided to them
11
+ class TemplateRenderingContext < BasicObject
12
+ def initialize(template_path, allow_unused: false, indent: 0, **parameters)
13
+ @allow_unused = allow_unused
14
+ @indent = indent
15
+ @template_path = template_path
16
+ @parameters = parameters
17
+ @used_parameters = ::Set.new
18
+ end
19
+
20
+ def __verify
21
+ return if @allow_unused
22
+
23
+ unused_parameters = @parameters.keys.to_set -
24
+ @used_parameters
25
+ if !unused_parameters.empty?
26
+ ::Kernel.raise ::Autoproj::Jenkins::UnusedTemplateParameters, "#{unused_parameters.size} unused parameters: #{unused_parameters.map(&:to_s).sort.join(", ")}"
27
+ end
28
+ end
29
+
30
+ def render_template(path, escape: false, indent: 0, **parameters)
31
+ result = ::Autoproj::Jenkins.render_template(path, template_path: @template_path, indent: indent, **parameters)
32
+ @used_parameters.merge(parameters.keys)
33
+ if escape
34
+ result = escape_to_groovy(result)
35
+ end
36
+
37
+ indent_string = " " * indent
38
+ # We assume that the ERB tag for render_template is indented
39
+ # properly
40
+ result.split("\n").join("\n#{indent_string}")
41
+ end
42
+
43
+ def read_and_escape_file(path)
44
+ file_data = (::Autoproj::Jenkins.template_path + path).read
45
+ escape_to_groovy(file_data)
46
+ end
47
+
48
+ def escape_to_groovy(content)
49
+ content.
50
+ gsub("\n", "\\n").
51
+ gsub("\"", "\\\"")
52
+ end
53
+
54
+ def method_missing(m)
55
+ if @parameters.has_key?(m)
56
+ result = @parameters.fetch(m)
57
+ @used_parameters << m
58
+ result
59
+ else
60
+ ::Kernel.raise ::Autoproj::Jenkins::UnknownTemplateParameter, "#{m} is not a known template parameter"
61
+ end
62
+ end
63
+ end
64
+
65
+ # The path to autoproj-jenkins templates
66
+ def self.template_path
67
+ Pathname.new(__dir__) + "templates"
68
+ end
69
+
70
+ # Test if a template with the given basename exists
71
+ def self.has_template?(template_name)
72
+ (template_path + "#{template_name}.erb").exist?
73
+ end
74
+
75
+ # Create a template rendering context for the given parameters
76
+ #
77
+ # @param [String] template_name the name of the template to be rendered,
78
+ # without the .erb extension
79
+ # @param [Hash<Symbol,Object>] parameters the template parameters
80
+ # @param [Pathname] template_path where the templates are located on disk
81
+ # @return [String]
82
+ def self.render_template(template_name, allow_unused: false, template_path: self.template_path, **parameters)
83
+ context = TemplateRenderingContext.new(template_path, allow_unused: allow_unused, **parameters)
84
+ template_path = template_path + "#{template_name}.erb"
85
+ template = ERB.new(template_path.read)
86
+ template.filename = template_path.to_s
87
+ b = context.instance_eval { Kernel.binding }
88
+ result = template.result(b)
89
+ context.__verify
90
+ result
91
+ end
92
+ end
@@ -0,0 +1,79 @@
1
+ module Autoproj::Jenkins
2
+ # The interface to a Jenkins server
3
+ class Server
4
+ # The underlying client
5
+ #
6
+ # @return [JenkinsApi::Client]
7
+ attr_reader :client
8
+
9
+ # The job-related API
10
+ #
11
+ # @return [JenkinsApi::Client::Job]
12
+ attr_reader :jobs
13
+
14
+ def initialize(**options)
15
+ @client = JenkinsApi::Client.new(log_location: STDERR, **options)
16
+ @jobs = JenkinsApi::Client::Job.new(client)
17
+ end
18
+
19
+ # Create a job using a rendered template
20
+ #
21
+ # @param [String] job_name the name of the new job
22
+ # @param [String] template the name of the template
23
+ # @param [Hash] parameters parameters for the template rendering
24
+ # @raise (see Autoproj::Jenkins.render_template)
25
+ def create_job(job_name, template, **parameters)
26
+ xml = Autoproj::Jenkins.render_template(template, **parameters)
27
+ jobs.create(job_name, xml)
28
+ end
29
+
30
+ # Test whether the server already has a job
31
+ #
32
+ # @param [String] job_name
33
+ def has_job?(job_name)
34
+ jobs.exists?(job_name)
35
+ end
36
+
37
+ # Read a job configuration
38
+ #
39
+ # @return [REXML::Document]
40
+ def read_job_config(job_name)
41
+ xml_config = jobs.get_config(job_name)
42
+ REXML::Document.new(xml_config)
43
+ end
44
+
45
+ # Update a job configuration
46
+ #
47
+ # @param [String] job_name
48
+ # @param [REXML::Document] xml the configuration XML document
49
+ def update_job_config(job_name, xml)
50
+ jobs.update(job_name, xml.to_s)
51
+ end
52
+
53
+ # Delete a job
54
+ #
55
+ # @param [String] job_name
56
+ def delete_job(job_name)
57
+ jobs.delete(job_name)
58
+ end
59
+
60
+ # Trigger a job
61
+ def trigger_job(job_name)
62
+ jobs.build(job_name)
63
+ end
64
+
65
+ # Update the pipeline of the given job
66
+ def update_job_pipeline(job_name, template, **parameters)
67
+ config = read_job_config(job_name)
68
+ pipeline = Autoproj::Jenkins.render_template(template, **parameters)
69
+ config.elements['//definition/script'].text = pipeline
70
+ update_job_config(job_name, config)
71
+ end
72
+
73
+ # Add a job as a downstream job of another
74
+ def add_downstream_project(upstream_job_name, downstream_job_name)
75
+ jobs.add_downstream_projects(upstream_job_name, downstream_job_name, 'success', false)
76
+ end
77
+ end
78
+ end
79
+
@@ -0,0 +1,18 @@
1
+ def upstream_jobs = [<%= upstream_jobs.each_key.map { |job_name| "'#{job_name}'" }.join(", ") %>]
2
+
3
+ // Iterate list -- NOTE: we cannot use groovy style or even modern java style iteration
4
+ for (int i = 0; i < upstream_jobs.size(); i++) {
5
+ def job = Jenkins.instance.getItem(upstream_jobs[i])
6
+ if (!job) {
7
+ error("cannot find upstream job ${upstream_jobs[i]}")
8
+ }
9
+
10
+ def result = job.getLastBuild().getResult()
11
+ if (result != Result.SUCCESS && result != Result.UNSTABLE)
12
+ {
13
+ echo "${upstream_jobs[i]} did not finish successfully, aborting this build"
14
+ currentBuild.result = 'NOT_BUILT';
15
+ return;
16
+ }
17
+ }
18
+
@@ -0,0 +1,27 @@
1
+ def fullWorkspaceDir = pwd()
2
+ env.HOME = fullWorkspaceDir
3
+ <% if autoproj_install_path %>
4
+ sh 'cp -f "<%= autoproj_install_path %>" ./autoproj_install'
5
+ <% else %>
6
+ sh 'wget -O autoproj_install https://raw.githubusercontent.com/rock-core/autoproj/master/bin/autoproj_install'
7
+ <% end %>
8
+ def gemfile = "<%= read_and_escape_file gemfile %>"
9
+ writeFile file: 'Gemfile', text: gemfile
10
+ def config = "<%= render_template('buildconf-config.yml', vcs: vcs, escape: true) %>"
11
+ writeFile file: 'seed.yml', text: config
12
+ dir('dev') {
13
+ sh "ruby ../autoproj_install --skip-stage2 --seed-config=../seed.yml --gems-path=${env.JENKINS_HOME}/cache/gems --gemfile=../Gemfile"
14
+ <%= render_template("import-#{vcs.type}.pipeline",
15
+ patch: false,
16
+ allow_unused: true,
17
+ package_dir: 'autoproj',
18
+ vcs: vcs,
19
+ credentials: vcs_credentials.for(vcs),
20
+ package_name: 'autoproj/') %>
21
+
22
+ <%= render_template('setup-git-credentials.pipeline', credentials: vcs_credentials[:git]) %>
23
+ sh ".autoproj/bin/aup autoproj/ --force-reset"
24
+ }
25
+
26
+ def autoproj = "${fullWorkspaceDir}/dev/.autoproj/bin/autoproj"
27
+ env.AUTOPROJ_CURRENT_ROOT = "${fullWorkspaceDir}/dev"
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+ gem 'autoproj', '>= 2.0.0.a'
3
+ gem 'autoproj-jenkins'
@@ -0,0 +1,12 @@
1
+ osdeps_mode: 'all'
2
+ GITORIOUS: http,http,http
3
+ GITHUB: http,http,http
4
+ separate_prefixes: true
5
+ ROCK_SELECTED_FLAVOR: master
6
+ ROCK_FLAVOR: master
7
+ ROCK_BRANCH: master
8
+ USE_OCL: false
9
+ rtt_target: gnulinux
10
+ rtt_corba_implementation: omniorb
11
+ autoproj_test_utility_default: true
12
+ <%= ::YAML.dump('manifest_source' => vcs.to_hash).gsub(/^---\s*/, '') %>
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+ gem 'autoproj', path: '/opt/autoproj'
3
+ gem 'autobuild', path: '/opt/autobuild'
4
+ gem 'autoproj-jenkins', path: '/opt/autoproj-jenkins'
@@ -0,0 +1,43 @@
1
+ node(label: 'autoproj-jenkins') {
2
+ stage 'bootstrap'
3
+ <%= render_template('bootstrap.pipeline', vcs: vcs, gemfile: gemfile, autoproj_install_path: autoproj_install_path, vcs_credentials: vcs_credentials, indent: 4) %>
4
+
5
+ dir('dev') {
6
+ def arg_packages = "<%= package_names.map { |name| "'#{name}'" }.join(" ") %>"
7
+
8
+ stage 'checkout and update packages'
9
+ sh "${autoproj} test enable"
10
+ <%= render_template('setup-git-credentials.pipeline', credentials: vcs_credentials[:git], indent: 8) %>
11
+ sh "${autoproj} update ${arg_packages} --force-reset -k"
12
+
13
+ stage 'update package jobs and trigger them'
14
+ def arg_dev = "<%= " --dev" if dev %>"
15
+ def arg_job_prefix = "<%= " '--job-prefix=#{job_prefix}'" if !job_prefix.empty? %>"
16
+ <% if vcs_credentials.empty? %>
17
+ def arg_vcs_credentials = ""
18
+ <% else %>
19
+ <% arg_vcs_credentials = vcs_credentials.credentials.flat_map do |vcs_type, vcs_c|
20
+ vcs_c.map do |c|
21
+ "#{vcs_type}:#{c.protocol}://#{c.host}"
22
+ end
23
+ end.join(" ") %>
24
+ def arg_vcs_credentials = " '--vcs-credentials=<%= arg_vcs_credentials %>'"
25
+ <% end %>
26
+
27
+ <% if credentials_id %>
28
+ def jobNames = withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: '<%= credentials_id %>',
29
+ usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
30
+ def credentials = " --username '${env.USERNAME}' --password '${env.PASSWORD}'"
31
+ sh(script: "${autoproj} jenkins update${arg_dev}${arg_job_prefix} '${env.JENKINS_URL}' ${arg_packages}${credentials}${arg_vcs_credentials}", returnStdout: true).split("\n")
32
+ }
33
+ <% else %>
34
+ def jobNames = sh(
35
+ script: "${autoproj} jenkins update${arg_dev}${arg_job_prefix} 'http://localhost:8080' ${arg_packages}${arg_vcs_credentials}",
36
+ returnStdout: true).split("\n")
37
+ <% end %>
38
+ for (job_name in jobNames) {
39
+ build job: job_name, wait: false
40
+ }
41
+ }
42
+ }
43
+
@@ -0,0 +1,24 @@
1
+ <?xml version='1.0' encoding='UTF-8'?>
2
+ <flow-definition plugin="workflow-job@2.3">
3
+ <actions/>
4
+ <description></description>
5
+ <keepDependencies>false</keepDependencies>
6
+ <properties/>
7
+ <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@2.9">
8
+ <script>
9
+ </script>
10
+ <sandbox>true</sandbox>
11
+ </definition>
12
+ <triggers/>
13
+ <quietPeriod><%= quiet_period %></quietPeriod>
14
+ <jenkins.model.BuildDiscarderProperty>
15
+ <strategy class="hudson.tasks.LogRotator">
16
+ <daysToKeep>30</daysToKeep>
17
+ <numToKeep>-1</numToKeep>
18
+ <artifactDaysToKeep>7</artifactDaysToKeep>
19
+ <artifactNumToKeep>-1</artifactNumToKeep>
20
+ </strategy>
21
+ </jenkins.model.BuildDiscarderProperty>
22
+ </flow-definition>
23
+
24
+
@@ -0,0 +1,20 @@
1
+ def downstreamDir = "artifacts/downstream"
2
+ def targetArtifactPath = "${fullWorkspaceDir}/${downstreamDir}/<%= job_name %>-prefix.zip"
3
+
4
+ dir(downstreamDir) { deleteDir() }
5
+ dir("${downstreamDir}/<%= job_name %>") {
6
+ sh "rsync '${jobPackagePrefix}/' './' -a --delete"
7
+ sh "${autoproj} jenkins relativize ./ '${fullWorkspaceDir}' '@WORKSPACE_ROOT@'"
8
+ zip zipFile: targetArtifactPath, glob: "<%= artifact_glob %>"
9
+ }
10
+ dir(downstreamDir) {
11
+ archiveArtifacts artifacts: "*.zip"
12
+ deleteDir()
13
+ }
14
+
15
+ if (triggeredByUser) { // Defined in handle-upstream.pipeline.erb
16
+ <% downstream_jobs.each_key do |job_name| %>
17
+ build job: "<%= job_name %>", wait: false
18
+ <% end %>
19
+ }
20
+
@@ -0,0 +1,2 @@
1
+ sh "${autoproj} update --force-reset '<%= package_name %>'"
2
+
@@ -0,0 +1,16 @@
1
+ dir('<%= package_dir %>') {
2
+ <% if patch %>
3
+ if (fileExists('.git')) {
4
+ sh "${autoproj} unpatch ."
5
+ }
6
+ <% end %>
7
+
8
+ <% if credentials
9
+ arg_credentials = "credentialsId: '#{credentials.jenkins_id}', "
10
+ end %>
11
+ <%= vcs.type %> <%= arg_credentials %> <%= Hash[url: vcs.url].merge(vcs.options).map { |k, v| "#{k}: '#{v}'" }.join(", ") %>
12
+ <% if patch %>
13
+ sh "${autoproj} patch ."
14
+ <% end %>
15
+ }
16
+
@@ -0,0 +1,13 @@
1
+ dir('<%= package_dir %>') {
2
+ <% raise "SVN credentials are not supported at the moment" if credentials %>
3
+ <% if patch %>
4
+ if (fileExists('.svn')) {
5
+ sh "${autoproj} unpatch ."
6
+ }
7
+ <% end %>
8
+ svn url: '<%= vcs.url %>'
9
+ <% if patch %>
10
+ sh "${autoproj} patch ."
11
+ <% end %>
12
+ }
13
+
@@ -0,0 +1,5 @@
1
+ setup_package("<%= package_name %>") do |pkg|
2
+ <% upstream_jobs.each_value do |pkg_name| %>
3
+ pkg.depends_on "<%= pkg_name %>"
4
+ <% end %>
5
+ end
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gem 'autoproj', '>= 2.0.0.a'
@@ -0,0 +1,102 @@
1
+ import java.nio.file.Paths
2
+
3
+ def jobPackageName = "<%= package_name %>"
4
+ def upstreamJobNames = [<%= upstream_jobs.each_key.map { |job_name| "'#{job_name}'" }.join(", ") %>]
5
+ def upstreamPackageNames = [<%= upstream_jobs.each_value.map { |package_name| "'#{package_name}'" }.join(", ") %>]
6
+
7
+ stage 'waiting for upstream jobs to finish'
8
+ <%= render_template('wait-upstream.pipeline') %>
9
+
10
+ node(label: 'autoproj-jenkins') {
11
+ dir('dev/install/log') { deleteDir() }
12
+
13
+ stage 'bootstrap'
14
+ <%= render_template('bootstrap.pipeline', vcs: buildconf_vcs, gemfile: gemfile, autoproj_install_path: autoproj_install_path, vcs_credentials: vcs_credentials, indent: 4) %>
15
+ stage 'install upstream artifacts'
16
+
17
+ def upstreamDir = "artifacts/upstream"
18
+ def packagePrefixes = sh(script: "${autoproj} locate --no-cache --prefix '${jobPackageName}' ${upstreamPackageNames.join(" ")}", returnStdout: true).
19
+ split("\n")
20
+
21
+ def jobPackagePrefix = packagePrefixes[0]
22
+ def upstreamPackagePrefixes = packagePrefixes.tail()
23
+
24
+ parallel(makeUpstreamArtifactImporters(
25
+ autoproj, fullWorkspaceDir, upstreamDir,
26
+ upstreamJobNames, upstreamPackagePrefixes, upstreamBuilds)
27
+ )
28
+ // We don't need the upstream artifacts anymore, clear some disk space
29
+ dir(upstreamDir) { deleteDir() }
30
+
31
+ if (fileExists("lastPrefix")) {
32
+ sh "mv lastPrefix '${jobPackagePrefix}'"
33
+ }
34
+
35
+ def jenkins_dependency_overrides = "<%= render_template 'jenkins_dependency_overrides.rb', escape: true, package_name: package_name, upstream_jobs: upstream_jobs %>"
36
+ writeFile file: 'dev/autoproj/overrides.d/99_jenkins_dependency_overrides.rb',
37
+ text: jenkins_dependency_overrides
38
+
39
+ dir('dev') {
40
+ stage 'prepare build'
41
+ <%= render_template("import-#{vcs.type}.pipeline",
42
+ patch: true,
43
+ allow_unused: true,
44
+ package_dir: package_dir,
45
+ vcs: vcs,
46
+ credentials: vcs_credentials.for(vcs),
47
+ package_name: package_name,
48
+ indent: 8) %>
49
+ sh "${autoproj} test disable '<%= package_name %>'"
50
+ sh "${autoproj} osdeps '<%= package_name %>' 'pkg-config'"
51
+
52
+ stage 'build'
53
+ try {
54
+ sh "${autoproj} build --force --deps=f '<%= package_name %>' -p1"
55
+ }
56
+ catch(err) {
57
+ archive includes: 'install/<%= package_name %>/log/<%= package_name %>-*.log'
58
+ throw(err)
59
+ }
60
+ archive includes: 'install/<%= package_name %>/log/<%= package_name %>-*.log'
61
+ }
62
+
63
+ stage 'trigger dependencies'
64
+ <%= render_template('handle-downstream.pipeline',
65
+ job_name: job_name,
66
+ artifact_glob: artifact_glob,
67
+ downstream_jobs: downstream_jobs,
68
+ indent: 4) %>
69
+
70
+ stage 'tests'
71
+ def test_timestamp_path = "${fullWorkspaceDir}/test-timestamp"
72
+ touch file: test_timestamp_path
73
+ def test_output_path = "${fullWorkspaceDir}/test"
74
+ def autoproj_test_failed = false
75
+ dir('dev')
76
+ {
77
+ try {
78
+ sh "${autoproj} test enable '<%= package_name %>'"
79
+ sh "${autoproj} osdeps '<%= package_name %>'"
80
+ sh "${autoproj} build --deps=f '<%= package_name %>' -p1"
81
+ sh "${autoproj} test -p=1 '<%= package_name %>'"
82
+ }
83
+ catch(err) { autoproj_test_failed = true }
84
+
85
+ try { sh "${autoproj} jenkins postprocess-tests --after=${test_timestamp_path} ${test_output_path} '<%= package_name %>'" }
86
+ catch(err) { autoproj_test_failed = true }
87
+ }
88
+ try { junit allowEmptyResults: true, keepLongStdio: true, testResults: "test/*.xml" }
89
+ catch(err) { autoproj_test_failed = true }
90
+
91
+ if (autoproj_test_failed)
92
+ {
93
+ currentBuild.result = 'UNSTABLE'
94
+ }
95
+
96
+ // Move the current package prefix to a separate folder, to ensure that
97
+ // other workspaces don't have access to it. It's not strictly required,
98
+ // but is a good sanity check
99
+ dir('lastPrefix') { deleteDir() }
100
+ sh "mv '${jobPackagePrefix}' lastPrefix"
101
+ }
102
+
@@ -0,0 +1,23 @@
1
+ <?xml version='1.0' encoding='UTF-8'?>
2
+ <flow-definition plugin="workflow-job@2.3">
3
+ <actions/>
4
+ <description></description>
5
+ <keepDependencies>false</keepDependencies>
6
+ <properties/>
7
+ <definition class="org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition" plugin="workflow-cps@2.9">
8
+ <script />
9
+ <sandbox>false</sandbox>
10
+ </definition>
11
+ <triggers/>
12
+ <publishers/>
13
+ <quietPeriod><%= quiet_period %></quietPeriod>
14
+ <jenkins.model.BuildDiscarderProperty>
15
+ <strategy class="hudson.tasks.LogRotator">
16
+ <daysToKeep>30</daysToKeep>
17
+ <numToKeep>-1</numToKeep>
18
+ <artifactDaysToKeep>7</artifactDaysToKeep>
19
+ <artifactNumToKeep>-1</artifactNumToKeep>
20
+ </strategy>
21
+ </jenkins.model.BuildDiscarderProperty>
22
+ </flow-definition>
23
+
@@ -0,0 +1,8 @@
1
+ <% credentials.each do |cred| %>
2
+ sh "git config --global credential.<%= cred.protocol %>://<%= cred.host %>.helper cache"
3
+ withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: '<%= cred.jenkins_id %>',
4
+ usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
5
+ def credentials = "protocol=<%= cred.protocol %>\nhost=<%= cred.host %>\nusername=${env.USERNAME}\npassword=${env.PASSWORD}\n"
6
+ sh "echo '${credentials}' | git credential approve"
7
+ }
8
+ <% end %>