develop

iOS shell파일로 앱스토어(appstoreconnect) 에 업로드 본문

ETC

iOS shell파일로 앱스토어(appstoreconnect) 에 업로드

pikachu987 2021. 4. 4. 10:39
반응형

개인앱을 하나씩 앱스토어에 업로드를 하다가

앱이 5 + α 개 이상으로 늘어나니까

개인 앱이라 공통 라이브러리 or 공통 코드를 수정하면 전체 앱을 한번씩 배포를 해주다 보니

한번에 업로드 하기가 너무 시간이 걸리고 귀찮았다.

어떻게 하면 알아서 앱스토어 업로드까지 나가면서 나는 다른 일을 할 수 있을까 생각하다가

fastlane 처럼 터미널에서 업로드를 해야겠다고 생각하였고

sh 파일을 만들었다.

 

username="";
password="";
gitPath="https://$username:$password@github.com/$username";
distributeBranch="distribute";
exportOptionsPath="ExportOptions.plist";
storagePath="ios_distribute";

cd ~
homePath="$PWD";
rootPath="$homePath/$storagePath";

username과 password는 자신의 아이디, 비밀번호에 맞게 수정한다.

나는 git에 있는 앱 배포 브랜치를 distribute로 만들었다. (실제 git에 distribute 브랜치가 있어야 한다.)

ExportOptions.plist 위치를 지정하고 (ExportOptions.plist 내용은 하단 참조)

storagePath를 지정하였다. storagePath는 ~/ios_distribute/ 폴더에 git 이 다운되고 빌드, 업로드 되는 폴더이다.

 

sourcePath="$gitPath/Repository";
projectName="";

git clone $sourcePath -b $distributeBranch -q $rootPath/$projectName;
cd $rootPath/$projectName;
sudo chmod -R 777 $rootPath/$projectName;

그리고 프로젝트 이름을 맞게 수정을 하고

git clone을 $sourcePath(깃헙 리포지토리)에서 $distributeBranch(distribute) 브랜치만 --quiet(터미널에 메시지 없게) $rootPath/$projectName (~/ios_distribute/projectName) 여기에 clone받는다.

 

cd $rootPath/$projectName;
/usr/local/bin/pod cache clean --all --allow-root --silent
/usr/local/bin/pod install --repo-update --allow-root --silent
sudo chmod -R 777 $rootPath/$projectName;

난 cocoapods을 쓰니까

$projectName폴더로 이동해서

pod cache를 clean을 해주고 pod install을 한다.

 

/usr/bin/xcodebuild clean -workspace $rootPath/$projectName/$projectName.xcworkspace -scheme $projectName -quiet
/usr/bin/xcodebuild build -workspace $rootPath/$projectName/$projectName.xcworkspace -scheme $projectName -configuration Release -quiet
/usr/bin/xcodebuild archive -workspace $rootPath/$projectName/$projectName.xcworkspace -scheme $projectName -archivePath $rootPath/$projectName/archive.xcarchive -configuration Release -quiet
if [ -d "$rootPath/$projectName/archive.xcarchive" ]; then
	xcodebuild -exportArchive -allowProvisioningUpdates -allowProvisioningDeviceRegistration -archivePath $rootPath/$projectName/arcive.xcarchive -exportOptionsPlist $rootPath/$projectName/$exportOptionsPath -quiet
    sudo rm -rf $rootPath/$projectName
fi

xcodebuild를 사용하여 clean을 해주고 (scheme는 각자에 맞게 나는 프로젝트Name을 빌드, 업로드할 스키마로 만듬)

xcodebuild를 사용하여 build를 한다.

그리고 xcodebuild를 사용하여 archive를 하는데 archive가 만들어질 path를 지정한다. 나는 프로젝트 있는곳에 바로 나두겠다.

그리고 archive가 있으면

xcodebuild를 사용하여 exportArchive를 한다. (앱스토어에 업로드한다.)

아까 만들었던 ExportOptions.plist를 같이 적어준다.

그리고 프로젝트를 지운다.

 

 

- 여러앱 업로드

 

그리고 나는 여러 앱들을 한번에 업로드 하기 위해 for문으로 돌렸다.

아래 코드는 여러 앱들을 한번에 앱스토어에 업로드 하는 shell파일 코드 예시이다.

#!/bin/bash
export LANG=en_US.UTF-8

username="";
password="";
gitPath="https://$username:$password@github.com/$username";
distributeBranch="distribute";
exportOptionsPath="ExportOptions.plist";
storagePath="ios_distribute";

# index, title, sourcePath, projectName
appList=();
appList+=("1,ExTitle1,$gitPath/Project1.git,ProjectName1");
appList+=("2,ExTitle2,$gitPath/Project2.git,ProjectName2");
appList+=("3,ExTitle3,$gitPath/Project3.git,ProjectName3");
appList+=("4,ExTitle4,$gitPath/Project4.git,ProjectName4");

apps=();

cd ~
homePath="$PWD";
rootPath="$homePath/$storagePath";

selectAppStart() {
	echo ""
	echo "---------------------------------------------------------"
	echo "앱스토어에 업로드할 앱들의 번호를 입력하세요. (띄워쓰기로 구분)";
	echo "---------------------------------------------------------"

	echo "0.전체";
	for idx in "${!appList[@]}"; do
		app=(`echo ${appList[idx]} | tr "," "\n"`);
		echo ${app[0]}.${app[1]};
	done

	echo "---------------------------------------------------------"
	read selectApps;

	if [ "$selectApps" == "0" ]; then
		for index in "${!appList[@]}"; do
			apps+=("${appList[index]}");
		done
	else
		selectAppMap=(`echo $selectApps | tr " " "\n"`);
		for element in "${selectAppMap[@]}"; do
			for index in "${!appList[@]}"; do
				app=(`echo ${appList[index]} | tr "," "\n"`);
				if [ "${app[0]}" == "$element" ]; then
					apps+=("${appList[index]}");
				fi
			done
		done
	fi

	for idx in "${!apps[@]}"; do
		app=(`echo ${apps[idx]} | tr "," "\n"`);
		echo ${app[1]}
	done

	echo "---------------------------------------------------------"

	startBuild
}

startBuild() {
	if [ ! -d "$rootPath" ]; then
		sudo mkdir $rootPath;
		echo "🔵 sudo mkdir $rootPath;";
		sudo chmod -R 777 $rootPath;
		echo "🔵 sudo chmod -R 777 $rootPath;";
	fi

	/usr/local/bin/pod cache clean --all --allow-root --silent
	echo "🔵 /usr/local/bin/pod cache clean --all --allow-root --silent";
	
	cd $rootPath;
	echo "🔵 cd $rootPath;";

	echo "---------------------------------------------------------"
	echo "🔵 START";
	echo "---------------------------------------------------------"
	for index in "${!apps[@]}"; do
		ifExistApp $index;
	done

	echo "🟢 COMPLETE";
	exit 0;
}

ifExistApp() {
	index=$1;
	appString="${apps[index]}";
	appStringMap=(`echo $appString | tr "," "\n"`);
	appStringMapIndex=0;

	for element in "${appStringMap[@]}"; do
		if [ $appStringMapIndex == 1 ]; then
			title=$element;
		elif [ $appStringMapIndex == 2 ]; then
			sourcePath=$element;
		elif [ $appStringMapIndex == 3 ]; then
			projectName=$element;
		fi
		appStringMapIndex=$((appStringMapIndex+1));
	done

	cd $rootPath;
	if [ -d "$rootPath/$projectName" ]; then
		rm -rf $rootPath/$projectName;
		echo "🔵 $title rm -rf $rootPath/$projectName;";
	fi
	git clone $sourcePath -b $distributeBranch -q $rootPath/$projectName;
	echo "🔵 $title git clone $sourcePath -b $branch -q $rootPath/$projectName;";
	sudo chmod -R 777 $rootPath/$projectName;
	echo "🔵 $title sudo chmod -R 777 $rootPath/$projectName;";
	cd $rootPath/$projectName;
	echo "🔵 $title cd $rootPath/$projectName;";
	libInstall
	build
}

libInstall() {
	cd $rootPath/$projectName;
	echo "🔵 $title cd $rootPath/$projectName;";
	
	/usr/local/bin/pod install --repo-update --allow-root --silent
	echo "🔵 $title /usr/local/bin/pod install --repo-update --allow-root --silent";

	sudo chmod -R 777 $rootPath/$projectName;
	echo "🔵 $title sudo chmod -R 777 $rootPath/$projectName;";
}

build() {
	cd $rootPath/$projectName;
	echo "🔵 $title cd $rootPath/$projectName;";
	
	/usr/bin/xcodebuild clean -workspace $rootPath/$projectName/$projectName.xcworkspace -scheme $projectName -quiet
	echo "🔵 $title /usr/bin/xcodebuild clean -workspace $rootPath/$projectName/$projectName.xcworkspace -scheme $projectName -quiet";
	
	/usr/bin/xcodebuild build -workspace $rootPath/$projectName/$projectName.xcworkspace -scheme $projectName -configuration Release -quiet
	echo "🔵 $title /usr/bin/xcodebuild build -workspace $rootPath/$projectName/$projectName.xcworkspace -scheme $projectName -configuration Release -quiet"

	/usr/bin/xcodebuild archive -workspace $rootPath/$projectName/$projectName.xcworkspace -scheme $projectName -archivePath $rootPath/$projectName/arcive.xcarchive -configuration Release -quiet
	echo "🔵 $title /usr/bin/xcodebuild archive -workspace $rootPath/$projectName/$projectName.xcworkspace -scheme $projectName -archivePath $rootPath/$projectName/arcive.xcarchive -configuration Release -quiet";
	
	if [ -d "$rootPath/$projectName/arcive.xcarchive" ]; then
		xcodebuild -exportArchive -allowProvisioningUpdates -allowProvisioningDeviceRegistration -archivePath $rootPath/$projectName/archive.xcarchive -exportOptionsPlist $rootPath/$projectName/$exportOptionsPath -quiet
		echo "🔵 $title xcodebuild -exportArchive -allowProvisioningUpdates -allowProvisioningDeviceRegistration -archivePath $rootPath/$projectName/archive.xcarchive -exportOptionsPlist $rootPath/$projectName/$exportOptionsPath -quiet";

		sudo rm -rf $rootPath/$projectName
		echo "🔵 $title sudo rm -rf $rootPath/$projectName";

		echo ""
		echo "-----------------------------------------------------------------------"
		echo "🟣 $title complete distribute 🎉";
		echo "-----------------------------------------------------------------------"
		echo ""
	else
		echo ""
		echo "-----------------------------------------------------------------------"
		echo "🔴 $title xcodebuild -archive no $rootPath/$projectName/arcive.xcarchive file";
		echo "-----------------------------------------------------------------------"
		echo ""
	fi
}

selectAppStart​

 

 

 

 

- ExportOptions

ExportOptions의 내용은

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>compileBitcode</key>
	<true/>
	<key>destination</key>
	<string>upload</string>
	<key>method</key>
	<string>app-store</string>
	<key>signingStyle</key>
	<string>automatic</string>
	<key>stripSwiftSymbols</key>
	<true/>
	<key>teamID</key>
	<string></string>
	<key>thinning</key>
	<string>&lt;none&gt;</string>
</dict>
</plist>

이렇게 만들었다.

그리고 깃에 같이 저장해 두었다.

signingStyle를 맞게 수정하고

teamID를 수정을 한다.

 

참조

gist.github.com/skabber/4f2b20c6bd18e5934909189489549cce

 

Export Options Plist Example

Export Options Plist Example. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

gist.github.com/sandeeplearner/52d12fd43ba15596a8af94ab2f2ddacb

 

Example of ExportOptions.plist

Example of ExportOptions.plist. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

반응형
Comments