Skip to content

Commit

Permalink
CI: Add a codesign step for macOS extension builds
Browse files Browse the repository at this point in the history
This is not fully tested yet because of Apple issues.
The notarization process can hang in perpetuity, with
no way for the developer to affect it or even to
understand the source of the hiccup.

But the overall flow for the extension codesign should
be correct here. We still need to do the same for the
example project, but let's see if we can get this working first.
  • Loading branch information
YuriSizov committed Jun 5, 2024
1 parent 4791bdb commit d36110e
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 0 deletions.
72 changes: 72 additions & 0 deletions .github/actions/sign-extension/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Codesign GDSiON (macos)
description: Configure the environment and sign the build artifacts for macOS.

inputs:
setup-env:
description: Flag that enables the setup step.
default: false
codesign:
description: Flag that enables the codesign step.
default: false

# Setup arguments.
apple-cert-base64:
required: true
apple-cert-password:
required: true

# Codesign arguments.
apple-dev-id:
required: true
apple-dev-app-id:
required: true
apple-dev-team-id:
required: true
apple-dev-password:
required: true

# Input/output arguments.
directory:
description: Path to the root folder of the .framework folder.
required: true
target-name:
description: Exact name of the .framework folder.
required: true

runs:
using: composite
steps:
# macOS-specific steps.

# Setup.

- name: Set up the signing environment
if: ${{ env.SCONS_PLATFORM == 'macos' && inputs.setup-env }}
shell: bash
env:
APPLE_CERT_BASE64: ${{ inputs.apple-cert-base64 }}
APPLE_CERT_PASSWORD: ${{ inputs.apple-cert-password }}
run: $GITHUB_ACTION_PATH/setup.sh

# Codesign.

- name: Prepare the .plist file
if: ${{ env.SCONS_PLATFORM == 'macos' && inputs.codesign }}
shell: bash
env:
RESOURCES_PATH: '${{ inputs.directory }}/${{ inputs.target-name }}/Resources'
run: |
mkdir $RESOURCES_PATH
sed 's/\${FRAMEWORK_NAME}/${{ inputs.target-name }}/g' $GITHUB_ACTION_PATH/Info.plist > $RESOURCES_PATH/Info.plist
- name: Sign and notarize the framework
if: ${{ env.SCONS_PLATFORM == 'macos' && inputs.codesign }}
shell: bash
env:
APPLE_DEV_ID: ${{ inputs.apple-dev-id }}
APPLE_DEV_APP_ID: ${{ inputs.apple-dev-app-id }}
APPLE_DEV_TEAM_ID: ${{ inputs.apple-dev-team-id }}
APPLE_DEV_PASSWORD: ${{ inputs.apple-dev-password }}
FRAMEWORK_PATH: ${{ inputs.directory }}/${{ inputs.target-name }}
ARCHIVE_PATH: ${{ inputs.directory }}/framework.zip
run: $GITHUB_ACTION_PATH/sign.sh
32 changes: 32 additions & 0 deletions .github/actions/sign-extension/macos/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${FRAMEWORK_NAME}</string>
<key>CFBundleName</key>
<string>GDSiON Software Synthesizer</string>
<key>CFBundleDisplayName</key>
<string>GDSiON Software Synthesizer</string>
<key>CFBundleIdentifier</key>
<string>net.humnom.gdsion</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright (c) 2024 Yuri Sizov and contributors</string>
<key>CFBundleVersion</key>
<string>0.6.9</string>
<key>CFBundleShortVersionString</key>
<string>0.6.9</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>DTPlatformName</key>
<string>macosx</string>
<key>LSMinimumSystemVersion</key>
<string>10.12</string>
</dict>
</plist>
41 changes: 41 additions & 0 deletions .github/actions/sign-extension/macos/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash

# Based on https://github.com/godot-jolt/godot-jolt/blob/master/scripts/ci_sign_macos.ps1

certificate_base64="$APPLE_CERT_BASE64"
certificate_password="$APPLE_CERT_PASSWORD"

if [ -z "${certificate_base64}" ]; then
echo "ERROR: Missing codesign certificate."
exit 1
fi
if [ -z "${certificate_password}" ]; then
echo "ERROR: Missing codesign certificate password."
exit 1
fi

# Convert the certificate back to its file form.

echo "Decoding the base64 certificate..."

certificate_path="certificate.p12"
base64 --decode -o ${certificate_path} <<< "${certificate_base64}"

# Set up the keychain and import the certificate.

keychain="ephemeral.keychain"
keychain_password="$(openssl rand -base64 16)"

echo "Creating the default keychain..."

security create-keychain -p ${keychain_password} ${keychain}
security default-keychain -s ${keychain}

echo "Importing the certificate into the keychain..."

security import ${certificate_path} -k ~/Library/Keychains/${keychain} -P ${certificate_password} -T /usr/bin/codesign
security find-identity

echo "Granting access to the keychain..."

security set-key-partition-list -S "apple-tool:,apple:" -s -k ${keychain_password} ${keychain}
48 changes: 48 additions & 0 deletions .github/actions/sign-extension/macos/sign.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/bash

# Based on https://github.com/godot-jolt/godot-jolt/blob/master/scripts/ci_sign_macos.ps1

apple_dev_id="$APPLE_DEV_ID"
apple_dev_app_id="$APPLE_DEV_APP_ID"
apple_dev_team_id="$APPLE_DEV_TEAM_ID"
apple_dev_password="$APPLE_DEV_PASSWORD"

framework_path="$FRAMEWORK_PATH"
archive_path="$ARCHIVE_PATH"

if [ -z "${apple_dev_id}" ]; then
echo "ERROR: Missing Apple developer ID."
exit 1
fi
if [ -z "${apple_dev_app_id}" ]; then
echo "ERROR: Missing Apple developer application ID."
exit 1
fi
if [ -z "${apple_dev_team_id}" ]; then
echo "ERROR: Missing Apple team ID."
exit 1
fi
if [ -z "${apple_dev_password}" ]; then
echo "ERROR: Missing Apple developer password."
exit 1
fi
if [ -z "${framework_path}" ]; then
echo "ERROR: Missing framework path to sign."
exit 1
fi
if [ -z "${archive_path}" ]; then
echo "ERROR: Missing target archive path."
exit 1
fi

# Sign and notarize the framework.

echo "Signing and verifying the framework at '${framework_path}'..."

codesign --verify --timestamp --verbose --deep --sign "${apple_dev_app_id}" "${framework_path}"
codesign --verify "${framework_path}"

echo "Archiving and notarizing the signed framework..."

ditto -ck "${framework_path}" "${archive_path}"
xcrun notarytool submit "${archive_path}" --apple-id ${apple_dev_id} --team-id ${apple_dev_team_id} --password ${apple_dev_password} --wait
49 changes: 49 additions & 0 deletions .github/actions/upload-extension/action.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,77 @@
name: Upload GDSiON release
description: Strip and upload build artifacts.

inputs:
sign-extension:
description: Flag that enables the codesign routine for platforms that support it.
default: false

runs:
using: "composite"
steps:

# Linux-specific steps.

- name: Prepare the binaries (Linux)
if: ${{ env.SCONS_PLATFORM == 'linux' }}
shell: bash
run: |
strip bin/libgdsion.linux.*
chmod +x bin/libgdsion.linux.*
# macOS-specific steps.

- name: Prepare the binaries (macOS)
if: ${{ env.SCONS_PLATFORM == 'macos' }}
shell: bash
run: |
chmod +x bin/libgdsion.macos.*
- name: Set up codesign (macOS)
if: ${{ env.SCONS_PLATFORM == 'macos' && inputs.sign-extension }}
uses: ./.github/actions/sign-extension
with:
setup-env: true

apple-cert-base64: ${{ secrets.APPLE_CERT_BASE64 }}
apple-cert-password: ${{ secrets.APPLE_CERT_PASSWORD }}

- name: Sign the binaries (macOS, debug)
if: ${{ env.SCONS_PLATFORM == 'macos' && inputs.sign-extension }}
uses: ./.github/actions/sign-extension
with:
codesign: true
directory: bin
target-name: libgdsion.macos.template_debug.framework

apple-dev-id: ${{ secrets.APPLE_DEV_ID }}
apple-dev-app-id: ${{ secrets.APPLE_DEV_APP_ID }}
apple-dev-team-id: ${{ secrets.APPLE_DEV_TEAM_ID }}
apple-dev-password: ${{ secrets.APPLE_DEV_PASSWORD }}

- name: Sign the binaries (macOS, release)
if: ${{ env.SCONS_PLATFORM == 'macos' && inputs.sign-extension }}
uses: ./.github/actions/sign-extension
with:
codesign: true
directory: bin
target-name: libgdsion.macos.template_release.framework

apple-dev-id: ${{ secrets.APPLE_DEV_ID }}
apple-dev-app-id: ${{ secrets.APPLE_DEV_APP_ID }}
apple-dev-team-id: ${{ secrets.APPLE_DEV_TEAM_ID }}
apple-dev-password: ${{ secrets.APPLE_DEV_PASSWORD }}

# Windows-specific steps.

- name: Prepare the binaries (Windows)
if: ${{ env.SCONS_PLATFORM == 'windows' }}
shell: powershell
run: |
Remove-Item bin/* -Include *.exp,*.lib,*.pdb -Force
# Common final steps.

- name: Upload the binaries as an artifact
uses: actions/upload-artifact@v4
with:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build-release-tagged.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ jobs:
uses: ./.github/workflows/extension-build-macos.yml
with:
git-base-ref: ${{ github.ref }}
with-codesign: true

build-windows:
name: Compile and upload Windows version
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build-release-unstable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
uses: ./.github/workflows/extension-build-macos.yml
with:
git-base-ref: 'main'
with-codesign: true

build-windows:
name: Compile and upload Windows version
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/extension-build-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
git-base-ref:
type: string
default: 'main'
with-codesign:
type: boolean
default: false

# Make sure jobs cannot overlap.
concurrency:
Expand Down Expand Up @@ -44,3 +47,5 @@ jobs:

- name: Upload release
uses: ./.github/actions/upload-extension
with:
sign-extension: ${{ inputs.with-codesign }}

0 comments on commit d36110e

Please sign in to comment.