@@ -35,56 +35,142 @@ def generate_package(project) # rubocop:disable Metrics/AbcSize
3535 bom_install = [ ]
3636 end
3737
38- if project . extra_files_to_sign . any?
39- method = project . use_local_signing ? 'local_commands' : 'commands'
40- sign_commands = Vanagon ::Utilities ::ExtraFilesSigner . send ( method , project , @mktemp , "/osx/build/root/#{ project . name } -#{ project . version } " )
41- else
42- sign_commands = [ ]
38+ # Previously, the "commands" method would test if it could SSH to the signer node and just skip
39+ # all the signing stuff if it couldn't and VANAGON_FORCE_SIGNING was not set. It never really tested
40+ # that signing actually worked and skipped it if it didn't. Now with the local commands, we really
41+ # can't even do that test. So just don't even try signing unless VANAGON_FORCE_SIGNING is set.
42+ unlock = 'security unlock-keychain -p $$SIGNING_KEYCHAIN_PW $$SIGNING_KEYCHAIN'
43+ extra_sign_commands = [ ]
44+ sign_files_commands = [ ]
45+ # If we're not signing, move the pkg to the right place
46+ sign_package_commands = [ "mv #{ project . name } -#{ project . version } -#{ project . release } -installer.pkg pkg/" ]
47+ sign_dmg_commands = [ ]
48+ notarize_dmg_commands = [ ]
49+ if ENV [ 'VANAGON_FORCE_SIGNING' ]
50+ # You should no longer really need to do this, but it's here just in case.
51+ if project . extra_files_to_sign . any?
52+ method = project . use_local_signing ? 'local_commands' : 'commands'
53+ extra_sign_commands = Vanagon ::Utilities ::ExtraFilesSigner . send ( method , project , @mktemp , "/osx/build/root/#{ project . name } -#{ project . version } " )
54+ end
55+
56+ # As of MacOS 15, we have to notarize the dmg. In order to get notarization, we have to
57+ # code sign every single binary, .bundle, and .dylib file in the package. So instead of
58+ # only signing a few files we specify, sign everything we can find that needs to be signed.
59+ # We then need to notarize the resulting dmg.
60+ #
61+ # This requires the VM to have the following env vars set in advance.
62+ # SIGNING_KEYCHAIN - the name of the keychain containing the code/installer signing identities
63+ # SIGNING_KEYCHAIN_PW - the password to unlock the keychain
64+ # APPLICATION_SIGNING_CERT - the identity description used for application signing
65+ # INSTALLER_SIGNING_CERT - the identity description used for installer .pkg signing
66+ # NOTARY_PROFILE - The name of the notary profile stored in the keychain
67+
68+
69+
70+ paths_with_binaries = {
71+ "root/#{ project . name } -#{ project . version } /opt/puppetlabs/bin/" => '*' ,
72+ "root/#{ project . name } -#{ project . version } /opt/puppetlabs/puppet/bin/" => '*' ,
73+ "root/#{ project . name } -#{ project . version } /opt/puppetlabs/puppet/lib/ruby/vendor_gems/bin" => '*' ,
74+ "root/#{ project . name } -#{ project . version } /opt/puppetlabs/puppet/lib/" => '*.dylib' ,
75+ "root/#{ project . name } -#{ project . version } /opt/puppetlabs/puppet/lib" => '*.bundle' ,
76+ 'plugins' => 'puppet-agent-installer-plugin' ,
77+ }
78+
79+ sign_files_commands = [ unlock ]
80+ sign_files_commands += paths_with_binaries . map do |path , name |
81+ "find $(tempdir)/osx/build/#{ path } -name '#{ name } ' -type f -exec codesign --timestamp --options runtime --keychain $$SIGNING_KEYCHAIN -vfs \" $$APPLICATION_SIGNING_CERT\" {} \\ ;"
82+ end
83+ sign_files_commands += paths_with_binaries . map do |path , name |
84+ "find $(tempdir)/osx/build/#{ path } -name '#{ name } ' -type f -exec codesign --verify --strict --verbose=2 {} \\ ;"
85+ end
86+
87+ sign_package_commands = [
88+ unlock ,
89+ "productsign --keychain $$SIGNING_KEYCHAIN --sign \" $$INSTALLER_SIGNING_CERT\" $(tempdir)/osx/build/#{ project . name } -#{ project . version } -#{ project . release } -installer.pkg $(tempdir)/osx/build/pkg/#{ project . name } -#{ project . version } -#{ project . release } -installer.pkg" ,
90+ "rm $(tempdir)/osx/build/#{ project . name } -#{ project . version } -#{ project . release } -installer.pkg" ,
91+ ]
92+
93+ dmg = "$(tempdir)/osx/build/dmg/#{ project . package_name } "
94+ sign_dmg_commands = [
95+ unlock ,
96+ 'cd $(tempdir)/osx/build' ,
97+ "codesign --timestamp --keychain $$SIGNING_KEYCHAIN --sign \" $$APPLICATION_SIGNING_CERT\" #{ dmg } " ,
98+ "codesign --verify --strict --verbose=2 #{ dmg } " ,
99+ ]
100+
101+ notarize_dmg_commands = ENV [ 'NO_NOTARIZE' ] ? [ ] : [
102+ unlock ,
103+ "xcrun notarytool submit #{ dmg } --keychain-profile \" $$NOTARY_PROFILE\" --wait" ,
104+ "xcrun stapler staple #{ dmg } " ,
105+ "spctl --assess --type open --verbose #{ dmg } "
106+ ]
43107 end
44108
45109 # Setup build directories
46- [ "bash -c 'mkdir -p $(tempdir)/osx/build/{dmg,pkg,scripts,resources,root,payload,plugins}'" ,
47- "mkdir -p $(tempdir)/osx/build/root/#{ project . name } -#{ project . version } " ,
48- "mkdir -p $(tempdir)/osx/build/pkg" ,
49- # Grab distribution xml, scripts and other external resources
50- "cp #{ project . name } -installer.xml $(tempdir)/osx/build/" ,
51- #copy the uninstaller to the pkg dir, where eventually the installer will go too
52- "cp #{ project . name } -uninstaller.tool $(tempdir)/osx/build/pkg/" ,
53- "cp scripts/* $(tempdir)/osx/build/scripts/" ,
54- "if [ -d resources/osx/productbuild ] ; then cp -r resources/osx/productbuild/* $(tempdir)/osx/build/; fi" ,
55- # Unpack the project
56- "gunzip -c #{ project . name } -#{ project . version } .tar.gz | '#{ @tar } ' -C '$(tempdir)/osx/build/root/#{ project . name } -#{ project . version } ' --strip-components 1 -xf -" ,
57-
58- bom_install ,
59-
60- # Sign extra files
61- sign_commands ,
62-
63- # Package the project
64- "(cd $(tempdir)/osx/build/; #{ @pkgbuild } --root root/#{ project . name } -#{ project . version } \
65- --scripts $(tempdir)/osx/build/scripts \
66- --identifier #{ project . identifier } .#{ project . name } \
67- --version #{ project . version } \
68- --preserve-xattr \
69- --install-location / \
70- payload/#{ project . name } -#{ project . version } -#{ project . release } .pkg)",
71- # Create a custom installer using the pkg above
72- "(cd $(tempdir)/osx/build/; #{ @productbuild } --distribution #{ project . name } -installer.xml \
73- --identifier #{ project . identifier } .#{ project . name } -installer \
74- --package-path payload/ \
75- --resources $(tempdir)/osx/build/resources \
76- --plugins $(tempdir)/osx/build/plugins \
77- pkg/#{ project . name } -#{ project . version } -#{ project . release } -installer.pkg)",
78- # Create a dmg and ship it to the output directory
79- "(cd $(tempdir)/osx/build; \
80- #{ @hdiutil } create \
81- -volname #{ project . name } -#{ project . version } \
82- -fs JHFS+ \
83- -format UDBZ \
84- -srcfolder pkg \
85- dmg/#{ project . package_name } )",
86- "mkdir -p output/#{ target_dir } " ,
87- "cp $(tempdir)/osx/build/dmg/#{ project . package_name } ./output/#{ target_dir } " ] . flatten . compact
110+ [
111+ "bash -c 'mkdir -p $(tempdir)/osx/build/{dmg,pkg,scripts,resources,root,payload,plugins}'" ,
112+ "mkdir -p $(tempdir)/osx/build/root/#{ project . name } -#{ project . version } " ,
113+ "mkdir -p $(tempdir)/osx/build/pkg" ,
114+ # Grab distribution xml, scripts and other external resources
115+ "cp #{ project . name } -installer.xml $(tempdir)/osx/build/" ,
116+ #copy the uninstaller to the pkg dir, where eventually the installer will go too
117+ "cp #{ project . name } -uninstaller.tool $(tempdir)/osx/build/pkg/" ,
118+ "cp scripts/* $(tempdir)/osx/build/scripts/" ,
119+ "if [ -d resources/osx/productbuild ] ; then cp -r resources/osx/productbuild/* $(tempdir)/osx/build/; fi" ,
120+ # Unpack the project
121+ "gunzip -c #{ project . name } -#{ project . version } .tar.gz | '#{ @tar } ' -C '$(tempdir)/osx/build/root/#{ project . name } -#{ project . version } ' --strip-components 1 -xf -" ,
122+
123+ bom_install ,
124+
125+ # Sign extra files
126+ extra_sign_commands ,
127+
128+ # As of MacOS 15, we have to notarize the dmg. In order to get notarization, we have to
129+ # code sign every single binary, .bundle, and .dylib file in the package. So instead of
130+ # only signing a few files we specify, sign everything we can find that needs to be signed.
131+ #
132+ # This requires the VM to have the following env vars set in advance.
133+ # SIGNING_KEYCHAIN - the name of the keychain containing the code/installer signing identities
134+ # SIGNING_KEYCHAIN_PW - the password to unlock the keychain
135+ # APPLICATION_SIGNING_CERT - the identity description used for application signing
136+ # INSTALLER_SIGNING_CERT - the identity description used for installer .pkg signing
137+ # NOTARY_PROFILE - The name of the notary profile stored in the keychain
138+
139+ # Package the project
140+ "(cd $(tempdir)/osx/build/; #{ @pkgbuild } --root root/#{ project . name } -#{ project . version } \
141+ --scripts $(tempdir)/osx/build/scripts \
142+ --identifier #{ project . identifier } .#{ project . name } \
143+ --version #{ project . version } \
144+ --preserve-xattr \
145+ --install-location / \
146+ payload/#{ project . name } -#{ project . version } -#{ project . release } .pkg)",
147+
148+ sign_files_commands ,
149+
150+ # Create a custom installer using the pkg above
151+ "(cd $(tempdir)/osx/build/; #{ @productbuild } --distribution #{ project . name } -installer.xml \
152+ --identifier #{ project . identifier } .#{ project . name } -installer \
153+ --package-path payload/ \
154+ --resources $(tempdir)/osx/build/resources \
155+ --plugins $(tempdir)/osx/build/plugins \
156+ #{ project . name } -#{ project . version } -#{ project . release } -installer.pkg)",
157+
158+ sign_package_commands ,
159+
160+ # Create a dmg and ship it to the output directory
161+ "(cd $(tempdir)/osx/build; \
162+ #{ @hdiutil } create \
163+ -volname #{ project . name } -#{ project . version } \
164+ -fs JHFS+ \
165+ -format UDBZ \
166+ -srcfolder pkg \
167+ dmg/#{ project . package_name } )",
168+
169+ sign_dmg_commands ,
170+ notarize_dmg_commands ,
171+ "mkdir -p output/#{ target_dir } " ,
172+ "cp $(tempdir)/osx/build/dmg/#{ project . package_name } ./output/#{ target_dir } "
173+ ] . flatten . compact
88174 end
89175
90176 # Method to generate the files required to build a osx package for the project
0 commit comments