Skip to content

Commit d218b53

Browse files
authored
chore(ci): Sign XCFrameworks with OneSignal identity and improve manifest updates (#1676)
1 parent ec44204 commit d218b53

3 files changed

Lines changed: 118 additions & 39 deletions

File tree

.github/workflows/create-release-prs.yml

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,20 @@ jobs:
4444
BASE_BRANCH: ${{ github.event.inputs.base_branch }}
4545
RELEASE_BRANCH: ${{ needs.prep.outputs.release_branch }}
4646
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
47+
# Single source of truth for the XCFrameworks the Code Sign and Verify steps
48+
# operate on (paths relative to iOS_SDK/OneSignalSDK). Keep in sync with the
49+
# frameworks built by build_all_frameworks.sh.
50+
XCFRAMEWORKS: >-
51+
OneSignal_Core/OneSignalCore.xcframework
52+
OneSignal_OSCore/OneSignalOSCore.xcframework
53+
OneSignal_Outcomes/OneSignalOutcomes.xcframework
54+
OneSignal_Extension/OneSignalExtension.xcframework
55+
OneSignal_Notifications/OneSignalNotifications.xcframework
56+
OneSignal_User/OneSignalUser.xcframework
57+
OneSignal_LiveActivities/OneSignalLiveActivities.xcframework
58+
OneSignal_Location/OneSignalLocation.xcframework
59+
OneSignal_InAppMessages/OneSignalInAppMessages.xcframework
60+
OneSignal_XCFramework/OneSignalFramework.xcframework
4761
4862
steps:
4963
- name: 📋 Display Configuration
@@ -75,21 +89,13 @@ jobs:
7589
with:
7690
xcode-version: "15.2"
7791

78-
- name: Install the Apple distribution certificate and provisioning profile (OneSignal)
92+
- name: Install the Apple distribution certificate (OneSignal)
7993
uses: apple-actions/import-codesign-certs@v2
8094
with:
8195
keychain-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
8296
p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
8397
p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
8498

85-
- name: Install the Apple distribution certificate and provisioning profile (Lilomi)
86-
uses: apple-actions/import-codesign-certs@v2
87-
with:
88-
create-keychain: false # do not create a new keychain for this value
89-
keychain-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
90-
p12-file-base64: ${{ secrets.DEV_CERTIFICATES_P12 }}
91-
p12-password: ${{ secrets.DEV_CERTIFICATES_P12_PASSWORD }}
92-
9399
- name: Update Version in SDK and Podspec Files
94100
run: |
95101
cd iOS_SDK/OneSignalSDK
@@ -112,16 +118,41 @@ jobs:
112118
- name: Code Sign
113119
run: |
114120
cd iOS_SDK/OneSignalSDK
115-
codesign --timestamp -v --sign "Apple Distribution: OneSignal, Inc. (J3J28YJX9L)" OneSignal_Core/OneSignalCore.xcframework
116-
codesign --timestamp -v --sign "Apple Distribution: OneSignal, Inc. (J3J28YJX9L)" OneSignal_Extension/OneSignalExtension.xcframework
117-
codesign --timestamp -v --sign "Apple Distribution: OneSignal, Inc. (J3J28YJX9L)" OneSignal_InAppMessages/OneSignalInAppMessages.xcframework
118-
codesign --timestamp -v --sign "Apple Distribution: OneSignal, Inc. (J3J28YJX9L)" OneSignal_Location/OneSignalLocation.xcframework
119-
codesign --timestamp -v --sign "Apple Distribution: OneSignal, Inc. (J3J28YJX9L)" OneSignal_Notifications/OneSignalNotifications.xcframework
120-
codesign --timestamp -v --sign "Apple Distribution: OneSignal, Inc. (J3J28YJX9L)" OneSignal_OSCore/OneSignalOSCore.xcframework
121-
codesign --timestamp -v --sign "Apple Distribution: OneSignal, Inc. (J3J28YJX9L)" OneSignal_Outcomes/OneSignalOutcomes.xcframework
122-
codesign --timestamp -v --sign "Apple Distribution: OneSignal, Inc. (J3J28YJX9L)" OneSignal_User/OneSignalUser.xcframework
123-
codesign --timestamp -v --sign "Apple Distribution: OneSignal, Inc. (J3J28YJX9L)" OneSignal_XCFramework/OneSignalFramework.xcframework
124-
codesign --timestamp -v --sign "Apple Distribution: OneSignal, Inc. (J3J28YJX9L)" OneSignal_LiveActivities/OneSignalLiveActivities.xcframework
121+
set -e
122+
IDENTITY="Apple Distribution: OneSignal, Inc. (J3J28YJX9L)"
123+
for XCF in $XCFRAMEWORKS; do
124+
# Sign inside-out: each slice's .framework binary first, then the
125+
# .xcframework wrapper. -f replaces the linker's ad-hoc signature left
126+
# by the unsigned archive build, so both inner and outer end up signed
127+
# with the official OneSignal Apple Distribution identity.
128+
while IFS= read -r FW; do
129+
echo "Signing inner framework: $FW"
130+
codesign --timestamp -f -v --sign "$IDENTITY" "$FW"
131+
done < <(find "$XCF" -type d -name "*.framework")
132+
echo "Signing wrapper: $XCF"
133+
codesign --timestamp -f -v --sign "$IDENTITY" "$XCF"
134+
done
135+
shell: bash
136+
137+
- name: Verify Code Signing
138+
run: |
139+
cd iOS_SDK/OneSignalSDK
140+
set -e
141+
# Fail the release if any slice or wrapper is tampered/unsigned or not
142+
# signed by the OneSignal team. --deep is unreliable across xcframework
143+
# slices, so each inner .framework is verified explicitly.
144+
REQUIREMENT="anchor apple generic and certificate leaf[subject.OU] = J3J28YJX9L"
145+
for XCF in $XCFRAMEWORKS; do
146+
while IFS= read -r FW; do
147+
echo "Verifying inner framework: $FW"
148+
codesign --verify --strict --verbose=2 "$FW"
149+
codesign --verify -R="$REQUIREMENT" "$FW"
150+
done < <(find "$XCF" -type d -name "*.framework")
151+
echo "Verifying wrapper: $XCF"
152+
codesign --verify --strict --verbose=2 "$XCF"
153+
codesign --verify -R="$REQUIREMENT" "$XCF"
154+
done
155+
echo "All XCFrameworks verified: intact and signed by OneSignal (J3J28YJX9L)."
125156
shell: bash
126157

127158
- name: Commit Build and Push Changes

iOS_SDK/OneSignalSDK/build_all_frameworks.sh

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,17 @@ create_xcframework() {
2626

2727
xcodebuild -list
2828

29-
xcodebuild archive ONLY_ACTIVE_ARCH=NO -scheme ${BUILD_SCHEME} -destination="generic/platform=iOS Simulator" -archivePath "${SIMULATOR_ARCHIVE_PATH}" -sdk iphonesimulator SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
29+
# Note: code signing is disabled here. These are distribution XCFrameworks
30+
# that are signed afterward with the Apple Distribution cert in the workflow's
31+
# "Code Sign" step, so the archive itself does not need to be signed. This also
32+
# avoids depending on the project's baked-in DEVELOPMENT_TEAM / dev certificate.
33+
CODE_SIGN_FLAGS="CODE_SIGN_IDENTITY= CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO"
3034

31-
xcodebuild archive -scheme ${BUILD_SCHEME} -destination="generic/platform=iOS" -archivePath "${IOS_DEVICE_ARCHIVE_PATH}" -sdk iphoneos SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
35+
xcodebuild archive ONLY_ACTIVE_ARCH=NO -scheme ${BUILD_SCHEME} -destination="generic/platform=iOS Simulator" -archivePath "${SIMULATOR_ARCHIVE_PATH}" -sdk iphonesimulator SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES ${CODE_SIGN_FLAGS}
3236

33-
xcodebuild archive -scheme ${BUILD_SCHEME} -destination='generic/platform=macOS,variant=Mac Catalyst' -archivePath "${CATALYST_ARCHIVE_PATH}" SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
37+
xcodebuild archive -scheme ${BUILD_SCHEME} -destination="generic/platform=iOS" -archivePath "${IOS_DEVICE_ARCHIVE_PATH}" -sdk iphoneos SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES ${CODE_SIGN_FLAGS}
38+
39+
xcodebuild archive -scheme ${BUILD_SCHEME} -destination='generic/platform=macOS,variant=Mac Catalyst' -archivePath "${CATALYST_ARCHIVE_PATH}" SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES ${CODE_SIGN_FLAGS}
3440

3541
xcodebuild -create-xcframework -framework ${SIMULATOR_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework -debug-symbols ${SIMULATOR_ARCHIVE_PATH}/dSYMs/${FRAMEWORK_NAME}.framework.dSYM -framework ${IOS_DEVICE_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework -debug-symbols ${IOS_DEVICE_ARCHIVE_PATH}/dSYMs/${FRAMEWORK_NAME}.framework.dSYM -framework ${CATALYST_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework -debug-symbols ${CATALYST_ARCHIVE_PATH}/dSYMs/${FRAMEWORK_NAME}.framework.dSYM -output "${FRAMEWORK_PATH}"
3642
rm -rf "${SIMULATOR_ARCHIVE_PATH}"

iOS_SDK/OneSignalSDK/update_swift_package.sh

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ WORKING_DIR=$(pwd)
88
# read VERSION_NUMBER
99
VERSION_NUMBER=$1
1010

11+
if [ -z "${VERSION_NUMBER}" ]; then
12+
echo "ERROR: release version argument is required (usage: $0 <version>)" >&2
13+
exit 1
14+
fi
15+
1116
update_framework() {
1217
FRAMEWORK_FOLDER_NAME=$1
1318

@@ -36,43 +41,80 @@ update_framework() {
3641
# Compute the checksum for the Zipped framework
3742
echo "Computing package checksum and updating Package.swift ${SWIFT_PACKAGE_PATH}"
3843
CHECKSUM=$(swift package compute-checksum "${FRAMEWORK_ZIP_PATH}")
39-
SWIFT_PM_CHECKSUM_LINE=" checksum: \"${CHECKSUM}\""
40-
41-
# Use sed to remove line from the Swift.package and replace it with the new checksum
42-
sed -i '' "$3s/.*/$SWIFT_PM_CHECKSUM_LINE/" "${SWIFT_PACKAGE_PATH}"
43-
SWIFT_PM_URL_LINE=" url: \"https:\/\/github.com\/OneSignal\/OneSignal-iOS-SDK\/releases\/download\/${VERSION_NUMBER}\/${FRAMEWORK_NAME}.xcframework.zip\","
44-
#Use sed to remove line from the Swift.package and replace it with the new URL for the new release
45-
sed -i '' "$4s/.*/$SWIFT_PM_URL_LINE/" "${SWIFT_PACKAGE_PATH}"
44+
if [ -z "${CHECKSUM}" ]; then
45+
echo "ERROR: empty checksum computed for ${FRAMEWORK_NAME}" >&2
46+
exit 1
47+
fi
48+
# Update this framework's .binaryTarget in place, located by the framework
49+
# name in its url line (NOT by hardcoded line number). Only the version in the
50+
# url and the hash in the following checksum line are rewritten; surrounding
51+
# structure/formatting is preserved. Matching by name keeps this correct even
52+
# when the manifest layout shifts -- the previous line-number approach silently
53+
# corrupted Package.swift once unrelated lines moved (broke 5.5.2 SPM).
54+
awk -v fw="${FRAMEWORK_NAME}" -v ver="${VERSION_NUMBER}" -v chk="${CHECKSUM}" '
55+
# This framework'"'"'s url line: bump only the version path segment.
56+
$0 ~ ("url: \"https://github.com/OneSignal/OneSignal-iOS-SDK/releases/download/[^/]*/" fw "\\.xcframework\\.zip\"") {
57+
sub("download/[^/]*/", "download/" ver "/")
58+
print
59+
expect_checksum = 1
60+
next
61+
}
62+
# The checksum must sit on the line IMMEDIATELY after that url (the
63+
# well-formed .binaryTarget layout). Only that one line is eligible, so a
64+
# reordered/stray/renamed checksum line can never be clobbered: if it is not
65+
# a checksum line nothing is rewritten and the post-run guard fails loudly.
66+
expect_checksum {
67+
expect_checksum = 0
68+
if ($0 ~ /^[[:space:]]*checksum: "[0-9a-fA-F]*"[[:space:]]*$/) {
69+
sub("checksum: \"[0-9a-fA-F]*\"", "checksum: \"" chk "\"")
70+
}
71+
print
72+
next
73+
}
74+
{ print }
75+
' "${SWIFT_PACKAGE_PATH}" > "${SWIFT_PACKAGE_PATH}.tmp"
76+
mv "${SWIFT_PACKAGE_PATH}.tmp" "${SWIFT_PACKAGE_PATH}"
77+
78+
# Fail loudly if the entry was not found/updated, instead of silently leaving
79+
# the manifest stale or malformed.
80+
if ! grep -q "releases/download/${VERSION_NUMBER}/${FRAMEWORK_NAME}.xcframework.zip" "${SWIFT_PACKAGE_PATH}"; then
81+
echo "ERROR: could not find/update url for ${FRAMEWORK_NAME} in Package.swift" >&2
82+
exit 1
83+
fi
84+
if ! grep -q "checksum: \"${CHECKSUM}\"" "${SWIFT_PACKAGE_PATH}"; then
85+
echo "ERROR: could not update checksum for ${FRAMEWORK_NAME} in Package.swift" >&2
86+
exit 1
87+
fi
4688
#Open XCFramework folder to drag zip into new release
4789
open "${WORKING_DIR}/${FRAMEWORK_FOLDER_NAME}"
4890
}
4991

5092
## OneSignal LiveActivities ##
51-
update_framework "OneSignal_LiveActivities" "OneSignalLiveActivities" "163" "162"
93+
update_framework "OneSignal_LiveActivities" "OneSignalLiveActivities"
5294

5395
## OneSignal Core ##
54-
update_framework "OneSignal_Core" "OneSignalCore" "158" "157"
96+
update_framework "OneSignal_Core" "OneSignalCore"
5597

5698
## OneSignal OSCore ##
57-
update_framework "OneSignal_OSCore" "OneSignalOSCore" "153" "152"
99+
update_framework "OneSignal_OSCore" "OneSignalOSCore"
58100

59101
## OneSignal Outcomes ##
60-
update_framework "OneSignal_Outcomes" "OneSignalOutcomes" "148" "147"
102+
update_framework "OneSignal_Outcomes" "OneSignalOutcomes"
61103

62104
## OneSignal Extension ##
63-
update_framework "OneSignal_Extension" "OneSignalExtension" "143" "142"
105+
update_framework "OneSignal_Extension" "OneSignalExtension"
64106

65107
## OneSignal Notifications ##
66-
update_framework "OneSignal_Notifications" "OneSignalNotifications" "138" "137"
108+
update_framework "OneSignal_Notifications" "OneSignalNotifications"
67109

68110
## OneSignal User ##
69-
update_framework "OneSignal_User" "OneSignalUser" "133" "132"
111+
update_framework "OneSignal_User" "OneSignalUser"
70112

71113
## OneSignal Location ##
72-
update_framework "OneSignal_Location" "OneSignalLocation" "128" "127"
114+
update_framework "OneSignal_Location" "OneSignalLocation"
73115

74116
## OneSignal InAppMessages ##
75-
update_framework "OneSignal_InAppMessages" "OneSignalInAppMessages" "123" "122"
117+
update_framework "OneSignal_InAppMessages" "OneSignalInAppMessages"
76118

77119
## OneSignal ##
78-
update_framework "OneSignal_XCFramework" "OneSignalFramework" "118" "117"
120+
update_framework "OneSignal_XCFramework" "OneSignalFramework"

0 commit comments

Comments
 (0)