Created
February 20, 2024 17:05
-
-
Save softlion/cd25e99980d89c37b34f399945637bd8 to your computer and use it in GitHub Desktop.
Build a xamarin iOS app for release and publish it to testflight via AppCenter Distribute
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Xamarin.iOS | |
# Build a Xamarin.iOS project. | |
# Add steps that install certificates, test, sign, and distribute an app, save build artifacts, and more: | |
# https://docs.microsoft.com/azure/devops/pipelines/languages/xamarin | |
trigger: | |
- release/store | |
pool: | |
vmImage: 'macos-latest' | |
name: $(TeamProject)_$(SourceBranchName)_$(Rev:r) | |
variables: | |
outputDirectory: '$(build.binariesDirectory)/$(BuildConfiguration)' | |
steps: | |
- checkout: self | |
persistCredentials: true | |
clean: true | |
- script: | | |
echo "Build.SourceBranch: $(Build.SourceBranch)" | |
# To manually select a Xamarin SDK version on the Microsoft-hosted macOS agent, | |
# configure this task with the *Mono* version that is associated with the | |
# Xamarin SDK version that you need, and set the "enabled" property to true. | |
# See https://go.microsoft.com/fwlink/?linkid=871629 | |
- script: sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh 6_12_24 | |
displayName: 'Select the Xamarin SDK version' | |
enabled: true | |
- task: Bash@3 | |
displayName: 'Change some app features' | |
inputs: | |
targetType: 'inline' | |
failOnStderr: true | |
script: | | |
INFOPLIST_PATH="$(Build.SourcesDirectory)/MyApp/MyApp.iOS/info.plist" | |
#xamarin tooling adds "Production" automatically but does not remove "Development" ... So correct that. | |
ENTITLEMENTS_PATH="$(Build.SourcesDirectory)/MyApp/MyApp.iOS/Entitlements.plist" | |
/usr/libexec/PlistBuddy -c "Delete :com.apple.developer.icloud-container-environment" "$ENTITLEMENTS_PATH" | |
/usr/libexec/PlistBuddy -c "Add :com.apple.developer.icloud-container-environment string Production" "$ENTITLEMENTS_PATH" | |
#change some app features (app bundle name, app name, icon) | |
#when adhoc build is used, so adhoc and testflight apps can be installed side by side | |
BRANCH_NAME=${BUILD_SOURCEBRANCH##refs/heads/} | |
buildShift=0 | |
acSlug="" | |
#URL: https://openapi.appcenter.ms/#/distribute/stores_list | |
#API: /v0.1/apps/{owner_name}/{app_name}/distribution_stores | |
acStoreId="" | |
if [ "$BRANCH_NAME" = "release/xxx/store" ]; then | |
echo "xxx branch detected: changing some app features" | |
buildShift=750 | |
acSlug="MyApp-Xxx-iOS" | |
acStoreId="aabbccb0-aac2-bb6a-cc74-dd46440a3df2" | |
#change bundle name | |
plutil -replace CFBundleIdentifier -string "com.companyname.MyApp-xxx-iOS" "$INFOPLIST_PATH" | |
#change app name | |
plutil -replace CFBundleName -string "MyApp Xxx" "$INFOPLIST_PATH" | |
plutil -replace CFBundleDisplayName -string "MyApp xxx" "$INFOPLIST_PATH" | |
#/usr/libexec/PlistBuddy -c "Set :CFBundleURLTypes:0:CFBundleURLName com.companyname.MyApp-xxx-iOS" "$INFOPLIST_PATH" | |
#change app icon | |
plutil -replace XSAppIconAssets -string "Resources/MyAppXxx.xcassets/MyApp.appiconset" "$INFOPLIST_PATH" | |
#change the appcenter crash log id | |
sed -i '' 's/AppCenterIosKey = "[^"]*"/AppCenterIosKey = "aa36bb1e-cc80-dd11-ee0a-ffe830a1e787"/g' "$(Build.SourcesDirectory)/MyApp/MyApp.Data/Services/AppSettings.cs" | |
################## NORMAL | |
elif [ "$BRANCH_NAME" = "release/store" ]; then | |
echo "todo" | |
else | |
echo "Unknown branch '$BRANCH_NAME' detected, cancelling" | |
exit 1; | |
fi | |
build="$(Build.BuildNumber)" | |
build="${build##*_}" | |
build="$((build + buildShift))" | |
echo "Using build $build" | |
plutil -replace CFBundleVersion -string "$build" "$INFOPLIST_PATH" | |
echo "##vso[task.setvariable variable=BUILD_NUMBER]$build" | |
echo "##vso[task.setvariable variable=APPCENTER_SLUG]$acSlug" | |
echo "##vso[task.setvariable variable=APPCENTER_STOREID]$acStoreId" | |
- task: InstallAppleCertificate@2 | |
inputs: | |
certSecureFile: 'MyApp Store.p12' | |
certPwd: '$(CERT_PASSWORD)' | |
keychain: 'temp' | |
#for release/store branch | |
- task: InstallAppleProvisioningProfile@1 | |
condition: eq(variables['Build.SourceBranch'], 'refs/heads/release/store') | |
inputs: | |
provisioningProfileLocation: 'secureFiles' | |
provProfileSecureFile: 'MyApp_Normal_AppStore.mobileprovision' | |
#for release/xxx/store branch | |
- task: InstallAppleProvisioningProfile@1 | |
condition: eq(variables['Build.SourceBranch'], 'refs/heads/release/xxx/store') | |
inputs: | |
provisioningProfileLocation: 'secureFiles' | |
provProfileSecureFile: 'MyApp_Xxx_AppStore.mobileprovision' | |
- task: NuGetToolInstaller@1 | |
inputs: | |
versionSpec: ">=6.7.0" | |
- task: NuGetCommand@2 | |
inputs: | |
restoreSolution: '$(Build.SourcesDirectory)/MyApp.sln' | |
feedsToUse: config | |
#This task uses msbuild from mono, which is old. We need msbuild from VSMac. | |
#- task: XamariniOS@2 | |
# inputs: | |
# solutionFile: '$(Build.SourcesDirectory)/MyApp.sln' | |
# configuration: 'Release' | |
# packageApp: true | |
# runNugetRestore: false | |
#signIdentityEscaped below is required, as our apple signing certificate name contains a comma ...!!! | |
- task: Bash@3 | |
displayName: 'Build iOS IPA' | |
inputs: | |
targetType: 'inline' | |
failOnStderr: true | |
script: | | |
signIdentityEscaped=$(echo "$APPLE_CERTIFICATE_SIGNING_IDENTITY" | sed 's/,/%2C/g') | |
cmd=' | |
/Library/Frameworks/Mono.framework/Versions/Current/Commands/mono | |
"/Applications/Visual Studio.app/Contents/MonoBundle/MSBuild/Current/bin/MSBuild.dll" | |
"'"$(Build.SourcesDirectory)"'/MyApp.sln" | |
/t:Build | |
/p:Configuration=Release | |
/p:Platform=iPhone | |
/p:buildForSimulator=false | |
/p:BuildIpa=true | |
/p:Codesignkey="'"$signIdentityEscaped"'" | |
/p:CodesignProvision='"$APPLE_PROV_PROFILE_UUID"' | |
' | |
echo $cmd | |
eval $cmd | |
#- task: CopyFiles@2 | |
# inputs: | |
# SourceFolder: '$(Build.SourcesDirectory)/MyApp/iOS/bin/iPhone/Release' | |
# Contents: '*.ipa' | |
# TargetFolder: '$(Build.ArtifactStagingDirectory)' | |
#- task: PublishBuildArtifacts@1 | |
# inputs: | |
# PathtoPublish: '$(Build.ArtifactStagingDirectory)' | |
# ArtifactName: 'IPA' | |
# publishLocation: 'Container' | |
#see https://github.com/microsoft/azure-pipelines-tasks/blob/master/Tasks/AppCenterDistributeV3/task.json | |
- task: AppCenterDistribute@3 | |
displayName: 'Post IPA and Symbols to appcenter distribute' | |
condition: eq(variables['Build.SourceBranch'], 'refs/heads/release/store') | |
inputs: | |
serverEndpoint: 'AppCenter MyApp' | |
destinationType: 'store' | |
destinationStoreId: '$(APPCENTER_STOREID)' | |
appSlug: 'MyCompany/$(APPCENTER_SLUG)' | |
app: 'MyApp/MyApp.iOS/bin/iPhone/Release/MyApp.ipa' | |
symbolsType: Apple | |
dsymPath: 'MyApp/MyApp.iOS/bin/iPhone/Release/MyApp.app.dSYM' | |
releaseNotesSelection: 'input' | |
releaseNotesInput: 'Updates to our mobile app' | |
- task: Bash@3 | |
displayName: 'Tag Git Branch' | |
inputs: | |
targetType: 'inline' | |
failOnStderr: false | |
script: | | |
if [ "${AGENT_JOBSTATUS}" == "Succeeded" ]; then | |
git config --global user.email "azure@pipeline" | |
git config --global user.name "Azure Pipeline" | |
# Extract branch name from SourceBranch | |
branchName=${BUILD_SOURCEBRANCH##refs/heads/} | |
#Build.SourceBranchName | |
# Tag the branch if the build succeeded | |
TAG="$branchName-$BUILD_NUMBER" | |
git tag "$TAG" | |
git push origin "HEAD:$branchName" --tags | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment