Path: blob/main/build/azure-pipelines/darwin/product-build-darwin.yml
3520 views
parameters:1- name: VSCODE_ARCH2type: string3- name: VSCODE_CIBUILD4type: boolean5- name: VSCODE_RUN_ELECTRON_TESTS6type: boolean7default: false8- name: VSCODE_RUN_BROWSER_TESTS9type: boolean10default: false11- name: VSCODE_RUN_REMOTE_TESTS12type: boolean13default: false14- name: VSCODE_TEST_ARTIFACT_NAME15type: string16default: ""1718steps:19- template: ../common/checkout.yml@self2021- task: NodeTool@022inputs:23versionSource: fromFile24versionFilePath: .nvmrc2526- template: ../distro/download-distro.yml@self2728- task: AzureKeyVault@229displayName: "Azure Key Vault: Get Secrets"30inputs:31azureSubscription: vscode32KeyVaultName: vscode-build-secrets33SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key"3435- task: DownloadPipelineArtifact@236inputs:37artifact: Compilation38path: $(Build.ArtifactStagingDirectory)39displayName: Download compilation output4041- script: tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz42displayName: Extract compilation output4344- script: node build/setup-npm-registry.js $NPM_REGISTRY45condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none'))46displayName: Setup NPM Registry4748- script: mkdir -p .build && node build/azure-pipelines/common/computeNodeModulesCacheKey.js darwin $VSCODE_ARCH $(node -p process.arch) > .build/packagelockhash49displayName: Prepare node_modules cache key5051- task: Cache@252inputs:53key: '"node_modules" | .build/packagelockhash'54path: .build/node_modules_cache55cacheHitVar: NODE_MODULES_RESTORED56displayName: Restore node_modules cache5758- script: tar -xzf .build/node_modules_cache/cache.tgz59condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))60displayName: Extract node_modules cache6162- script: |63set -e64# Set the private NPM registry to the global npmrc file65# so that authentication works for subfolders like build/, remote/, extensions/ etc66# which does not have their own .npmrc file67npm config set registry "$NPM_REGISTRY"68echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)"69condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none'))70displayName: Setup NPM7172- task: npmAuthenticate@073inputs:74workingFile: $(NPMRC_PATH)75condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none'))76displayName: Setup NPM Authentication7778- script: |79set -e80c++ --version81xcode-select -print-path82python3 -m pip install setuptools8384for i in {1..5}; do # try 5 times85npm ci && break86if [ $i -eq 5 ]; then87echo "Npm install failed too many times" >&288exit 189fi90echo "Npm install failed $i, trying again..."91done92env:93npm_config_arch: $(VSCODE_ARCH)94ELECTRON_SKIP_BINARY_DOWNLOAD: 195PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 196GITHUB_TOKEN: "$(github-distro-mixin-password)"97# Avoid using dlopen to load Kerberos on macOS which can cause missing libraries98# https://github.com/mongodb-js/kerberos/commit/04044d2814ad1d01e77f1ce87f26b03d86692cf299# flipped the default to support legacy linux distros which shouldn't happen100# on macOS.101GYP_DEFINES: "kerberos_use_rtld=false"102displayName: Install dependencies103condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))104105- script: node build/azure-pipelines/distro/mixin-npm106condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))107displayName: Mixin distro node modules108109- script: |110set -e111node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt112mkdir -p .build/node_modules_cache113tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt114condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))115displayName: Create node_modules archive116117- script: node build/azure-pipelines/distro/mixin-quality118displayName: Mixin distro quality119120- template: ../common/install-builtin-extensions.yml@self121122- ${{ if ne(parameters.VSCODE_CIBUILD, true) }}:123- script: node build/lib/policies darwin124displayName: Generate policy definitions125retryCountOnTaskFailure: 3126127- script: |128set -e129npm run gulp vscode-darwin-$(VSCODE_ARCH)-min-ci130echo "##vso[task.setvariable variable=BUILT_CLIENT]true"131env:132GITHUB_TOKEN: "$(github-distro-mixin-password)"133displayName: Build client134135- script: |136set -e137npm run gulp vscode-reh-darwin-$(VSCODE_ARCH)-min-ci138mv ../vscode-reh-darwin-$(VSCODE_ARCH) ../vscode-server-darwin-$(VSCODE_ARCH) # TODO@joaomoreno139ARCHIVE_PATH=".build/darwin/server/vscode-server-darwin-$(VSCODE_ARCH).zip"140mkdir -p $(dirname $ARCHIVE_PATH)141(cd .. && zip -Xry $(Build.SourcesDirectory)/$ARCHIVE_PATH vscode-server-darwin-$(VSCODE_ARCH))142echo "##vso[task.setvariable variable=SERVER_PATH]$ARCHIVE_PATH"143env:144GITHUB_TOKEN: "$(github-distro-mixin-password)"145displayName: Build server146147- script: |148set -e149npm run gulp vscode-reh-web-darwin-$(VSCODE_ARCH)-min-ci150mv ../vscode-reh-web-darwin-$(VSCODE_ARCH) ../vscode-server-darwin-$(VSCODE_ARCH)-web # TODO@joaomoreno151ARCHIVE_PATH=".build/darwin/server/vscode-server-darwin-$(VSCODE_ARCH)-web.zip"152mkdir -p $(dirname $ARCHIVE_PATH)153(cd .. && zip -Xry $(Build.SourcesDirectory)/$ARCHIVE_PATH vscode-server-darwin-$(VSCODE_ARCH)-web)154echo "##vso[task.setvariable variable=WEB_PATH]$ARCHIVE_PATH"155env:156GITHUB_TOKEN: "$(github-distro-mixin-password)"157displayName: Build server (web)158159- ${{ if ne(parameters.VSCODE_CIBUILD, true) }}:160- task: DownloadPipelineArtifact@2161inputs:162artifact: unsigned_vscode_cli_darwin_$(VSCODE_ARCH)_cli163patterns: "**"164path: $(Build.ArtifactStagingDirectory)/cli165displayName: Download VS Code CLI166167- script: |168set -e169APP_ROOT="$(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH)"170APP_NAME="`ls $APP_ROOT | head -n 1`"171APP_PATH="$APP_ROOT/$APP_NAME"172unzip $(Build.ArtifactStagingDirectory)/cli/*.zip -d $(Build.ArtifactStagingDirectory)/cli173CLI_APP_NAME=$(node -p "require(\"$APP_PATH/Contents/Resources/app/product.json\").tunnelApplicationName")174APP_NAME=$(node -p "require(\"$APP_PATH/Contents/Resources/app/product.json\").applicationName")175mv "$(Build.ArtifactStagingDirectory)/cli/$APP_NAME" "$APP_PATH/Contents/Resources/app/bin/$CLI_APP_NAME"176chmod +x "$APP_PATH/Contents/Resources/app/bin/$CLI_APP_NAME"177displayName: Make CLI executable178179- script: |180set -e181APP_ROOT="$(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH)"182APP_NAME="`ls $APP_ROOT | head -n 1`"183APP_PATH="$APP_ROOT/$APP_NAME" node build/darwin/verify-macho.js $(VSCODE_ARCH)184APP_PATH="$(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH)" node build/darwin/verify-macho.js $(VSCODE_ARCH)185displayName: Verify arch of Mach-O objects186187- script: |188set -e189ARCHIVE_PATH="$(Pipeline.Workspace)/unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive/VSCode-darwin-$(VSCODE_ARCH).zip"190mkdir -p $(dirname $ARCHIVE_PATH)191(cd ../VSCode-darwin-$(VSCODE_ARCH) && zip -Xry $ARCHIVE_PATH *)192echo "##vso[task.setvariable variable=CLIENT_PATH]$ARCHIVE_PATH"193condition: and(succeededOrFailed(), eq(variables['BUILT_CLIENT'], 'true'))194displayName: Package client195196- pwsh: node build/azure-pipelines/common/checkForArtifact.js CLIENT_ARCHIVE_UPLOADED unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive197env:198SYSTEM_ACCESSTOKEN: $(System.AccessToken)199displayName: Check for client artifact200201- template: ../common/publish-artifact.yml@self202parameters:203targetPath: $(CLIENT_PATH)204artifactName: unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive205displayName: Publish client archive (unsigned)206sbomBuildDropPath: $(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH)207sbomPackageName: "VS Code macOS $(VSCODE_ARCH) (unsigned)"208sbomPackageVersion: $(Build.SourceVersion)209condition: and(succeeded(), ne(variables['CLIENT_PATH'], ''), eq(variables['CLIENT_ARCHIVE_UPLOADED'], 'false'))210211# Hardened entitlements should be set after publishing unsigned client artifacts212# to ensure entitlement signing doesn't modify sha that would affect universal build.213#214# Setting hardened entitlements is a requirement for:215# * Apple notarization216# * Running tests on Big Sur (because Big Sur has additional security precautions)217- script: |218set -e219security create-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain220security default-keychain -s $(agent.tempdirectory)/buildagent.keychain221security unlock-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain222echo "$(macos-developer-certificate)" | base64 -D > $(agent.tempdirectory)/cert.p12223security import $(agent.tempdirectory)/cert.p12 -k $(agent.tempdirectory)/buildagent.keychain -P "$(macos-developer-certificate-key)" -T /usr/bin/codesign224export CODESIGN_IDENTITY=$(security find-identity -v -p codesigning $(agent.tempdirectory)/buildagent.keychain | grep -oEi "([0-9A-F]{40})" | head -n 1)225security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $(agent.tempdirectory)/buildagent.keychain226DEBUG=electron-osx-sign* node build/darwin/sign.js $(agent.builddirectory)227displayName: Set Hardened Entitlements228229- script: |230set -e231ARCHIVE_PATH="$(Pipeline.Workspace)/vscode_client_darwin_$(VSCODE_ARCH)_archive/VSCode-darwin-$(VSCODE_ARCH).zip"232mkdir -p $(dirname $ARCHIVE_PATH)233(cd ../VSCode-darwin-$(VSCODE_ARCH) && zip -Xry $ARCHIVE_PATH *)234echo "##vso[task.setvariable variable=CLIENT_PATH]$ARCHIVE_PATH"235condition: and(succeededOrFailed(), eq(variables['BUILT_CLIENT'], 'true'))236displayName: Re-package client after entitlement237238- task: UseDotNet@2239inputs:240version: 6.x241242- task: EsrpCodeSigning@5243inputs:244UseMSIAuthentication: true245ConnectedServiceName: vscode-esrp246AppRegistrationClientId: $(ESRP_CLIENT_ID)247AppRegistrationTenantId: $(ESRP_TENANT_ID)248AuthAKVName: vscode-esrp249AuthSignCertName: esrp-sign250FolderPath: .251Pattern: noop252displayName: 'Install ESRP Tooling'253254- pwsh: |255. build/azure-pipelines/win32/exec.ps1256$ErrorActionPreference = "Stop"257$EsrpCodeSigningTool = (gci -directory -filter EsrpCodeSigning_* $(Agent.RootDirectory)/_tasks | Select-Object -last 1).FullName258$Version = (gci -directory $EsrpCodeSigningTool | Select-Object -last 1).FullName259echo "##vso[task.setvariable variable=EsrpCliDllPath]$Version/net6.0/esrpcli.dll"260displayName: Find ESRP CLI261262- script: npx deemon --detach --wait node build/azure-pipelines/darwin/codesign.js263env:264EsrpCliDllPath: $(EsrpCliDllPath)265SYSTEM_ACCESSTOKEN: $(System.AccessToken)266displayName: ✍️ Codesign & Notarize267268- ${{ if or(eq(parameters.VSCODE_RUN_ELECTRON_TESTS, true), eq(parameters.VSCODE_RUN_BROWSER_TESTS, true), eq(parameters.VSCODE_RUN_REMOTE_TESTS, true)) }}:269- template: product-build-darwin-test.yml@self270parameters:271VSCODE_TEST_ARTIFACT_NAME: ${{ parameters.VSCODE_TEST_ARTIFACT_NAME }}272VSCODE_RUN_ELECTRON_TESTS: ${{ parameters.VSCODE_RUN_ELECTRON_TESTS }}273VSCODE_RUN_BROWSER_TESTS: ${{ parameters.VSCODE_RUN_BROWSER_TESTS }}274VSCODE_RUN_REMOTE_TESTS: ${{ parameters.VSCODE_RUN_REMOTE_TESTS }}275276- ${{ if ne(parameters.VSCODE_CIBUILD, true) }}:277- script: npx deemon --attach node build/azure-pipelines/darwin/codesign.js278condition: succeededOrFailed()279displayName: "Post-job: ✍️ Codesign & Notarize"280281- script: unzip $(Pipeline.Workspace)/vscode_client_darwin_$(VSCODE_ARCH)_archive/VSCode-darwin-$(VSCODE_ARCH).zip -d $(Build.ArtifactStagingDirectory)/VSCode-darwin-$(VSCODE_ARCH)282displayName: Extract signed app283284- script: |285set -e286APP_ROOT="$(Build.ArtifactStagingDirectory)/VSCode-darwin-$(VSCODE_ARCH)"287APP_NAME="`ls $APP_ROOT | head -n 1`"288APP_PATH="$APP_ROOT/$APP_NAME"289codesign -dv --deep --verbose=4 "$APP_PATH"290"$APP_PATH/Contents/Resources/app/bin/code" --export-default-configuration=.build291displayName: Verify signature292293- script: mv $(Pipeline.Workspace)/vscode_client_darwin_$(VSCODE_ARCH)_archive/VSCode-darwin-x64.zip $(Pipeline.Workspace)/vscode_client_darwin_$(VSCODE_ARCH)_archive/VSCode-darwin.zip294displayName: Rename x64 build to its legacy name295condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'))296297- template: ../common/publish-artifact.yml@self298parameters:299${{ if eq(parameters.VSCODE_ARCH, 'arm64') }}:300targetPath: $(Pipeline.Workspace)/vscode_client_darwin_$(VSCODE_ARCH)_archive/VSCode-darwin-arm64.zip301${{ else }}:302targetPath: $(Pipeline.Workspace)/vscode_client_darwin_$(VSCODE_ARCH)_archive/VSCode-darwin.zip303artifactName: vscode_client_darwin_$(VSCODE_ARCH)_archive304displayName: Publish client archive305sbomBuildDropPath: $(Build.ArtifactStagingDirectory)/VSCode-darwin-$(VSCODE_ARCH)306sbomPackageName: "VS Code macOS $(VSCODE_ARCH)"307sbomPackageVersion: $(Build.SourceVersion)308309- script: echo "##vso[task.setvariable variable=ARTIFACT_PREFIX]attempt$(System.JobAttempt)_"310condition: and(succeededOrFailed(), notIn(variables['Agent.JobStatus'], 'Succeeded', 'SucceededWithIssues'))311displayName: Generate artifact prefix312313- template: ../common/publish-artifact.yml@self314parameters:315targetPath: $(SERVER_PATH)316artifactName: $(ARTIFACT_PREFIX)vscode_server_darwin_$(VSCODE_ARCH)_archive-unsigned317displayName: Publish server archive318sbomBuildDropPath: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH)319sbomPackageName: "VS Code macOS $(VSCODE_ARCH) Server"320sbomPackageVersion: $(Build.SourceVersion)321condition: and(succeededOrFailed(), ne(variables['SERVER_PATH'], ''))322323- template: ../common/publish-artifact.yml@self324parameters:325targetPath: $(WEB_PATH)326artifactName: $(ARTIFACT_PREFIX)vscode_web_darwin_$(VSCODE_ARCH)_archive-unsigned327displayName: Publish web server archive328sbomBuildDropPath: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH)-web329sbomPackageName: "VS Code macOS $(VSCODE_ARCH) Web"330sbomPackageVersion: $(Build.SourceVersion)331condition: and(succeededOrFailed(), ne(variables['WEB_PATH'], ''))332333334