puppet 2.7.25 → 2.7.26

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (77) hide show
  1. data/bin/puppet +4 -0
  2. data/ext/build_defaults.yaml +4 -4
  3. data/ext/debian/control +1 -1
  4. data/ext/packaging/Gemfile +8 -0
  5. data/ext/packaging/Gemfile.lock +28 -0
  6. data/ext/packaging/README.md +31 -4
  7. data/ext/packaging/lib/packaging.rb +21 -0
  8. data/ext/packaging/lib/packaging/config.rb +277 -0
  9. data/ext/packaging/lib/packaging/config/params.rb +175 -0
  10. data/ext/packaging/lib/packaging/tar.rb +186 -0
  11. data/ext/packaging/lib/packaging/util.rb +44 -0
  12. data/ext/packaging/lib/packaging/util/date.rb +15 -0
  13. data/ext/packaging/lib/packaging/util/file.rb +60 -0
  14. data/ext/packaging/lib/packaging/util/jira.rb +83 -0
  15. data/ext/packaging/lib/packaging/util/net.rb +16 -0
  16. data/ext/packaging/lib/packaging/util/rake_utils.rb +57 -0
  17. data/ext/packaging/lib/packaging/util/serialization.rb +19 -0
  18. data/ext/packaging/lib/packaging/util/tool.rb +30 -0
  19. data/ext/packaging/lib/packaging/util/version.rb +300 -0
  20. data/ext/packaging/packaging.rake +10 -5
  21. data/ext/packaging/spec/fixtures/config/ext/build_defaults.yaml +2 -0
  22. data/ext/packaging/spec/fixtures/config/ext/project_data.yaml +2 -0
  23. data/ext/packaging/spec/fixtures/config/params.yaml +2 -0
  24. data/ext/packaging/spec/fixtures/util/pre_tasks.yaml +4 -0
  25. data/ext/packaging/spec/lib/packaging/config_spec.rb +330 -0
  26. data/ext/packaging/spec/lib/packaging/tar_spec.rb +122 -0
  27. data/ext/packaging/spec/lib/packaging/util/file_spec.rb +48 -0
  28. data/ext/packaging/spec/lib/packaging/util/jira_spec.rb +50 -0
  29. data/ext/packaging/spec/lib/packaging/util/net_spec.rb +23 -0
  30. data/ext/packaging/spec/lib/packaging/util/rake_utils_spec.rb +70 -0
  31. data/ext/packaging/spec/lib/packaging/util/version_spec.rb +67 -0
  32. data/ext/packaging/spec/lib/packaging_spec.rb +19 -0
  33. data/ext/packaging/spec/spec_helper.rb +10 -0
  34. data/ext/packaging/spec/tasks/00_utils_spec.rb +218 -88
  35. data/ext/packaging/tasks/00_utils.rake +63 -320
  36. data/ext/packaging/tasks/30_metrics.rake +4 -4
  37. data/ext/packaging/tasks/apple.rake +28 -13
  38. data/ext/packaging/tasks/build.rake +2 -176
  39. data/ext/packaging/tasks/deb.rake +61 -20
  40. data/ext/packaging/tasks/deb_repos.rake +12 -12
  41. data/ext/packaging/tasks/doc.rake +5 -5
  42. data/ext/packaging/tasks/fetch.rake +9 -9
  43. data/ext/packaging/tasks/gem.rake +59 -33
  44. data/ext/packaging/tasks/ips.rake +22 -23
  45. data/ext/packaging/tasks/jenkins.rake +34 -34
  46. data/ext/packaging/tasks/jenkins_dynamic.rake +22 -19
  47. data/ext/packaging/tasks/load_extras.rake +21 -0
  48. data/ext/packaging/tasks/mock.rake +16 -16
  49. data/ext/packaging/tasks/pe_deb.rake +2 -2
  50. data/ext/packaging/tasks/pe_remote.rake +9 -9
  51. data/ext/packaging/tasks/pe_rpm.rake +1 -1
  52. data/ext/packaging/tasks/pe_ship.rake +48 -37
  53. data/ext/packaging/tasks/pe_sign.rake +5 -5
  54. data/ext/packaging/tasks/release.rake +5 -5
  55. data/ext/packaging/tasks/remote_build.rake +27 -27
  56. data/ext/packaging/tasks/retrieve.rake +5 -5
  57. data/ext/packaging/tasks/rpm.rake +27 -10
  58. data/ext/packaging/tasks/rpm_repos.rake +13 -12
  59. data/ext/packaging/tasks/ship.rake +67 -45
  60. data/ext/packaging/tasks/sign.rake +37 -30
  61. data/ext/packaging/tasks/tar.rake +14 -69
  62. data/ext/packaging/tasks/tickets.rake +449 -0
  63. data/ext/packaging/tasks/update.rake +2 -2
  64. data/ext/packaging/tasks/vendor_gems.rake +2 -2
  65. data/ext/packaging/tasks/version.rake +8 -38
  66. data/ext/packaging/tasks/z_data_dump.rake +35 -3
  67. data/ext/packaging/templates/downstream.xml.erb +2 -2
  68. data/ext/packaging/templates/packaging.xml.erb +13 -13
  69. data/ext/packaging/templates/repo.xml.erb +9 -7
  70. data/lib/puppet/indirector/facts/facter.rb +1 -1
  71. data/lib/puppet/version.rb +1 -1
  72. data/spec/unit/indirector/facts/facter_spec.rb +2 -2
  73. metadata +38 -13
  74. data/ext/packaging/spec/tasks/build_object_spec.rb +0 -178
  75. data/ext/packaging/tasks/10_setupvars.rake +0 -135
  76. data/ext/packaging/tasks/20_setupextravars.rake +0 -53
  77. data/ext/packaging/tasks/template.rake +0 -27
@@ -4,7 +4,7 @@ def sign_rpm(rpm, sign_flags = nil)
4
4
  # rpm signing, we have to be able to tell the packaging repo what binary to
5
5
  # use as the rpm signing tool.
6
6
  #
7
- rpm_cmd = ENV['RPM'] || find_tool('rpm')
7
+ rpm_cmd = ENV['RPM'] || Pkg::Util::Tool.find_tool('rpm')
8
8
 
9
9
  # If we're using the gpg agent for rpm signing, we don't want to specify the
10
10
  # input for the passphrase, which is what '--passphrase-fd 3' does. However,
@@ -12,7 +12,7 @@ def sign_rpm(rpm, sign_flags = nil)
12
12
  # defaults on modern rpm. The fun part of gpg-agent signing of rpms is
13
13
  # specifying that the gpg check command always return true
14
14
  #
15
- if boolean_value(ENV['RPM_GPG_AGENT'])
15
+ if Pkg::Util.boolean_value(ENV['RPM_GPG_AGENT'])
16
16
  gpg_check_cmd = "--define '%__gpg_check_password_cmd /bin/true'"
17
17
  else
18
18
  input_flag = "--passphrase-fd 3"
@@ -24,7 +24,7 @@ def sign_rpm(rpm, sign_flags = nil)
24
24
  # accept extra flags to override certain signing behavior for older
25
25
  # versions of rpm, e.g. specifying V3 signatures instead of V4.
26
26
  #
27
- sh "#{rpm_cmd} #{gpg_check_cmd} --define '%_gpg_name #{@build.gpg_name}' --define '%__gpg_sign_cmd %{__gpg} gpg #{sign_flags} #{input_flag} --batch --no-verbose --no-armor --no-secmem-warning -u %{_gpg_name} -sbo %{__signature_filename} %{__plaintext_filename}' --addsign #{rpm}"
27
+ sh "#{rpm_cmd} #{gpg_check_cmd} --define '%_gpg_name #{Pkg::Config.gpg_name}' --define '%__gpg_sign_cmd %{__gpg} gpg #{sign_flags} #{input_flag} --batch --no-verbose --no-armor --no-secmem-warning -u %{_gpg_name} -sbo %{__signature_filename} %{__plaintext_filename}' --addsign #{rpm}"
28
28
  end
29
29
 
30
30
  end
@@ -34,14 +34,14 @@ def sign_legacy_rpm(rpm)
34
34
  end
35
35
 
36
36
  def rpm_has_sig(rpm)
37
- %x{rpm -Kv #{rpm} | grep "#{@build.gpg_key.downcase}" &> /dev/null}
37
+ %x{rpm -Kv #{rpm} | grep "#{Pkg::Config.gpg_key.downcase}" &> /dev/null}
38
38
  $?.success?
39
39
  end
40
40
 
41
41
  def sign_deb_changes(file)
42
42
  # Lazy lazy lazy lazy lazy
43
43
  sign_program = "-p'gpg --use-agent --no-tty'" if ENV['RPM_GPG_AGENT']
44
- sh "debsign #{sign_program} --re-sign -k#{@build.gpg_key} #{file}"
44
+ sh "debsign #{sign_program} --re-sign -k#{Pkg::Config.gpg_key} #{file}"
45
45
  end
46
46
 
47
47
  # requires atleast a self signed prvate key and certificate pair
@@ -50,15 +50,15 @@ end
50
50
  # technically this can be any ips-compliant package identifier, e.g. application/facter
51
51
  # repo_uri is the path to the repo currently containing the package
52
52
  def sign_ips(fmri, repo_uri)
53
- %x{pkgsign -s #{repo_uri} -k #{@build.privatekey_pem} -c #{@build.certificate_pem} -i #{@build.ips_inter_cert} #{fmri}}
53
+ %x{pkgsign -s #{repo_uri} -k #{Pkg::Config.privatekey_pem} -c #{Pkg::Config.certificate_pem} -i #{Pkg::Config.ips_inter_cert} #{fmri}}
54
54
  end
55
55
 
56
56
  namespace :pl do
57
57
  desc "Sign the tarball, defaults to PL key, pass GPG_KEY to override or edit build_defaults"
58
58
  task :sign_tar do
59
- File.exist?("pkg/#{@build.project}-#{@build.version}.tar.gz") or fail "No tarball exists. Try rake package:tar?"
60
- load_keychain if has_tool('keychain')
61
- gpg_sign_file "pkg/#{@build.project}-#{@build.version}.tar.gz"
59
+ File.exist?("pkg/#{Pkg::Config.project}-#{Pkg::Config.version}.tar.gz") or fail "No tarball exists. Try rake package:tar?"
60
+ load_keychain if Pkg::Util::Tool.find_tool('keychain', :required => false)
61
+ gpg_sign_file "pkg/#{Pkg::Config.project}-#{Pkg::Config.version}.tar.gz"
62
62
  end
63
63
 
64
64
  desc "Sign mocked rpms, Defaults to PL Key, pass KEY to override"
@@ -66,21 +66,28 @@ namespace :pl do
66
66
  # Find x86_64 noarch rpms that have been created as hard links and remove them
67
67
  rm_r Dir["pkg/*/*/*/x86_64/*.noarch.rpm"]
68
68
  # We'll sign the remaining noarch
69
- el5_rpms = Dir["pkg/el/5/**/*.rpm"].join(' ')
70
- modern_rpms = (Dir["pkg/el/6/**/*.rpm"] + Dir["pkg/fedora/**/*.rpm"]).join(' ')
71
- unless el5_rpms.empty?
72
- puts "Signing el5 rpms..."
73
- sign_legacy_rpm(el5_rpms)
69
+ all_rpms = Dir["pkg/**/*.rpm"]
70
+ old_rpms = Dir["pkg/el/4/**/*.rpm"] + Dir["pkg/el/5/**/*.rpm"]
71
+ modern_rpms = Dir["pkg/el/6/**/*.rpm"] + Dir["pkg/el/7/**/*.rpm"] + Dir["pkg/fedora/**/*.rpm"]
72
+
73
+ unsigned_rpms = all_rpms - old_rpms - modern_rpms
74
+ unless unsigned_rpms.empty?
75
+ fail "#{unsigned_rpms} are not signed. Please update the automation in the signing task"
76
+ end
77
+
78
+ unless old_rpms.empty?
79
+ puts "Signing old rpms..."
80
+ sign_legacy_rpm(old_rpms.join(' '))
74
81
  end
75
82
 
76
83
  unless modern_rpms.empty?
77
- puts "Signing el6 and fedora rpms..."
78
- sign_rpm(modern_rpms)
84
+ puts "Signing modern rpms..."
85
+ sign_rpm(modern_rpms.join(' '))
79
86
  end
80
87
  # Now we hardlink them back in
81
88
  Dir["pkg/*/*/*/i386/*.noarch.rpm"].each do |rpm|
82
89
  cd File.dirname(rpm) do
83
- ln File.basename(rpm), File.join("..","x86_64"), :force => true
90
+ FileUtils.ln(File.basename(rpm), File.join("..","x86_64"), :force => true, :verbose => true)
84
91
  end
85
92
  end
86
93
  end
@@ -91,12 +98,12 @@ namespace :pl do
91
98
  fmri = args.fmri
92
99
  puts "Signing ips packages..."
93
100
  sign_ips(fmri, repo_uri)
94
- end if @build.build_ips
101
+ end if Pkg::Config.build_ips
95
102
 
96
103
  desc "Check if all rpms are signed"
97
104
  task :check_rpm_sigs do
98
105
  signed = TRUE
99
- rpms = Dir["pkg/el/5/**/*.rpm"] + Dir["pkg/el/6/**/*.rpm"] + Dir["pkg/fedora/**/*.rpm"]
106
+ rpms = Dir["pkg/**/*.rpm"]
100
107
  print 'Checking rpm signatures'
101
108
  rpms.each do |rpm|
102
109
  if rpm_has_sig rpm
@@ -113,7 +120,7 @@ namespace :pl do
113
120
  desc "Sign generated debian changes files. Defaults to PL Key, pass KEY to override"
114
121
  task :sign_deb_changes do
115
122
  begin
116
- load_keychain if has_tool('keychain')
123
+ load_keychain if Pkg::Util::Tool.find_tool('keychain')
117
124
  sign_deb_changes("pkg/deb/*/*.changes") unless Dir["pkg/deb/*/*.changes"].empty?
118
125
  sign_deb_changes("pkg/deb/*.changes") unless Dir["pkg/deb/*.changes"].empty?
119
126
  ensure
@@ -126,7 +133,7 @@ namespace :pl do
126
133
  # server, ships our packages out to it, signs them, and brings them back.
127
134
  #
128
135
  namespace :jenkins do
129
- desc "Sign all locally staged packages on #{@build.distribution_server}"
136
+ desc "Sign all locally staged packages on #{Pkg::Config.distribution_server}"
130
137
  task :sign_all => "pl:fetch" do
131
138
  Dir["pkg/*"].empty? and fail "There were files found in pkg/. Maybe you wanted to build/retrieve something first?"
132
139
 
@@ -140,16 +147,16 @@ namespace :pl do
140
147
  # containing a git bundle to be used as the environment for the packaging
141
148
  # repo in a signing operation.
142
149
  signing_bundle = ENV['SIGNING_BUNDLE']
143
- rpm_sign_task = @build.build_pe ? "pe:sign_rpms" : "pl:sign_rpms"
144
- deb_sign_task = @build.build_pe ? "pe:sign_deb_changes" : "pl:sign_deb_changes"
150
+ rpm_sign_task = Pkg::Config.build_pe ? "pe:sign_rpms" : "pl:sign_rpms"
151
+ deb_sign_task = Pkg::Config.build_pe ? "pe:sign_deb_changes" : "pl:sign_deb_changes"
145
152
  sign_tasks = ["pl:sign_tar", rpm_sign_task, deb_sign_task]
146
- remote_repo = remote_bootstrap(@build.distribution_server, 'HEAD', nil, signing_bundle)
147
- build_params = remote_buildparams(@build.distribution_server, @build)
148
- rsync_to('pkg', @build.distribution_server, remote_repo)
149
- remote_ssh_cmd(@build.distribution_server, "cd #{remote_repo} ; rake #{sign_tasks.join(' ')} PARAMS_FILE=#{build_params}")
150
- rsync_from("#{remote_repo}/pkg/", @build.distribution_server, "pkg/")
151
- remote_ssh_cmd(@build.distribution_server, "rm -rf #{remote_repo}")
152
- remote_ssh_cmd(@build.distribution_server, "rm #{build_params}")
153
+ remote_repo = remote_bootstrap(Pkg::Config.distribution_server, 'HEAD', nil, signing_bundle)
154
+ build_params = remote_buildparams(Pkg::Config.distribution_server, Pkg::Config)
155
+ rsync_to('pkg', Pkg::Config.distribution_server, remote_repo)
156
+ remote_ssh_cmd(Pkg::Config.distribution_server, "cd #{remote_repo} ; rake #{sign_tasks.join(' ')} PARAMS_FILE=#{build_params}")
157
+ rsync_from("#{remote_repo}/pkg/", Pkg::Config.distribution_server, "pkg/")
158
+ remote_ssh_cmd(Pkg::Config.distribution_server, "rm -rf #{remote_repo}")
159
+ remote_ssh_cmd(Pkg::Config.distribution_server, "rm #{build_params}")
153
160
  puts "Signed packages staged in 'pkg/ directory"
154
161
  end
155
162
  end
@@ -2,84 +2,29 @@ namespace :package do
2
2
  desc "Create a source tar archive"
3
3
  task :tar => [ :clean ] do
4
4
 
5
- if @build.pre_tar_task
6
- invoke_task(@build.pre_tar_task)
5
+ if Pkg::Config.pre_tar_task
6
+ invoke_task(Pkg::Config.pre_tar_task)
7
7
  end
8
8
 
9
- Rake::Task["package:doc"].invoke if @build.build_doc
10
- tar = ENV['TAR'] || 'tar'
11
- workdir = "pkg/#{@build.project}-#{@build.version}"
12
- mkdir_p(workdir)
9
+ Rake::Task["package:doc"].invoke if Pkg::Config.build_doc
13
10
 
14
- # The list of files to install in the tarball
15
- install = FileList.new
11
+ tar = Pkg::Tar.new
16
12
 
17
- # It is nice to use arrays in YAML to represent array content, but we used
18
- # to support a mode where a space-separated string was used. Support both
19
- # to allow a gentle migration to a modern style...
20
- patterns =
21
- case @build.files
22
- when String
23
- STDERR.puts "warning: `files` should be an array, not a string"
24
- @build.files.split(' ')
25
-
26
- when Array
27
- @build.files
28
-
29
- else
30
- raise "`files` must be a string or an array!"
31
- end
32
-
33
- # We need to add our list of file patterns from the configuration; this
34
- # used to be a list of "things to copy recursively", which would install
35
- # editor backup files and other nasty things.
13
+ # If the user has specified templates via config file, they will be ack'd
14
+ # by the tar class. Otherwise, we load what we consider to be the "default"
15
+ # set, which is default for historical purposes.
36
16
  #
37
- # This handles that case correctly, with a deprecation warning, to augment
38
- # our FileList with the right things to put in place.
39
- #
40
- # Eventually, when all our projects are migrated to the new standard, we
41
- # can drop this in favour of just pushing the patterns directly into the
42
- # FileList and eliminate many lines of code and comment.
43
- patterns.each do |pattern|
44
- if File.directory?(pattern) and not Dir[pattern + "/**/*"].empty?
45
- install.add(pattern + "/**/*")
46
- else
47
- install.add(pattern)
48
- end
49
- end
17
+ tar.templates ||= Dir[File.join(Pkg::Config.project_root, "ext", "**", "*.erb")].select { |i| i !~ /ext\/packaging|ext\/osx/ }
50
18
 
51
- # Transfer all the files and symlinks into the working directory...
52
- install = install.select { |x| File.file?(x) or File.symlink?(x) or empty_dir?(x) }
53
19
 
54
- install.each do |file|
55
- if empty_dir?(file)
56
- mkpath(File.join(workdir,file), :verbose => false)
57
- else
58
- mkpath(File.dirname( File.join(workdir, file) ), :verbose => false)
59
- cp_p(file, File.join(workdir, file), :verbose => false)
60
- end
61
- end
62
-
63
- tar_excludes = @build.tar_excludes.nil? ? [] : @build.tar_excludes.split(' ')
64
- tar_excludes << "ext/#{@build.packaging_repo}"
65
- Rake::Task["package:template"].invoke(workdir)
66
-
67
- # This is to support packages that only burn-in the version number in the
68
- # release artifact, rather than storing it two (or more) times in the
69
- # version control system. Razor is a good example of that; see
70
- # https://github.com/puppetlabs/Razor/blob/master/lib/project_razor/version.rb
71
- # for an example of that this looks like.
20
+ # If the user has specified things to exclude via config file, they will be
21
+ # honored by the tar class, but we also always exclude the packaging repo.
72
22
  #
73
- # If you set this the version will only be modified in the temporary copy,
74
- # with the intent that it never change the official source tree.
75
- Rake::Task["package:versionbump"].invoke(workdir) if @build.update_version_file
23
+ tar.excludes << "ext/packaging"
76
24
 
77
- cd "pkg" do
78
- sh "#{tar} --exclude #{tar_excludes.join(" --exclude ")} -zcf '#{@build.project}-#{@build.version}.tar.gz' #{@build.project}-#{@build.version}"
79
- end
80
- rm_rf(workdir)
81
- puts
82
- puts "Wrote #{`pwd`.strip}/pkg/#{@build.project}-#{@build.version}.tar.gz"
25
+ tar.pkg!
26
+
27
+ puts "Wrote #{`pwd`.strip}/pkg/#{Pkg::Config.project}-#{Pkg::Config.version}.tar.gz"
83
28
  end
84
29
  end
85
30
 
@@ -0,0 +1,449 @@
1
+ # This rake task creates tickets in jira for a release.
2
+ #
3
+
4
+ def get_password(site, user)
5
+ require 'io/console'
6
+ puts "Logging in to #{site} as #{user}"
7
+ print "Password please: "
8
+ password = STDIN.noecho(&:gets).chomp
9
+ puts "\nOkay trying to log in to #{site} as #{user} ..."
10
+ password
11
+ end
12
+
13
+ def get_vars
14
+ vars = {}
15
+
16
+ # roles
17
+ vars[:builder] = Pkg::Util.get_var("BUILDER")
18
+ vars[:developer] = Pkg::Util.get_var("DEVELOPER")
19
+ vars[:writer] = Pkg::Util.get_var("WRITER")
20
+
21
+ # project and release
22
+ vars[:release] = Pkg::Util.get_var("RELEASE")
23
+ vars[:project] = Pkg::Util.get_var("PROJECT")
24
+ vars[:date] = Pkg::Util.get_var("DATE")
25
+
26
+ # Jira authentication - do this after validating other params, so user doesn't need to
27
+ # enter password only to find out they typo'd one of the above
28
+ vars[:site] = 'https://tickets.puppetlabs.com'
29
+ vars[:username] = Pkg::Util.get_var("JIRA_USER")
30
+ vars[:password] = get_password(vars[:site], vars[:username])
31
+
32
+ vars
33
+ end
34
+
35
+ def validate_vars(jira, vars)
36
+ jira.project?(vars[:project])
37
+ jira.user? (vars[:builder])
38
+ jira.user? (vars[:writer])
39
+ jira.user? (vars[:developer])
40
+ end
41
+
42
+ def create_tickets(jira, vars)
43
+ description = {}
44
+ description[:code_ready] = <<-DOC
45
+ All tests (spec, acceptance) should be passing on all platforms for both stable & master.
46
+
47
+ * If a new platform has been added, make sure that platform has acceptance testing, new features have decent coverage, etc. etc.
48
+ * If the release is going to be cut from a sha, rather than the head of a branch, make sure that sha specifically has gone through spec/acceptance/etc. tests
49
+ * Move all items that should be moved from Ready for CI to Ready for Review
50
+
51
+ Have all tickets been resolved (passed Functional Review)? If not please add any missing tickets to the current sprint's board.
52
+
53
+ NOTE: This link may not work properly for RC releases. Edit it to remove the "-rc#".
54
+ https://tickets.puppetlabs.com/issues/?jql=project%20%3D%20#{vars[:project]}%20AND%20resolution%20%3D%20Unresolved%20AND%20fixVersion%20%3D%20%22#{vars[:release]}%22
55
+ DOC
56
+
57
+ description[:jira_tickets_for_commit] = <<-DOC
58
+ Ensure all tickets referenced in the commit log have a bug targeted at the release
59
+
60
+ * git log <old tag>..<new tag>
61
+ * look through, and make sure that if there is a JIRA ticket number referenced in any of the commits, that ticket is targeted at the release
62
+ * Also, make sure the code itself is sane, that you understand why the change was made, etc. etc.
63
+ * [ticketmatch.rb script|https://gist.github.com/hlindberg/9520023] is a ruby script that helps with "Is there a JIRA ticket targeted at the release for every commit?" and "Is there a commit for every JIRA ticket targeted at the release?" (it beats doing it manually, but requires manual steps and hacking the script for the specific release)
64
+ DOC
65
+
66
+ description[:git_commits_for_tickets] = <<-DOC
67
+ Ensure all tickets targeted at the release have a corresponding commit
68
+ * git log <old tag>..<new tag>
69
+ * This time, look through tickets targeted at this release in JIRA, and compare it to the commit log, looking for the corresponding numbers
70
+ * [ticketmatch.rb script|https://gist.github.com/hlindberg/9520023] is a ruby script that helps with "Is there a JIRA ticket targeted at the release for every commit?" and "Is there a commit for every JIRA ticket targeted at the release?" (it beats doing it manually, but requires manual steps and hacking the script for the specific release)
71
+ DOC
72
+
73
+ description[:update_version_source] = <<-DOC
74
+ Bump VERSION in lib/{#project}/version.rb to correct version.
75
+
76
+ * Commit the updated version file.
77
+ * e.g) commit -m "(packaging) Update FACTERVERSION to 1.7.3-rc1".
78
+ * If any merging needs to happen (i.e. master into stable/stable into master), it can now happen (different subtask).
79
+ * Once this is done, hand the SHA to be built to RelEng to be tagged.
80
+
81
+ Dependencies:
82
+ * Is the code ready for release?
83
+ * Is there a commit for every JIRA ticket targeted at the release?
84
+ DOC
85
+
86
+ description[:merge_to_stable] = <<-DOC
87
+ For some releases, the code base will need to be merged down to stable.
88
+
89
+ *NOTE:* This is usually only during a x.y.0-rc1 release, but even then it may have already been done. If it doesn't apply, close this ticket.
90
+
91
+
92
+ Assuming you have origin (your remote) and upstream (puppetlabs remote), the commands will look something like this:
93
+ {noformat}
94
+ git fetch upstream
95
+ git rebase upstream/master
96
+
97
+ git checkout stable
98
+ git rebase upstream/stable
99
+
100
+ git merge master --no-ff --log
101
+ {noformat}
102
+
103
+ Once that looks good:
104
+ {noformat}
105
+ git push origin
106
+ git push upstream
107
+ {noformat}
108
+
109
+ After merging to stable, the jobs on jenkins may require updates (spec, acceptance, etc) when you merge master into stable. Please ensure that the jenkins jobs are updated if necessary.
110
+
111
+ Dependencies:
112
+ * Is the code ready for release?
113
+ * Is there a commit for every JIRA ticket targeted at the release?
114
+ * Update version number in source
115
+ DOC
116
+
117
+ description[:jira_maintenance] = <<-DOC
118
+ This happens on Jira - we need to clean up the current release and prepare for the next release.
119
+ * Mark the version that's going out as "Released" in the Project Admin -> Versions panel.
120
+ * Create a version we can target future issues or issues that didn't make it into the current release. (e.g. if we're releasing Facter 1.7.4, make sure there's a 1.7.5 version (or at least 1.7.x if there's isn't another bug release planned for the near future)
121
+ * Create a public pair of queries for inclusion in the release notes/announcement. These allow easy tracking as new bugs come in for a particular version and allow everyone to see the list of changes slated for the next release (Paste their URLs into the "Release story" ticket):
122
+ - 'project = XX AND affectedVersion = 'X.Y.Y', Save as "Introduced in X.Y.Y", click Details, add permission for Everyone
123
+ - 'project = XX AND fixVersion = 'X.Y.Z', Save as "Fixes for X.Y.Z", click Details, add permission for Everyone
124
+ DOC
125
+
126
+ description[:release_notes] = <<-DOC
127
+ Collaborating with product for release story
128
+
129
+ Dependencies:
130
+ * Is there a JIRA ticket targeted at the release for every commit?
131
+ * Is there a commit for every JIRA ticket targeted at the release?
132
+ DOC
133
+
134
+ description[:tag_package] = <<-DOC
135
+ Tag and create packages
136
+
137
+ * Developer provides the SHA - [~#{vars[:developer]}] - Please add the SHA as a comment (this should be the commit which contains the newly updated version.rb)
138
+ * checkout the sha
139
+ * NOTE: If this is a final release, make sure you're releasing only the code that already went through rc, so don't let any new code get into the final release
140
+ * Make sure you are about to tag the correct thing
141
+ * Create the tag e.g.) git tag -s -u {GPG key} -m "1.7.3-rc1" 1.7.3-rc1
142
+ * You need to know the pass phrase for this to complete successfully. It's important that we make sure all releases are signed to verify authenticity.
143
+ * DO NOT push the tag to the repo, keep it local only
144
+ * `git describe` will show you the tag. Make sure you're building what you think you're building.
145
+ * Make sure you look over the code that has changed since the previous release so we know what's going out the door.
146
+ * run `rake package:implode package:bootstrap pl:jenkins:uber_build` when you've verified what version you're building (this uses the latest version of the packaging repo to build the packages).
147
+ * If this is a puppet release, you have to build the windows msi. This is done using jenkins jobs on jenkins-legacy. You have to make sure you're targeting the correct versions of hiera, facter and puppet.
148
+ * [~#{vars[:builder]}] please add a comment with location of packages.
149
+
150
+ For puppet, don't forget the msi packages. This usually comes after other smoke testing is going well since it does require the tag to be pushed live.
151
+
152
+ Dependencies:
153
+ * Every ticket before this except for release notes.
154
+ DOC
155
+
156
+ description[:smoke_test] = <<-DOC
157
+ Procedure may vary by project and point in the release cycle. Ask around.
158
+
159
+ In general this should happen on a variety of platforms, i.e. one or two each of kind of package we create (i.e., gem, dmg, msi, deb, rpm, etc).
160
+ If this is a final release then the previous RC (which should be identical to what is currently being released) will have gone through this testing. Lighter testing is acceptable.
161
+
162
+ * Add a link to the Packages repository that you receive from the "Tag and create packages" subtask
163
+ * Ping folks on your team for help with different platforms.
164
+ * When you pick up a platform, please leave a comment below that you are testing it. When it looks good, leave another comment, preferably with a code snippet showing the commands executed and their output.
165
+ * If your smoke testing includes MSIs, you will generally test on other platforms first and when that is looking good, ping the Release Engineer that built the other packages to move forward with MSIs (they require tags to be pushed). This ticket doesn't close until all chosen platforms (including MSIs) have been tested.
166
+ * When all platforms picked have been smoke tested, move this ticket to done.
167
+
168
+ IMPORTANT: Please edit the description of this ticket and remove "Example:" below. Edit the platforms to smoke test on, and the smoke test procedure.
169
+
170
+ Example:
171
+ Smoke test platforms:
172
+ * pick some platforms such as
173
+ * RHEL 5/6/7
174
+ * CentOS 5/6
175
+ * Windows 2003/2008/2012
176
+ * Debian 6/7/
177
+ * Ubuntu 10.04/12.04/14.04
178
+
179
+ Smoke test procedure:
180
+ * Start/stop/restart a master with the init scripts (on Debian try the passenger master)
181
+ * Start/stop/restart an agent
182
+ * Help/man
183
+ * Write and run some manifests
184
+
185
+ Dependencies:
186
+ * Tag and create packages
187
+ * For Windows MSIs - Push tag
188
+ DOC
189
+
190
+ description[:go_no_go] = <<-DOC
191
+ Get a yes/no for the release from dev, docs, product, qa, releng.
192
+
193
+ This meeting is informal, over chat, and usually happens right before packages are pushed.
194
+ Keep in mind we typically do not ship releases in the evening and we don't ship on Friday if the release is a final release.
195
+
196
+ Dependencies:
197
+ * Smoke testing
198
+ DOC
199
+
200
+ description[:push_tag] = <<-DOC
201
+ The development team is responsible for updating the stable/master branches as necessary.
202
+ This will be done after the version bump in version.rb.
203
+
204
+ Dependencies:
205
+ * Go / No Go meeting (except where it's required to push the tag to build packages - MSIs)
206
+ DOC
207
+
208
+ description[:push_packages] = <<-DOC
209
+ Push packages
210
+ * run `rake pl:jenkins:uber_ship`
211
+ * You will need the keys to the castle (aka the passphrase) for this to work.
212
+ * Don't forget to make sure everything looks like it's in the correct folder, the pkgs dir has been cleared out, and that you are shipping for all expected platforms.
213
+ * Get a *second set of RelEng eyes* on the packages that are about to be shipped to make sure everything looks a-okay.
214
+ * If you're shipping a gem you need to make sure you have a rubygems account, are an owner of that project, and have a gem config file.
215
+ * If you're shipping puppet you need to sign the MSI file for Windows. This is a manual process and the ship task doesn't ship or build the msi so talk to Moses or [~matthaus] for more details. This file also needs to be manually signed.
216
+
217
+ Dependencies:
218
+ * Go / No Go meeting (Status - Ship it!)
219
+ DOC
220
+
221
+ description[:update_downloads] = <<-DOC
222
+ Update downloads page
223
+ * Update misc/download-options to reflect the new builds you just pushed and also make sure they're displayed. It's a good idea to make sure this looks like it's supposed to
224
+
225
+ NOTE: this page will hopefully be deprecated soon. The idea is that docs with update their documentation to include "latest release version" and where to download files. This page will then be changed to redirect to docs.puppetlabs.com and will no longer need updating.
226
+
227
+ Dependencies:
228
+ * Go / No Go meeting (Status - Ship it!)
229
+ DOC
230
+
231
+ description[:push_docs] = <<-DOC
232
+ Push the documentation updates to docs.puppetlabs.com.
233
+
234
+ Dependencies:
235
+ * Go / No Go meeting (Status - Ship it!)
236
+ DOC
237
+
238
+ description[:send_announcements] = <<-DOC
239
+ * Update the release google document (ask around for location).
240
+ * Send the drafted release notes email.
241
+ * If final send to puppet-announce and specific distribution lists (e.g. puppet to puppet-users & puppet-dev).
242
+ * If RC only send to the specific distribution lists.
243
+ * Make a PSA on IRC letting those kiddos know about the new release.
244
+ * Something along the lines of "PSA: facter 1.7.3-rc1 now available"
245
+
246
+ Dependencies:
247
+ * Prepare long form release notes and short form release story
248
+ * Packages pushed
249
+ DOC
250
+
251
+ description[:update_dujour] = <<-DOC
252
+ Update dujour to notify users to use #{vars[:release]}.
253
+
254
+ Dependencies:
255
+ * Packages pushed
256
+ DOC
257
+
258
+ description[:close_tickets] = <<-DOC
259
+ Close any tickets that have been resolved for the release.
260
+
261
+ NOTE: This link may not work properly for RC releases. Edit it to remove the "-rc#".
262
+ https://tickets.puppetlabs.com/issues/?jql=project%20%3D%20#{vars[:project]}%20AND%20resolution%20%3D%20Fixed%20AND%20fixVersion%20%3D%20%22#{vars[:release]}%22%20AND%20status%20%3D%20Resolved
263
+
264
+ There is a bulk edit at the top (a gear with the word "Tools"). Should you decide to take this route:
265
+ * Select Bulk Change - All # issues
266
+ * Step 1 - choose all relevant issues (likely all of them)
267
+ * Step 2 - Select "Transition Issues"
268
+ * Step 3 - Select "Closed"
269
+ * Step 4 - Select "Fixed" in Change Resolution.
270
+ * View what is about to change and confirm it. Then commit the change.
271
+
272
+ Dependencies:
273
+ * Packages pushed
274
+ DOC
275
+
276
+ # The subtickets to create for the individual tasks
277
+ subtickets =
278
+ [
279
+ {
280
+ :summary => 'Is the code ready for release?',
281
+ :description => description[:code_ready],
282
+ :assignee => vars[:developer]
283
+ },
284
+ {
285
+ :summary => 'Is there a JIRA ticket targeted at the release for every commit?',
286
+ :description => description[:jira_tickets_for_commit],
287
+ :assignee => vars[:developer]
288
+ },
289
+ {
290
+ :summary => 'Is there a commit for every JIRA ticket targeted at the release?',
291
+ :description => description[:git_commits_for_tickets],
292
+ :assignee => vars[:developer]
293
+ },
294
+ {
295
+ :summary => 'Update version number in source',
296
+ :description => description[:update_version_source],
297
+ :assignee => vars[:developer]
298
+ },
299
+ {
300
+ :summary => 'Merge master into stable',
301
+ :description => description[:merge_to_stable],
302
+ :assignee => vars[:developer]
303
+ },
304
+ {
305
+ :summary => 'Is the Jira tidy-up done for this release and prepared for the next one?',
306
+ :description => description[:jira_maintenance],
307
+ :assignee => vars[:developer]
308
+ },
309
+ {
310
+ :summary => 'Prepare long form release notes and short form release story',
311
+ :description => description[:release_notes],
312
+ :assignee => vars[:writer]
313
+ },
314
+ {
315
+ :summary => 'Tag the release and create packages',
316
+ :description => description[:tag_package],
317
+ :assignee => vars[:builder]
318
+ },
319
+ {
320
+ :summary => 'Smoke test packages',
321
+ :description => description[:smoke_test],
322
+ :assignee => vars[:developer]
323
+ },
324
+ {
325
+ :summary => 'Go/no-go meeting',
326
+ :description => description[:go_no_go],
327
+ :assignee => vars[:developer]
328
+ },
329
+ {
330
+ :summary => 'Push tag',
331
+ :description => description[:push_tag],
332
+ :assignee => vars[:builder]
333
+ },
334
+ {
335
+ :summary => 'Packages pushed',
336
+ :description => description[:push_packages],
337
+ :assignee => vars[:builder]
338
+ },
339
+ {
340
+ :summary => 'Update the downloads page',
341
+ :description => description[:update_downloads],
342
+ :assignee => vars[:builder]
343
+ },
344
+ {
345
+ :summary => 'Docs pushed',
346
+ :description => description[:push_docs],
347
+ :assignee => vars[:writer]
348
+ },
349
+ {
350
+ :summary => 'Send out announcements',
351
+ :description => description[:send_announcements],
352
+ :assignee => 'eric.sorenson'
353
+ },
354
+ {
355
+ :projects => ['PDB'], # Only PDB has this step
356
+ :summary => 'Update dujour to notify users to use #{vars[:release]}',
357
+ :description => description[:update_dujour],
358
+ :assignee => vars[:developer]
359
+ },
360
+ {
361
+ :summary => 'Close all resolved tickets in Jira',
362
+ :description => description[:close_tickets],
363
+ :assignee => vars[:developer]
364
+ },
365
+ ]
366
+
367
+ # Use the human-friendly project name in the summary
368
+ project_name = jira.project_name(vars[:project])
369
+ summary = "#{project_name} #{vars[:release]} #{vars[:date]} Release"
370
+ description[:top_level_ticket] = <<-DOC
371
+ #{summary}
372
+
373
+ When working through this ticket, add it to the board and then keep it in the Ready for Engineering column.
374
+ Move the subtasks to In Progress when you are working on them and Resolved when you have completed them.
375
+ In general subtasks should only be moved to Ready for Engineering when they are ready to be worked on. For some assignees this is their cue to start working on release-related items.
376
+
377
+ * The first set of tickets are assigned to the developer, those can all be converted to Ready for Engineering and you can start working through them.
378
+ * Only when those are done should you move the "Prepare notes" and "Tag release/create packages" tasks to Ready for Engineering. Ping those assigned to move forward.
379
+ * When you hear back for "Tag Release/create packages", you should move "Smoke test packages" to Ready for Engineering or In Progress if you are ready.
380
+ DOC
381
+
382
+ # Values for the main ticket
383
+ # Note: use the 're' user for the main ticket to get notifications
384
+ # to the Release Engineering team
385
+ project = vars[:project]
386
+ assignee = 're'
387
+
388
+ # Create the main ticket
389
+ key, parent_id = jira.create_issue(summary,
390
+ description[:top_level_ticket],
391
+ project,
392
+ nil, # no parent id
393
+ assignee)
394
+
395
+ puts "Main release ticket: #{key} (#{assignee}) - #{summary}"
396
+
397
+ # Create subtasks for each step of the release process
398
+ subticket_idx = 1
399
+ subtickets.each { |subticket|
400
+
401
+ next if subticket[:projects] && !subticket[:projects].include?(vars[:project])
402
+
403
+ key, _ = jira.create_issue(subticket[:summary],
404
+ subticket[:description],
405
+ project,
406
+ parent_id,
407
+ subticket[:assignee])
408
+
409
+ puts "\tSubticket #{subticket_idx.to_s.rjust(2)}: #{key} (#{subticket[:assignee]}) - #{subticket[:summary]}"
410
+
411
+ subticket_idx += 1
412
+ }
413
+ end
414
+
415
+ namespace :pl do
416
+ desc <<-EOS
417
+ Make release tickets in JIRA for this project.
418
+ Tickets are created by specifying a number of environment variables, e.g.:
419
+
420
+ rake pl:tickets BUILDER=melissa DEVELOPER=kylo WRITER=nickf RELEASE=3.5.0-rc4
421
+ DATE=2014-04-01 JIRA_USER=kylo PROJECT=PUP
422
+
423
+ The BUILDER/DEVELOPER/WRITER params must be valid jira usernames.
424
+
425
+ The RELEASE param is a freeform string, no validation is done against it.
426
+
427
+ The DATE param is a predicted date that this release ticket will be started. This
428
+ is a hint to Release Engineering about when to prep for the release, but not a
429
+ binding contract to release on that date.
430
+
431
+ The PROJECT param must be a valid jira project name; tickets will be created in this project.
432
+
433
+ The JIRA_USER parameter is used to login to jira to create the tickets. You will
434
+ be prompted for a password. It will not be displayed.
435
+ EOS
436
+
437
+ task :tickets do
438
+ vars = get_vars
439
+ jira = Pkg::Util::Jira.new(vars[:username], vars[:password], vars[:site])
440
+ validate_vars(jira, vars)
441
+
442
+ puts "Creating tickets based on:"
443
+ require 'pp'
444
+ pp vars.select { |k,v| k != :password }
445
+
446
+ create_tickets(jira, vars)
447
+ end
448
+ end
449
+