Skip to content
8 changes: 5 additions & 3 deletions .azure-pipelines/1ES.Build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,12 @@ extends:
ESRPInfo: ${{ parameters.ESRPInfo }}

# macOS uses a separate template because it runs on a different
# pool (Microsoft-hosted) and skips ESRP signing / cross-compile
# plumbing. The produced artifact name follows the same scheme
# (mxc-binaries-<triplet>) so Package_MXC_NPM_SDK can consume it.
# pool (Microsoft-hosted). The produced artifact name follows the same
# scheme (mxc-binaries-<triplet>) so Package_MXC_NPM_SDK can consume it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think Package_MXC_NPM_SDK is now just Package_MXC

- template: .azure-pipelines/templates/Mac.Build.Job.yml@self
parameters:
isOfficialBuild: ${{ eq(parameters.officialBuild, 'Official') }}
ESRPInfo: ${{ parameters.ESRPInfo }}

- stage: Package_MXC
displayName: 'Package MXC'
Expand Down
83 changes: 83 additions & 0 deletions .azure-pipelines/templates/Mac.Build.Job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ parameters:
- name: triplet
type: string
default: aarch64-apple-darwin
- name: isOfficialBuild
type: boolean
default: false
- name: ESRPInfo
type: object
default: {}

jobs:
- job: 'build_arm64_MAC'
Expand Down Expand Up @@ -82,6 +88,83 @@ jobs:
displayName: Run tests
workingDirectory: $(workingDirectory)

# --- macOS Code Signing + Notarization (official builds only) ---
# ESRP handles the full signing flow using Microsoft's Developer ID
# certificate (CP-401337-Apple). No local cert or codesign needed.
#
# ESRP's Mac signing requires a .zip (or .dmg) input β€” raw Mach-O
# binaries are rejected. We zip before signing and unzip afterward.
#
# Flow: (1) zip β†’ (2) ESRP sign (hardened runtime) β†’ (3) ESRP notarize β†’ (4) unzip
# Stapling is impossible for standalone Mach-O binaries (Apple limitation);
# Gatekeeper checks the notarization ticket online instead.
- script: |
cd "$(targetTripleDir)"
zip mxc-exec-mac.zip mxc-exec-mac
displayName: 'Zip binary for ESRP signing'
condition: and(succeeded(), eq(${{ parameters.isOfficialBuild }}, true))

- task: EsrpCodeSigning@5
displayName: 'Sign macOS binary (ESRP)'
condition: and(succeeded(), eq(${{ parameters.isOfficialBuild }}, true))
inputs:
ConnectedServiceName: ${{ parameters.ESRPInfo.serviceName }}
AppRegistrationClientId: ${{ parameters.ESRPInfo.clientId }}
AppRegistrationTenantId: ${{ parameters.ESRPInfo.tenantId }}
AuthAKVName: ${{ parameters.ESRPInfo.azureKeyVaultName }}
AuthCertName: ${{ parameters.ESRPInfo.authCertName }}
AuthSignCertName: ${{ parameters.ESRPInfo.signCertName }}
FolderPath: $(targetTripleDir)
Pattern: mxc-exec-mac.zip
UseMinimatch: true
signConfigType: 'inlineSignParams'
inlineOperation: >-
[
{
"KeyCode": "CP-401337-Apple",
"OperationCode": "MacAppDeveloperSign",
"Parameters": {
"Hardening": "--options=runtime"
},
"ToolName": "sign",
"ToolVersion": "1.0"
}
]

- task: EsrpCodeSigning@5
displayName: 'Notarize macOS binary (ESRP)'
condition: and(succeeded(), eq(${{ parameters.isOfficialBuild }}, true))
inputs:
ConnectedServiceName: ${{ parameters.ESRPInfo.serviceName }}
AppRegistrationClientId: ${{ parameters.ESRPInfo.clientId }}
AppRegistrationTenantId: ${{ parameters.ESRPInfo.tenantId }}
AuthAKVName: ${{ parameters.ESRPInfo.azureKeyVaultName }}
AuthCertName: ${{ parameters.ESRPInfo.authCertName }}
AuthSignCertName: ${{ parameters.ESRPInfo.signCertName }}
FolderPath: $(targetTripleDir)
Pattern: mxc-exec-mac.zip
UseMinimatch: true
signConfigType: 'inlineSignParams'
inlineOperation: >-
[
{
"KeyCode": "CP-401337-Apple",
"OperationCode": "MacAppNotarize",
"Parameters": {
"BundleId": "com.microsoft.mxc"
},
"ToolName": "sign",
"ToolVersion": "1.0"
}
]

- script: |
cd "$(targetTripleDir)"
unzip -o mxc-exec-mac.zip
rm mxc-exec-mac.zip
displayName: 'Unzip signed binary'
condition: and(succeeded(), eq(${{ parameters.isOfficialBuild }}, true))

- task: CopyFiles@2
displayName: Copy binary
inputs:
Expand Down
Loading