2021년 1월 12일 화요일

Jenkins in Docker, Fastlane 을 젠킨스 노드를 통해 IOS빌드하기

 앞서 간단히 Fastlane을 통해 ipa 파일을 클릭한번으로 생성하는 것을 해봤다. 
https://yunhos.blogspot.com/2021/01/ios-fastlane-ipa.html

이걸 젠킨스로 하고 싶은데, ubuntu linux기반이라  Xcode에서만 컴파일&인증이 가능하다.

물론 젠킨스를 맥에 설치하고 

https://stackoverflow.com/questions/32347839/building-an-ios-app-with-jenkins

xcrun xcodebuild -project ProjectName.xcodeproj \ -configuration Release \ -destination 'platform=iOS Simulator,name=iPhone 6s' \ -allowProvisioningUpdates \ CODE_SIGN_STYLE='Automatic' PROVISIONING_PROFILE_SPECIFIER=${PROVISIONING_PROFILE} CODE_SIGN_IDENTITY=${CODE_SIGNING_IDENTITY}

이딴 명령어를 빌드 shell 에 입력하면 된다. ( fastlane 도 되겠네.)

참고 자료

趣味でつくるiOSアプリこそJenkinsでリリースを自動化 https://qiita.com/makoto_kw/items/b23350aed11ea87cd92b


-------------------------------------------------------

그런데 ios 개발자들이 모두 젠킨스 설치해서 빌드하면 특정 개발자가 없는때는 어케 빌드하나? 

그리고 웬만하면 도커에 설치된 젠킨스에서 실행하고 싶었다.

검색해본 결과

딱맞는 강좌를 올린사람이 있었다.

CI/CD With Jenkins, Docker and Fastlane

https://medium.com/multinetinventiv/ci-cd-with-jenkins-docker-and-fastlane-p1-primer-6bfc28267381

요는 도커에 젠킨스를 올리고, 거기서는 ios 앱빌드가 안되니까 젠킨스의 멀티작업용 하위노드로 로컬피씨를 등록하고, 거기서 Fastlane을 돌려서 ios 을 성공적으로 빌드한다.

이런 시나리오다. 도커,젠킨스,fastlane,ios 코드사인 등이 설정이 쉽다면 오죽좋겠냐만은 징그러운 ios 빌드관련이라 역시 어렵다.


일단 저사람 강좌를 따라서 

1. 현재 IOS을 fastlane 으로 빌드 되도록 구성한다.

2. Docker + Jenkins 를 설치한다.

3. 맥에서 System preference -> Sharing 으로 가서 [Remote Loin] 을 체크하고 

[To log in to this computer remotely, type “ssh yourName@xxx.xxx.xxx.xxx”.]

을 확인한다. 즉 내부내트워크에서는 yourname사용자 이름으로 이 컴에 접속하도록한다. 

이걸 도커의 젠킨스에서 접속할때 사용할거다.

4. 젠킨스를 실행해서 Manage Jenkins - > Manage Node And Clouds 로 가서 [New Node]를 선택해서 맥을 노드로서 추가해야한다.

일단 처음에는 Node Name 입력 과 Permanent Agent만 선택하고 생성한다.

5. 다시 노드목록을 보면 젠킨스자신(master)와 아까 만든 노드이름이 있는데 새로만든 노드를 클릭해서 정보를 넣자. 노드 화면 왼쪽의 Configure를 선택하자. 

# of excutors 는 1

 Remote root directory 는 자신의맥에 적당한 폴더를 만들고 지정하자 /User/yourname/temp

Launch method 는 노드에 접속할 방법인데, 아까 ssh 로 도커컨테이너에서 내맥에 접속할수 있도록 share 해주었으니 그 정보를 넣자.

Launch agents via SSH 선택
만일 이게 없다면 SSH Build Agent Plugin 을 설치해야한다

Host 는 맥아이피(192.168.0.100등)

Credentials 는 Add에서 Username with password 타입으로 하되, 

   Username 은 아까 share 에서 표시된 사용자이름

  password 는 맥로그인시의 암호와 같음

으로 저장하고. 창이 닫히면 생성한 Credentials (이번에는 yourname/***)을 선택하자.

나머진 그냥두자. 

Relaunch 클릭해서 접속해보자.

6.위에서 다 입력했다면 젠킨스가 노드에 접속시도를 할것이다. 잘되었다면 접속시도 맨 마지막 줄에 Evacuated stdout

Agent successfully connected and online 

 가 나온다. 그리고 다시 nodes 목록으로 가면 해당 노드에 디스크정보등이 잘 표시된다.

만일 접속이 안된다면 

젠킨스컨테이너에 쉘접속해서 ssh yourname@xxx.xxx.xxx.xxx 로 맥으로 원겹접속한다음 yes해서 known_hosts 에 맥을 추가한다. 잘안될떄는 /root/.ssh/known_hosts 를 /var/jenkins/.ssh/known_hosts 로 755 권한으로 바꾸어서 복사해본다. 또는 그냥 접속만 해봐도 노드가 맥에 잘접속되는경우가 있다.

7.master  노드를 선택해서. configure 에서 # of excutors 는 0 으로 하자. 

 젠킨스환경설정 설명은 여기에 

https://www.lesstif.com/continuous-integration/%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95-31850999.html

8. 도커컨테이너를 실행중인 젠킨스에서 맥으로 원격접속해서 뭔가하도록 하는 설정은 끝났다.

9.젠킨스잡을 생성해야 한다. New Item -> Multibranch Pipeline을 선택해서 생성하자.

10. 새로운 아이템을 생성하면, 설정화면으로 가는데,

Build Configuration -> Script Path 를 Jenkinsfile 로 입력해서 git에서 체크아웃한 파일등중에 해당 파일이 있으면 젠킨스가 해당파일의 내용을 실행하도록 하자.

Github도 설정하자. Credentials 에 github 설정시에 password가 자신이 알고 있는 비번으로 접속이 안된다고 할때가 있는데, 이럴때는 github.com -> developer setting -> personal access token 에서 토큰을 생성하고 암호입력란에 넣으면 된다.

11 . Scan Multibranch Pipeline Triggers 에

Periodically if not other wise run 체크하고 15분 인터벌준다.

Orphaned Item Strategy에

Discard old items 를 체크하고 max #...를 50으로 한다.

12. 이제 잡은 준비되었다. 아까 설정시에 Jenkinsfile 이 있으면 그안의 내용을 실행한다고 했으니 해당 파일을 체크아웃할 git 에 만들어서 푸시해놓자.

Jenkinsfile 은 구루비 언어로 만든다.

#!groovy


def lastCommitInfo = ""

def skippingText = ""

def commitContainsSkip = 0

def slackMessage = ""

def shouldBuild = false


def pollSpec = ""


if(env.BRANCH_NAME == "master") {

    pollSpec = "*/5 * * * *"

} else if(env.BRANCH_NAME == "test") {

    pollSpec = "* * * * 1-5"

}


pipeline {

    agent any


    triggers {

        pollSCM ignorePostCommitHooks: true, scmpoll_spec: pollSpec

    }


    stages {

        stage('Init') {

            steps {

                script {

                    lastCommitInfo = sh(script: "git log -1", returnStdout: true).trim()

                    commitContainsSkip = sh(script: "git log -1 | grep '.*\\[skip ci\\].*'", returnStatus: true)


                    if(commitContainsSkip == 0) {

                        skippingText = "Skipping commit."

                        env.shouldBuild = false

                        currentBuild.result = "NOT_BUILT"

                    }


                }

            }

        }


        stage('Build application for beta') {

            steps {

                sh "ls"

                sh "/Users/yourname/temp/unlockme.sh"

                sh "/usr/local/bin/fastlane make_debug_ipa"

            }

        }





    }


}


13. 이제 Build Now 를 해보면 git 에서 체크아웃 한다음 Node설정에서 지정한 로컬맥폴더로 복사를 하고 Jenkinsfile에 있는 내용을 실행한다.

여기서 문제가 좀 있던게,  앱을 생성할때 사용하는 Codesign은 ssh를 통해서는 할수없도록 되어있기 때문에, 젠킨스에서 codesign전에 로컬에서 사용자암호를 묻는 과정을 생략해야한다.

그게 바로  

                sh "/Users/yourname/temp/unlockme.sh"
파일내용은 

#/bin/bash


security default-keychain -s '/Users/yourname/Library/Keychains/login.keychain'

security -v unlock-keychain -p "maybe MAC yourPass" "/Users/yourname/Library/Keychains/login.keychain" 

14. 자 이제 돌려보면 node설정에서 지정했던 폴더 하위에 myapp.ipa 파일이 똭(또는 fastlane에서 서버로 보냈거나..등등) 이 생긴다. 그걸로 테스트 팀에 주면된다.

 

0 comments:

댓글 쓰기