Azure DevOps로 iOS용 Unity 자동 빌드 환경 구축

소개



Pipelines의 Microsoft-hosted 및 Self-hosted
Self-hosted 환경을 구축하는 방법
Unity Tools for Azure DevOps 사용

위에서는 자동 빌드를 할 준비와 파트를 소개했지만, 이번에는 실제로 Microsoft-hosted 환경에서 Unity의 자동 빌드 환경을 구축하고 싶습니다.
벌써 소개 끝난 기사로 대범은 커버 할 수 있기 때문에, 정리 같은 기사가 되고 있습니다만 양해 바랍니다.

Microsoft-hosted이므로, 로컬에 환경이 없어도 Unity의 라이센스만 있으면 클라우드상에서 빌드 환경을 구축할 수 있습니다.

목표


  • Unity에서 iOS 자동 빌드 환경 구축

  • 소스 코드



    그럼 갑자기 소스 코드를 모두 게재합니다.
    ################################################################################
    #
    #  Unity Build for iOS (Microsoft-hosted)
    #
    ################################################################################
    
    trigger:
    - master
    
    variables:
      ProjectName: 'DevOps-Example'
    
      Unity.BaseDirectory: '/Applications/Unity/Hub/Editor'
      Unity.EditorDirectory: ''
      Unity.TargetBuild: 'iOS'
      Unity.InstallComponents: 'Mac,$(Unity.TargetBuild)'
      Unity.ProjectDirectory: '$(Build.SourcesDirectory)'
      Unity.OutputDirectory: '$(Build.BinariesDirectory)'
      Unity.OutputFileName: '$(ProjectName)-$(Unity.TargetBuild)'
    
      Configuration: 'Debug'
      SDK: 'iphoneos'
      TeamId: '<チーム ID>'
    
      Xcode.Scheme: 'Unity-iPhone'
      Xcode.ArchiveDirectory: '$(Build.BinariesDirectory)/Archive'
      Xcode.ExportDirectory: '$(Build.ArtifactStagingDirectory)/Export'
      Xcode.P12FileName: '<P12 ファイル名>'
      Xcode.ProvisioningProfileUuid: '<プロビジョニングプロファイルの UUID>'
      Xcode.ProvisioningProfile: '$(Xcode.ProvisioningProfileUuid).mobileprovision'
    
      AppCenter.Endpoint: 'AppCenter'
      AppCenter.AppSlug: '<組織名>/$(Unity.OutputFileName)'
      AppCenter.AppFilePath: '$(Xcode.ExportDirectory)/$(ProjectName).ipa'
    
    pool:
      vmImage: 'macOS-latest'
    
    jobs:
      - job: Unity
        displayName: 'Unity build started.'
        condition: or(not(variables['Unity.UserName']), not(variables['Unity.Password']), not(variables['Unity.SerialKey']))
        workspace:
          clean: outputs
    
        steps:
        # macOS を選択した場合、Unity の PackageManager が Mac のファイアーウォールで弾かれる可能性があるのでファイアーウォールを無効化
        - bash: |
            sudo defaults delete /Library/Preferences/com.apple.alf globalstate
    
        - task: UnityGetProjectVersionTask@1
          name: UnityGetProjectVersion
          inputs:
            unityProjectPath: '$(Unity.ProjectPath)'
    
        - bash: echo "##vso[task.setvariable variable=Unity.EditorDirectory]$(Unity.BaseDirectory)/$(UnityGetProjectVersion.projectVersion)"
          displayName: 'Unity エディターのパスを取得'
    
        - task: Cache@2
          displayName: 'Unity Install cache'
          inputs:
            key: '$(Agent.OS) | "$(UnityGetProjectVersion.projectVersion)" | $(Unity.InstallComponents)'
            path: '$(Unity.EditorDirectory)'
            cacheHitVar: 'UnityInstallCached'
    
        # Microsoft-hosted 環境で Unity のインストールが失敗する原因を解消する対処
        # https://github.com/microsoft/unitysetup.powershell/issues/156#issuecomment-650578187
        - powershell: |
            mkdir ~/.unitysetup
          displayName: 'mkdir ~/.unitysetup'
          condition: and(succeeded(), ne(variables['UnityInstallCached'], true))
    
        - powershell: |
            Install-Module -Name UnitySetup -AllowPrerelease -Force -AcceptLicense
          displayName: 'Installing Unity Setup Powershell Module.'
          condition: and(succeeded(), ne(variables['UnityInstallCached'], true))
          failOnStderr: true
    
        - powershell: |
            Install-UnitySetupInstance -Installers (Find-UnitySetupInstaller -Version '$(UnityGetProjectVersion.projectVersion)' -Components "$(Unity.InstallComponents)") -Verbose
          displayName: 'Installing Unity components.'
          condition: and(succeeded(), ne(variables['UnityInstallCached'], true))
    
        - task: UnityActivateLicenseTask@1
          displayName: 'Unity License Activations.'
          condition: succeeded()
          inputs:
            username: '$(Unity.UserName)'
            password: '$(Unity.Password)'
            serial: '$(Unity.SerialKey)'
            unityEditorsPathMode: 'unityHub'
            unityProjectPath: '$(Unity.ProjectPath)'
    
        - task: UnityBuildTask@3
          name: UnityBuild
          inputs:
            buildTarget: '$(Unity.TargetBuild)'
            unityProjectDirectory: '$(Unity.ProjectDirectory)'
            outputPath: '$(Unity.OutputDirectory)'
            outputFileName: '$(Unity.OutputFileName)'
    
        - task: PublishBuildArtifacts@1
          displayName: 'ビルドエラー時にエラーログをパブリッシュ'
          condition: failed()
          inputs:
            PathtoPublish: '$(UnityBuild.logsOutputPath)'
            ArtifactName: 'UnityLog'
            publishLocation: 'Container'
    
        - task: InstallAppleCertificate@2
          inputs:
            certSecureFile: '$(Xcode.P12FileName)'
            certPwd: '$(Xcode.P12Password)'
            keychain: 'temp'
    
        - task: InstallAppleProvisioningProfile@1
          inputs:
            provisioningProfileLocation: 'secureFiles'
            provProfileSecureFile: '$(Xcode.ProvisioningProfile)'
    
        # UnityBuildTask@3 で出力された MapFileParser.sh に実行権限がないため
        - bash: |
            chmod +x '$(Unity.OutputDirectory)/$(Unity.OutputFileName)/MapFileParser.sh'
          displayName: 'MapFileParser.sh に実行権限を付与'
    
        # Info.plist に記載されている CFBunbleVersion を置き換える
        # ここはプロジェクトごとにポリシーが違うと思いますので、削除なりしていただければよいかと
        - bash: |
            sed -i -e 's/99999/$(Build.BuildId)/g' $(Unity.OutputDirectory)/$(Unity.OutputFileName)/Info.plist
          displayName: 'CFBundleVersion の書き換え'
    
        - task: Xcode@5
          inputs:
            actions: 'archive'
            xcWorkspacePath: '$(Unity.OutputDirectory)/$(Unity.OutputFileName)/$(Xcode.Scheme).xcodeproj/project.xcworkspace'
            scheme: '$(Xcode.Scheme)'
            packageApp: true
            archivePath: '$(Xcode.ArchiveDirectory)'
            exportPath: '$(Xcode.ExportDirectory)'
            signingOption: 'manual'
            provisioningProfileUuid: '$(Xcode.ProvisioningProfileUuid)'
            args: 'DEVELOPMENT_TEAM=$(TeamId)'
    
        - task: AppCenterDistribute@3
          inputs:
            serverEndpoint: '$(AppCenter.Endpoint)'
            appSlug: '$(AppCenter.AppSlug)'
            appFile: '$(AppCenter.AppFilePath)'
            releaseNotesOption: 'input'
            releaseNotesInput: |
              - Agent Name:$(Agent.Name)
              - Agent OS:$(Agent.OS)
              - Agent Architecture:$(Agent.OSArchitecture)
              - Configuration:$(Configuration)
              - SDK:$(SDK)
              - Provisioning Profile:$(Xcode.ProvisioningProfileUuid)
              - Branch:$(Build.SourceBranchName)
              - Last Commit ID:$(Build.SourceVersion)
              - Last Commit Comment:$(Build.SourceVersionMessage)
              - BuildNumber:$(Build.BuildNumber)
              - Reason:$(Build.Reason)
              - Requester:$(Build.RequestedFor)
            isMandatory: true
            destinationType: 'groups'
    

    이 yml을 사용하려면 변수를 설정해야 합니다.
    yml 편집기의 오른쪽 상단에 있는 Variables에서 Unity.Password, Unity.SerialKey, Unity.UserName의 세 가지 변수를 설정합니다.



    각각 Unity에서 제공하는 '암호', '일련 번호', '사용자 이름'입니다.



    매우 간단합니다!
    이제 Azure DevOps Pipelines를 사용하여 Unity의 자동 빌드 환경을 만들 수 있습니다.
    이 소스 코드를 저장소에 azure-pipelines.yml이라는 이름으로 저장하고 가져오기만 하면 됩니다.

    작은 재료



    이번 Pipelines에서는 Azure Repos 등의 git에서 클론을 해오게 됩니다만, 한 번이라도 성공하면 소스 코드가 캐시되어 클론이 아니라 풀이 되기 때문에, 실패할 것 같은 태스크는 처음에는 코멘트 아웃 해 두고, 반드시 먼저 한 번 성공시켜 두는 것이 좋습니다.

    결론



    덧붙여서 무료 계정으로도 충분히 자동 빌드 환경의 구축이 가능하므로, 꼭 시험해 보세요.

    좋은 웹페이지 즐겨찾기