@@ -35,56 +35,139 @@ 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\" #{ project . name } -#{ project . version } -#{ project . release } -installer.pkg pkg/#{ project . name } -#{ project . version } -#{ project . release } -installer.pkg" ,
90+ "rm #{ project . name } -#{ project . version } -#{ project . release } -installer.pkg" ,
91+ ]
92+
93+ dmg = "dmg/#{ project . package_name } "
94+ sign_dmg_commands = [
95+ unlock ,
96+ "codesign --timestamp --keychain $$SIGNING_KEYCHAIN --sign \" $$APPLICATION_SIGNING_CERT\" #{ dmg } " ,
97+ "codesign --verify --strict --verbose=2 #{ dmg } " ,
98+ ]
99+
100+ notarize_dmg_commands = ENV [ 'NO_NOTARIZE' ] ? [ ] : [
101+ unlock ,
102+ "xcrun notarytool submit #{ dmg } --keychain-profile \" $$NOTARY_PROFILE\" --wait" ,
103+ "xcrun stapler staple #{ dmg } " ,
104+ "spctl --assess --type open --verbose #{ dmg } "
105+ ]
43106 end
44107
45108 # 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
109+ [
110+ "bash -c 'mkdir -p $(tempdir)/osx/build/{dmg,pkg,scripts,resources,root,payload,plugins}'" ,
111+ "mkdir -p $(tempdir)/osx/build/root/#{ project . name } -#{ project . version } " ,
112+ "mkdir -p $(tempdir)/osx/build/pkg" ,
113+ # Grab distribution xml, scripts and other external resources
114+ "cp #{ project . name } -installer.xml $(tempdir)/osx/build/" ,
115+ #copy the uninstaller to the pkg dir, where eventually the installer will go too
116+ "cp #{ project . name } -uninstaller.tool $(tempdir)/osx/build/pkg/" ,
117+ "cp scripts/* $(tempdir)/osx/build/scripts/" ,
118+ "if [ -d resources/osx/productbuild ] ; then cp -r resources/osx/productbuild/* $(tempdir)/osx/build/; fi" ,
119+ # Unpack the project
120+ "gunzip -c #{ project . name } -#{ project . version } .tar.gz | '#{ @tar } ' -C '$(tempdir)/osx/build/root/#{ project . name } -#{ project . version } ' --strip-components 1 -xf -" ,
121+
122+ bom_install ,
123+
124+ # Sign extra files
125+ extra_sign_commands ,
126+
127+ # As of MacOS 15, we have to notarize the dmg. In order to get notarization, we have to
128+ # code sign every single binary, .bundle, and .dylib file in the package. So instead of
129+ # only signing a few files we specify, sign everything we can find that needs to be signed.
130+ #
131+ # This requires the VM to have the following env vars set in advance.
132+ # SIGNING_KEYCHAIN - the name of the keychain containing the code/installer signing identities
133+ # SIGNING_KEYCHAIN_PW - the password to unlock the keychain
134+ # APPLICATION_SIGNING_CERT - the identity description used for application signing
135+ # INSTALLER_SIGNING_CERT - the identity description used for installer .pkg signing
136+ # NOTARY_PROFILE - The name of the notary profile stored in the keychain
137+
138+ # Package the project
139+ "(cd $(tempdir)/osx/build/; #{ @pkgbuild } --root root/#{ project . name } -#{ project . version } \
140+ --scripts $(tempdir)/osx/build/scripts \
141+ --identifier #{ project . identifier } .#{ project . name } \
142+ --version #{ project . version } \
143+ --preserve-xattr \
144+ --install-location / \
145+ payload/#{ project . name } -#{ project . version } -#{ project . release } .pkg)",
146+
147+ # Create a custom installer using the pkg above
148+ "(cd $(tempdir)/osx/build/; #{ @productbuild } --distribution #{ project . name } -installer.xml \
149+ --identifier #{ project . identifier } .#{ project . name } -installer \
150+ --package-path payload/ \
151+ --resources $(tempdir)/osx/build/resources \
152+ --plugins $(tempdir)/osx/build/plugins \
153+ #{ project . name } -#{ project . version } -#{ project . release } -installer.pkg)",
154+
155+ sign_package_commands ,
156+
157+ # Create a dmg and ship it to the output directory
158+ "(cd $(tempdir)/osx/build; \
159+ #{ @hdiutil } create \
160+ -volname #{ project . name } -#{ project . version } \
161+ -fs JHFS+ \
162+ -format UDBZ \
163+ -srcfolder pkg \
164+ dmg/#{ project . package_name } )",
165+
166+ sign_dmg_commands ,
167+ notarize_dmg_commands ,
168+ "mkdir -p output/#{ target_dir } " ,
169+ "cp $(tempdir)/osx/build/dmg/#{ project . package_name } ./output/#{ target_dir } "
170+ ] . flatten . compact
88171 end
89172
90173 # Method to generate the files required to build a osx package for the project
0 commit comments