Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notarize the GitX app #334

Merged
merged 2 commits into from
Sep 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 76 additions & 2 deletions .github/workflows/BuildPR.yml
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,84 @@ jobs:
submodules: recursive
- name: Set XCode Version
run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app
- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.provisionprofile
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db

# import certificate and provisioning profile from secrets
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output $CERTIFICATE_PATH
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode --output $PP_PATH

# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH

# import certificate to keychain
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH

# apply provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- name: pre build
run: cd External/objective-git && script/bootstrap && script/update_libgit2 && cd ../..
- name: Build project
run: xcodebuild -workspace GitX.xcworkspace -scheme GitX -archivePath ./GitX archive ARCHS="${{ matrix.abi }}"
run: xcodebuild -workspace GitX.xcworkspace -scheme GitX -archivePath ./GitX archive ARCHS="${{ matrix.abi }}" PRODUCT_BUNDLE_IDENTIFIER=${{ secrets.NOTARY_BUNDLE_IDENTIFIER}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@insha can it be this secrets.NOTARY_BUNDLE_IDENTIFIER can have a relation to this meaning identifier net.phere.GitX ?

- name: Prepare artifact
env:
EXPORT_OPTIONS: ${{ secrets.NOTARY_EXPORT_OPTIONS }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@insha
I try to do the same on an other project, but I've no clue what's the content of NOTARY_EXPORT_OPTIONS is.
I guess it's not a secret, am I right ?
If yes, please can you write me the content of it ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hannesa2 Apologies for the delayed response. The value of this secret variable is the contents of the export options plist file. It is in secrets because it contains my Apple Team ID. The contents are as follows with my team ID redacted:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>destination</key>
	<string>export</string>
	<key>method</key>
	<string>developer-id</string>
	<key>provisioningProfiles</key>
	<dict>
		<key>com.themacronaut.net.phere.GitX</key>
		<string>GitX Notarized Distribution</string>
	</dict>
	<key>signingCertificate</key>
	<string>Developer ID Application</string>
	<key>signingStyle</key>
	<string>manual</string>
	<key>teamID</key>
	<string>---REDACTED---</string>
</dict>
</plist>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean to say the entire XML content is put inside an environment variable? 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, from what I recall, that is correct. The reason being that the plist files has sensitive information in it.

run: |
mv GitX.xcarchive/Products/Applications/GitX.app .
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's about #337 and #336
@insha Before we move GitX.xcarchive/Products/Applications/GitX.app to root .

EXPORT_OPTIONS_PATH=$RUNNER_TEMP/ExportOptions.plist

echo -n "$EXPORT_OPTIONS" > EXPORT_OPTIONS_PATH

xcodebuild -exportArchive -archivePath GitX.xcarchive -exportPath . -exportOptionsPlist EXPORT_OPTIONS_PATH
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now we create a new archive and using this. Not sure if this is an issue


hdiutil create -fs HFS+ -srcfolder GitX.app -volname GitX GitX-${{ matrix.abi }}.dmg
zip -r GitX-${{ matrix.abi }}.zip GitX.app
- name: Notarize App
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
KEY_ID: ${{ secrets.APPLE_KEY_ID }}
run: |
APP_PATH="GitX.app"
ZIP_PATH="GitX.zip"
NOTARY_LOG="notary.log"
ID_FILE="id.txt"

ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"

xcrun notarytool submit "$ZIP_PATH" --key-id $KEY_ID --apple-id $APPLE_ID --team-id $TEAM_ID --password $APPLE_PASSWORD --wait | tee "$NOTARY_LOG" echo "print log output"
cat "$NOTARY_LOG"

ID=$(cat "$NOTARY_LOG" | tail -3 | cut -d':' -f2 | head -n 1)
echo "Id is: $ID"

xcrun notarytool log $ID --apple-id $APPLE_ID --team-id $TEAM_ID --password $APPLE_PASSWORD
- name: Staple Notarization
run: |
# While you can notarize a ZIP archive, you can’t staple to it directly.
# Instead, run stapler against each item that you added to the archive.
# Then create a new ZIP file containing the stapled items for distribution.
# Reference: https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/customizing_the_notarization_workflow
APP_PATH="GitX.app"
ZIP_PATH="GitX.zip"

xcrun stapler staple "$APP_PATH"
ditto -c -k --keepParent "$APP_PATH" "$ZIP_PATH"
- name: Check Notarization
run: spctl -a -vv GitX.app
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this verify of the notarization

- name: Upload artifact
uses: actions/upload-artifact@v3
if: ${{ success() }}
Expand All @@ -51,3 +120,8 @@ jobs:
with:
name: GitX-${{ matrix.abi }}.zip
path: GitX-${{ matrix.abi }}.zip
- name: Clean up keychain and provisioning profile
if: ${{ always() }}
run: |
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
rm ~/Library/MobileDevice/Provisioning\ Profiles/build_pp.provisionprofile
5 changes: 5 additions & 0 deletions GitX.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>
44 changes: 32 additions & 12 deletions GitX.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,9 @@
50DCC65820111E4000999D3D /* PBGitRevisionRow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PBGitRevisionRow.h; sourceTree = "<group>"; };
50DCC65920111E4000999D3D /* PBGitRevisionRow.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PBGitRevisionRow.m; sourceTree = "<group>"; };
551BF111112F371800265053 /* gitx_askpasswd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gitx_askpasswd; sourceTree = BUILT_PRODUCTS_DIR; };
62E3BAA728D5104C00DCD7B2 /* GitX.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GitX.entitlements; sourceTree = "<group>"; };
62E3BAC428D5105200DCD7B2 /* cli tool.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "cli tool.entitlements"; sourceTree = SOURCE_ROOT; };
62E3BAC528D5105600DCD7B2 /* gitx_askpasswd.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = gitx_askpasswd.entitlements; sourceTree = SOURCE_ROOT; };
643952751603EF9B00BB7AFF /* PBSourceViewGitSubmoduleItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PBSourceViewGitSubmoduleItem.h; sourceTree = "<group>"; };
643952761603EF9B00BB7AFF /* PBSourceViewGitSubmoduleItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PBSourceViewGitSubmoduleItem.m; sourceTree = "<group>"; };
6C2581091C2720E60080A89A /* GitXCommitCopier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GitXCommitCopier.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -756,6 +759,7 @@
29B97314FDCFA39411CA2CEA /* GitTest */ = {
isa = PBXGroup;
children = (
62E3BAA728D5104C00DCD7B2 /* GitX.entitlements */,
4A90A72B14A9C12F00D0DA02 /* README.markdown */,
4A5D762114A9A9CC00DF6C68 /* Classes */,
4A5D773E14A9AB3A00DF6C68 /* External Sources */,
Expand Down Expand Up @@ -793,6 +797,7 @@
37A5656C1EAD077400CA0332 /* cli tool */ = {
isa = PBXGroup;
children = (
62E3BAC428D5105200DCD7B2 /* cli tool.entitlements */,
4A5D768614A9A9CC00DF6C68 /* gitx.m */,
4A90A73314A9D1E800D0DA02 /* GitX.h */,
4DC1853818E6F93200E8DB8F /* Info-gitx.plist */,
Expand All @@ -804,6 +809,7 @@
37A5656D1EAD07C200CA0332 /* gitx_askpasswd */ = {
isa = PBXGroup;
children = (
62E3BAC528D5105600DCD7B2 /* gitx_askpasswd.entitlements */,
4A5D768714A9A9CC00DF6C68 /* gitx_askpasswd_main.m */,
);
name = gitx_askpasswd;
Expand Down Expand Up @@ -1157,10 +1163,10 @@
children = (
4A68AD6714A0050F006DE321 /* Sparkle.framework */,
D19D706227B8DA2A00A5C740 /* Autoupdate */,
D19D706427B8DA2A00A5C740 /* org.sparkle-project.InstallerLauncher.xpc */,
D19D706627B8DA2A00A5C740 /* org.sparkle-project.InstallerConnection.xpc */,
D19D706827B8DA2A00A5C740 /* org.sparkle-project.InstallerStatus.xpc */,
D19D706A27B8DA2A00A5C740 /* org.sparkle-project.Downloader.xpc */,
D19D706427B8DA2A00A5C740 /* Installer.xpc */,
D19D706627B8DA2A00A5C740 /* InstallerConnection.xpc */,
D19D706827B8DA2A00A5C740 /* InstallerStatus.xpc */,
D19D706A27B8DA2A00A5C740 /* Downloader.xpc */,
4A68AD6914A0050F006DE321 /* Sparkle Test App.app */,
D19D706C27B8DA2A00A5C740 /* TestAppHelper.xpc */,
4A68AD6B14A0050F006DE321 /* Sparkle Unit Tests.xctest */,
Expand Down Expand Up @@ -1423,31 +1429,31 @@
remoteRef = D19D706127B8DA2A00A5C740 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D19D706427B8DA2A00A5C740 /* org.sparkle-project.InstallerLauncher.xpc */ = {
D19D706427B8DA2A00A5C740 /* Installer.xpc */ = {
isa = PBXReferenceProxy;
fileType = "wrapper.xpc-service";
path = "org.sparkle-project.InstallerLauncher.xpc";
path = Installer.xpc;
remoteRef = D19D706327B8DA2A00A5C740 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D19D706627B8DA2A00A5C740 /* org.sparkle-project.InstallerConnection.xpc */ = {
D19D706627B8DA2A00A5C740 /* InstallerConnection.xpc */ = {
isa = PBXReferenceProxy;
fileType = "wrapper.xpc-service";
path = "org.sparkle-project.InstallerConnection.xpc";
path = InstallerConnection.xpc;
remoteRef = D19D706527B8DA2A00A5C740 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D19D706827B8DA2A00A5C740 /* org.sparkle-project.InstallerStatus.xpc */ = {
D19D706827B8DA2A00A5C740 /* InstallerStatus.xpc */ = {
isa = PBXReferenceProxy;
fileType = "wrapper.xpc-service";
path = "org.sparkle-project.InstallerStatus.xpc";
path = InstallerStatus.xpc;
remoteRef = D19D706727B8DA2A00A5C740 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
D19D706A27B8DA2A00A5C740 /* org.sparkle-project.Downloader.xpc */ = {
D19D706A27B8DA2A00A5C740 /* Downloader.xpc */ = {
isa = PBXReferenceProxy;
fileType = "wrapper.xpc-service";
path = "org.sparkle-project.Downloader.xpc";
path = Downloader.xpc;
remoteRef = D19D706927B8DA2A00A5C740 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
Expand Down Expand Up @@ -1827,8 +1833,10 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-gitx";
CODE_SIGN_ENTITLEMENTS = GitX.entitlements;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = "\"$(PROJECT_DIR)\"";
GCC_DYNAMIC_NO_PIC = NO;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
Expand All @@ -1849,8 +1857,10 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-gitx";
CODE_SIGN_ENTITLEMENTS = GitX.entitlements;
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = "\"$(PROJECT_DIR)\"";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Resources/GitX_Prefix.pch;
Expand Down Expand Up @@ -1985,7 +1995,9 @@
551BF113112F371800265053 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = gitx_askpasswd.entitlements;
CODE_SIGN_IDENTITY = "-";
ENABLE_HARDENED_RUNTIME = YES;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = gitx_askpasswd;
SKIP_INSTALL = YES;
Expand All @@ -1995,7 +2007,9 @@
551BF114112F371800265053 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = gitx_askpasswd.entitlements;
CODE_SIGN_IDENTITY = "-";
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_PREFIX_HEADER = $PROJECT_TEMP_DIR/revision;
INFOPLIST_PREPROCESS = YES;
INSTALL_PATH = /usr/local/bin;
Expand All @@ -2007,7 +2021,9 @@
551BF115112F371800265053 /* Install */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = gitx_askpasswd.entitlements;
CODE_SIGN_IDENTITY = "-";
ENABLE_HARDENED_RUNTIME = YES;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = gitx_askpasswd;
SKIP_INSTALL = YES;
Expand All @@ -2017,8 +2033,10 @@
913D5E4B0E55644600CECEA2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "cli tool.entitlements";
CODE_SIGN_IDENTITY = "-";
CREATE_INFOPLIST_SECTION_IN_BINARY = YES;
ENABLE_HARDENED_RUNTIME = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Resources/GitX_Prefix.pch;
INFOPLIST_FILE = "Resources/Info-gitx.plist";
Expand All @@ -2032,8 +2050,10 @@
913D5E4C0E55644600CECEA2 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "cli tool.entitlements";
CODE_SIGN_IDENTITY = "-";
CREATE_INFOPLIST_SECTION_IN_BINARY = YES;
ENABLE_HARDENED_RUNTIME = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Resources/GitX_Prefix.pch;
INFOPLIST_FILE = "Resources/Info-gitx.plist";
Expand Down
5 changes: 5 additions & 0 deletions cli tool.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>
5 changes: 5 additions & 0 deletions gitx_askpasswd.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>