import os = require ( 'os' ) ; import path = require ( 'path' ) ; import tl = require ( 'azure-pipelines-task-lib/task' ) ; import sign = require ( './ios-signing-common' ) ; import { ToolRunner } from 'azure-pipelines-task-lib/toolrunner' ; function findMatchExactlyOne ( defaultRoot , pattern ) { let files = tl . findMatch ( defaultRoot , pattern ) ; if ( ! files || files . length === 0 ) { throw new Error ( tl . loc ( 'NoMatchingFileWithSearchPattern' , pattern ) ) ; } if ( files . length > 1 ) { throw new Error ( tl . loc ( 'MultipleFilesFound' , pattern ) ) ; } return files [ 0 ] ; } async function run ( ) { let deleteKeychain = false ; let useKeychain ; let deleteProvProfile = false ; let useProvProfilePath ; try { tl . setResourcePath ( path . join ( __dirname , 'task.json' ) ) ; if ( os . platform ( ) !== 'darwin' ) { throw new Error ( tl . loc ( 'DarwinOnly' ) ) ; } let ipaPath = tl . getPathInput ( 'ipaPath' , true , false ) ; let signMethod = tl . getInput ( 'signMethod' , true ) ; let signFileP12Path ; let signFileP12Password ; let signIdIdentity ; let signIdUnlockKeychain = false ; let signIdKeychainPassword ; if ( signMethod === 'file' ) { signFileP12Path = tl . getPathInput ( 'signFileP12Path' , true , false ) ; if ( ! tl . filePathSupplied ( 'signFileP12Path' ) ) { throw new Error ( tl . loc ( 'P12FilePathNotAPath' , signFileP12Path ) ) ; } signFileP12Password = tl . getInput ( 'signFileP12Password' , true ) ; } else if ( signMethod === 'id' ) { signIdIdentity = tl . getInput ( 'signIdIdentity' , true ) ; signIdUnlockKeychain = tl . getBoolInput ( 'signIdUnlockKeychain' , false ) ; signIdKeychainPassword = tl . getInput ( 'signIdKeychainPassword' , false ) ; } let provisionMethod = tl . getInput ( 'provisionMethod' , true ) ; let provFileProfilePath ; let provFileRemoveProfile = false ; let provIdProfileUuid ; if ( provisionMethod === 'file' ) { provFileRemoveProfile = tl . getBoolInput ( 'provFileRemoveProfile' , false ) ; provFileProfilePath = tl . getPathInput ( 'provFileProfilePath' , true , false ) ; if ( ! tl . filePathSupplied ( 'provFileProfilePath' ) ) { throw new Error ( tl . loc ( 'ProvisionFilePathNotAPath' , provFileProfilePath ) ) ; } } else if ( provisionMethod === 'id' ) { provIdProfileUuid = tl . getInput ( 'provIdProfileUuid' , true ) ; } let entitlementsPath ; if ( tl . filePathSupplied ( 'entitlementsPath' ) ) { entitlementsPath = tl . getPathInput ( 'entitlementsPath' , false , false ) ; } let sighResignArgs = tl . getInput ( 'sighResignArgs' , false ) ; let cwdPath = tl . getInput ( 'cwdPath' , false ) ; let cwd = cwdPath || tl . getVariable ( 'build.sourceDirectory' ) || tl . getVariable ( 'build.sourcesDirectory' ) || tl . getVariable ( 'System.DefaultWorkingDirectory' ) ; tl . cd ( cwd ) ; tl . debug ( 'cwd = ' + cwd ) ; let useIpaPath = findMatchExactlyOne ( cwd , ipaPath ) ; let useSigningIdentity = null ; if ( signMethod === 'file' ) { let signFilePath = findMatchExactlyOne ( cwd , signFileP12Path ) ; let keychain = tl . resolve ( cwd , '_iparesigntasktmp.keychain' ) ; let keychainPwd = '_iparesigntask_TmpKeychain_Pwd#1' ; tl . debug ( 'installed cert in temp keychain' ) ; await sign . installCertInTemporaryKeychain ( keychain , keychainPwd , signFilePath , signFileP12Password ) ; useKeychain = keychain ; deleteKeychain = true ; useSigningIdentity = await sign . findSigningIdentity ( keychain ) ; } else if ( signMethod === 'id' ) { let defaultKeychain = await sign . getDefaultKeychainPath ( ) ; if ( signIdUnlockKeychain ) { await sign . unlockKeychain ( defaultKeychain , signIdKeychainPassword ) ; } useKeychain = defaultKeychain ; useSigningIdentity = signIdIdentity ; } if ( provisionMethod === 'file' ) { useProvProfilePath = findMatchExactlyOne ( cwd , provFileProfilePath ) ; deleteProvProfile = provFileRemoveProfile ; } else if ( provisionMethod === 'id' ) { useProvProfilePath = sign . getProvisioningProfilePath ( provIdProfileUuid ) ; } let useEntitlementsFilePath ; if ( entitlementsPath ) { useEntitlementsFilePath = findMatchExactlyOne ( cwd , entitlementsPath ) ; } tl . debug ( `GEM_CACHE=${ process . env [ 'GEM_CACHE' ] }` ) ; let gemCache = process . env [ 'GEM_CACHE' ] || path . join ( process . env [ 'HOME' ] , '.gem-cache' ) ; tl . debug ( `gemCache=${ gemCache }` ) ; process . env [ 'GEM_HOME' ] = gemCache ; process . env [ 'FASTLANE_DISABLE_COLORS' ] = 'true' ; process . env [ 'PATH' ] = process . env [ 'PATH' ] + ':' + gemCache + path . sep + 'bin' ; let installFastlane = tl . getBoolInput ( 'installFastlane' , false ) ; let fastlaneVersionChoice = tl . getInput ( 'fastlaneToolsVersion' , false ) ; let fastlaneVersionToInstall ; if ( fastlaneVersionChoice === 'SpecificVersion' ) { fastlaneVersionToInstall = tl . getInput ( 'fastlaneToolsSpecificVersion' , true ) ; } tl . debug ( 'Checking for ruby install...' ) ; tl . which ( 'ruby' , true ) ; if ( installFastlane && fastlaneVersionToInstall ) { try { let gemRunner = tl . tool ( tl . which ( 'gem' , true ) ) ; gemRunner . arg ( [ 'uninstall' , 'fastlane' ] ) ; tl . debug ( `Uninstalling all fastlane versions...` ) ; gemRunner . arg ( [ '-a' , '-I' ] ) ; await gemRunner . exec ( ) ; } catch ( err ) { tl . warning ( tl . loc ( 'UninstallFastlaneFailed' , err ) ) ; } } if ( installFastlane ) { tl . debug ( 'Installing fastlane...' ) ; let gemRunner = tl . tool ( tl . which ( 'gem' , true ) ) ; gemRunner . arg ( [ 'install' , 'fastlane' ] ) ; if ( fastlaneVersionToInstall ) { tl . debug ( `Installing specific version of fastlane: ${ fastlaneVersionToInstall }` ) ; gemRunner . arg ( [ '-v' , fastlaneVersionToInstall ] ) ; } await gemRunner . exec ( ) ; if ( ! fastlaneVersionToInstall ) { tl . debug ( 'Updating fastlane...' ) ; gemRunner = tl . tool ( tl . which ( 'gem' , true ) ) ; gemRunner . arg ( [ 'update' , 'fastlane' , '-i' , gemCache ] ) ; await gemRunner . exec ( ) ; } } else { tl . debug ( 'Skipped fastlane installation.' ) ; } let sighCommand = tl . tool ( 'fastlane' ) ; sighCommand . arg ( [ 'sigh' ] ) ; sighCommand . arg ( [ 'resign' , useIpaPath ] ) ; sighCommand . arg ( [ '--keychain_path' , useKeychain ] ) ; sighCommand . arg ( [ '--signing_identity' , useSigningIdentity ] ) ; sighCommand . arg ( [ '--provisioning_profile' , useProvProfilePath ] ) ; sighCommand . argIf ( useEntitlementsFilePath , [ '--entitlements' , useEntitlementsFilePath ] ) ; if ( sighResignArgs ) { sighCommand . line ( sighResignArgs ) ; } await sighCommand . exec ( ) ; tl . setResult ( tl . TaskResult . Succeeded , tl . loc ( 'SuccessfullyResigned' , useIpaPath ) ) ; } catch ( err ) { tl . setResult ( tl . TaskResult . Failed , err ) ; } finally { if ( deleteKeychain ) { try { await sign . deleteKeychain ( useKeychain ) ; } catch ( err ) { tl . debug ( 'Failed to delete temporary keychain. Error = ' + err ) ; tl . warning ( tl . loc ( 'FailedTemporaryKeyDeletion' , useKeychain ) ) ; } } if ( deleteProvProfile ) { try { await sign . deleteProvisioningProfile ( useProvProfilePath ) ; } catch ( err ) { tl . debug ( 'Failed to delete provisioning profile. Error = ' + err ) ; tl . warning ( tl . loc ( 'FailedProvisioningProfileDeletion' , useProvProfilePath ) ) ; } } } } run ( ) ;