macOS Code Signing and Notarization#669
macOS Code Signing and Notarization#669halprin merged 19 commits intoDescentDevelopers:mainfrom halprin:macos-code-sign
Conversation
…e into installed folder
tophyr
left a comment
There was a problem hiding this comment.
Thank you, thank you THANK YOU!!! This will really help the user experience on Mac. I noted some threat-model risks that we should mitigate, but I don't think they're critical to do before merging this.
.github/workflows/build.yml
Outdated
| runs-on: ${{ matrix.os.runner }} | ||
|
|
||
| env: | ||
| MACOS_SIGNING: ${{ secrets.MACOS_SIGNING_IDENTITY != '' }} |
There was a problem hiding this comment.
nit: might be better to include the os preset check in here as well? then the if clauses in the following changes could check just one master variable. thoughts?
| MACOS_SIGNING: ${{ secrets.MACOS_SIGNING_IDENTITY != '' }} | |
| MACOS_SIGNING: ${{ matrix.os.preset == 'mac' && secrets.MACOS_SIGNING_IDENTITY != '' }} |
There was a problem hiding this comment.
We can't lump them together because sometimes we need to build for non-Mac, build for the Mac but not sign, and build for the Mac and sign. If we combined the variables, then we couldn't sometimes build for the Mac but not sign or sometimes build for the Mac and sign.
There was a problem hiding this comment.
It would just be MACOS_SIGNING=false in those cases, wouldn't it? I'm just noticing that all three times MACOS_SIGNING is referenced, it's also &&'ed with the os.preset == 'mac' check. If we move the os.preset == 'mac' check into the MACOS_SIGNING variable, we can remove it from the three usage sites and prevent mixups in the future if someone alters this workflow to add a new usage but forgets to check the OS.
There was a problem hiding this comment.
Oh, I see. Hmmm. But even with this change we would continue to use if: ${{ matrix.os.preset == 'mac' }} like when we call Install macOS Rosetta 2 and a couple others places, right?
There was a problem hiding this comment.
Oh, I see. Hmmm. But even with this change we would continue to use
if: ${{ matrix.os.preset == 'mac' }}like when we callInstall macOS Rosetta 2and a couple others places, right?
I would imagine, yeah. Adding the check here would just be for fully-encapsulating the standalone answer to "should i perform mac signing"
| build: | ||
| name: Build for PR | ||
| uses: ./.github/workflows/build.yml | ||
| # explicitly not passing secrets into the build |
There was a problem hiding this comment.
double-checking: pull requests originating from outside the Descent3 repository will never get access to secrets, no matter what - correct? ie, even if the PR modifies this file, or even if someone merges a modification to this file?
(is it even possible to submit a PR to yourself? suppose i could try that out, but kinda irrelevant either way)
There was a problem hiding this comment.
I'll do an actual live test of this tomorrow.
There was a problem hiding this comment.
The live test was a success. I confirmed GitHub's documentation to be correct. A PR from a fork has no access to the secrets in the base repository. Even if the fork PR changes the GitHub Action and tries to reference the secrets and exfiltrate them, nothing is accessed.
Lgt2x
left a comment
There was a problem hiding this comment.
I tested your artifact, it works great! That's some seriously cool work you did there :)
I invited you to the github org so you can push the secrets you need
| CC: ${{ matrix.os.cc }} | ||
| CXX: ${{ matrix.os.cxx }} | ||
| run: cmake --preset ${{ matrix.os.preset }} -DBUILD_TESTING=ON -DENABLE_LOGGER=ON -DFORCE_PORTABLE_INSTALL=ON -DBUILD_EDITOR=ON -DUSE_EXTERNAL_PLOG=ON | ||
| run: cmake --preset ${{ matrix.os.preset }} -DCODESIGN_IDENTITY=${{ secrets.MACOS_SIGNING_IDENTITY }} -DBUILD_TESTING=ON -DENABLE_LOGGER=ON -DFORCE_PORTABLE_INSTALL=ON -DBUILD_EDITOR=ON -DUSE_EXTERNAL_PLOG=ON |
There was a problem hiding this comment.
The CODESIGN_IDENTITY CMake cache variable should be declared as such in the top-level CMakeLists.txt: set(CODESIGN_IDENTITY ... CACHE STRING ...) like we do for USE_VCPKG for example. It should also be documented in BUILD.md
There was a problem hiding this comment.
Fixed. CMake isn't my forte, so let me know if I can do this better.
There was a problem hiding this comment.
Oooo, maybe not fixed. In fact, the build is failing. Sad.
There was a problem hiding this comment.
I tried futzing with it but couldn't get it working. I'll try again tomorrow.
There was a problem hiding this comment.
I'll look into it tonight and try to help you out
There was a problem hiding this comment.
Thanks for the help! Fixed.
| target_include_directories(Descent3_Online_TCP_IP PRIVATE ${SDL3_INCLUDE_DIRS}) | ||
| if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") | ||
| set_target_properties(Descent3_Online_TCP_IP PROPERTIES SUFFIX ".dylib") | ||
| if(DEFINED CODESIGN_IDENTITY AND NOT "${CODESIGN_IDENTITY}" STREQUAL "") |
There was a problem hiding this comment.
We could make that couple lines a CMake function or macro that takes the target name as argument
There was a problem hiding this comment.
You can define a function like this in the top level CMakelists:
set(CODESIGN_IDENTITY "" CACHE STRING "Sets the macOS code signing identity. If set to something besides the empty string, then the dynamic libraries put into the hog files will be signed using this identity.")
function (macos_sign target)
message ("target: ${target}")
if(DEFINED CODESIGN_IDENTITY AND NOT "${CODESIGN_IDENTITY}" STREQUAL "")
message(STATUS "Code signing ${target}")
add_custom_command(TARGET ${target} POST_BUILD
COMMAND codesign --verbose --sign "${CODESIGN_IDENTITY}" --force --timestamp --deep -o runtime $<TARGET_FILE:${target}>)
endif()
endfunction()and use it as macos_sign("Parallax_Online") for instance
I hope this helps
There was a problem hiding this comment.
Thanks for the help! Fixed.
There was a problem hiding this comment.
Please use the https://github.com/DescentDevelopers/import-codesign-certs and https://github.com/DescentDevelopers/macos-sign-package-notarize actions instead of external ones, now that @Lgt2x has forked them.
CMakeLists.txt
Outdated
| set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "default build type") | ||
| endif() | ||
|
|
||
| set(CODESIGN_IDENTITY "" CACHE STRING "Sets the macOS code signing identity. If set to something besides the empty string "", then the dynamic libraries put into the hog files will be signed using this identity.") |
There was a problem hiding this comment.
this does not work because of the double quotes inside of the documentation string "", CMake does not like that
There was a problem hiding this comment.
Thanks for the help there!
|
Good for me, are the secrets all set on this repository so we can merge @halprin ? |
|
We're ready to merge! |
Pull Request Type
Description
The macOS binaries are now code signed and notarized.
There are two ways this is accomplished.
d3-osx.hogand everything in theonlinefolder.netgamesfolder. These binaries are signed after the build using a helper GitHub action. This helper GitHub action also packages everything into a DMG disk image and notarizes the disk image. A DMG is an established package format and natively supports notarization, unlike a zip file.Code signing and notarization only happens on push to the
mainbranch, not in a pull request. Secrets can't be accessed in a pull request from a fork, but I also chose to refactor the GitHub action workflows to explicitly not pass in secrets into the pull request workflow to make it obvious. Let me know if we don't like this, but I thought the explicit approach was better than implicit. We can also leverage this approach in the future for versioned releases.Updated the documentation to remove the work-arounds needed when the application was unsigned.
If you want to inspect a test build, you can see this build in my fork. You can't depend on the build on this PR because, as mentioned above, we aren't signing and notarizing for PR builds.
Related Issues
Fixes #540.
Fixes #559.
Screenshots (if applicable)
Checklist
Additional Comments