Search

Github Action 단단히 알아가기

 들어가며

해당 포스팅은 더 많은 사람들이 볼 수 있도록 EarthValley80 Discussion 페이지에 먼저 작성했던 글을 그대로 가져왔습니다.
오늘은 알아두면 뼈가 되고, 살이 되는 Github Action에 대해서 알아보고자 합니다.
Github Action을 사용해 본 지 벌써 1년째지만 아직까지도 잘 모르겠어요.
최근에도 Actions를 설정하면서 22번의 workflow runs 끝에 Github Action build를 성공시켰습니다.
여러분들은 이런 기위기위에 빠지지 않았으면 하는 마음으로 글을 작성해봅니다.

 SwiftLint를 Github Action에 적용해보기

여러분들은 SwiftLint를 어디다가 적용해보셨나요. 대부분 프로젝트일 겁니다.
저는 프로젝트에 SwiftLint를 적용하면서 가장 불편했던 부분이 너무 많은 Warning 표시가 나타난다는 점이었어요. SwiftLint에서 나온 Warning이 정작 봐야하는 프로젝트 Warning보다 많으니 어떤 게 프로젝트에서 나타나는 Warning이고 SwiftLint에서 나온건지가 한 눈에 들어오지 않더라구요. 그래서 저는 Github Action에다가 SwiftLint를 적용하기에 이르렀습니다.
Github Action에다가 적용된 SwiftLint는 제가 직접 만들 수도 있겠지만 이미 마켓플레이스에 존재하는 SwiftLint Action이 있었기 때문에 이걸 가져다가 사용해봤어요.

⓵ .github/workflows/swiftlint.yml 파일 생성

첫 번째로 swiftlint.yml 파일이 필요합니다. 해당 파일은 .github/workflows 파일의 하위 파일로 들어가면 됩니다.
.github/workflows 부분에서 Create new file를 해서 생성해주셔도 되고, 터미널을 사용해서 vi으로 swiftlint.yml파일을 만들어주셔도 됩니다.
swiftlint.yml 파일 내부는 이렇게 생겼습니다.
name: auto PR swiftLint on: pull_request: branches: [ develop ] paths: - '.github/workflows/swiftlint.yml' - '.swiftlint.yml' - '**/*.swift' jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: GitHub Action for SwiftLint uses: norio-nomura/action-swiftlint@master env: DIFF_BASE: ${{ github.base_ref }} - name: Add PR Comment if: ${{ success() }} uses: mshick/add-pr-comment@v1 with: message: | ## All File Checked ✅ | ✅ | Auto Pull Request SwiftLint Success!!!! | |--- |---------------------------------------------- | repo-token: ${{ secrets.ACCESS_TOKEN }} repo-token-user-login: 'github-actions[bot]' # The user.login for temporary GitHub tokens allow-repeats: false # This is the default
Plain Text
복사
쉽게 본 형식의 파일은 아닐거예요. 해당 파일은 yaml 파일 포맷입니다.
yaml은 xml, json과 같이 우리가 타 시스템 간에 데이터를 주고 받을 때 데이터 포맷에 대한 약속이라고 생각해주시면 됩니다. Github action이 어떤 식으로 action를 동작시킬 지에 대한 값들을 yaml 파일 형식으로 보내주는 거 같아요! 저도 정확히는 모르기 때문에 그럴거라고 추측합니다..

⓶ ACCESS_TOKEN 설정

swiftlint.yml 파일을 생성했고, 저희가 사용하는 yml 파일에는 repo-token를 설정하는 부분이 있기 때문에 이 부분을 같이 설정해보려고 합니다.
repo-token: ${{ secrets.ACCESS_TOKEN }}
Plain Text
복사
현재 우리의 레포지토리에 대한 접근 권한은 우리가 가지고 있어요. 따라서 github-actions[bot]이 우리의 레포에 답글을 달기 위해선 권한이 필요해요. 따라서 해당 권한을 repo-token을 설정해서 주는 것이죠.
repo-token은 Settings에서 설정을 해줄 수 있습니다.
Settings > Secrets > Actions에서 New repository secret를 눌러주세요.
그리고 title를 ACCESS_TOKEN으로 설정해주세요. 그래야 우리가 설정해 둔 secrets.ACCESS_TOKEN에서 값을 가지고 올 수 있어요. 만약, title를 GITHUB_TOKEN같은 걸로 설정한다고 하면 yml파일 내부에서 secrets.GITHUB_TOKEN으로 설정해주면 되겠죠?
Secret안에 들어가는 값은 Github Access Token을 사용하면 됩니다. Github Access Token을 발급하는 것은 검색하면 많이 나오니 해당 글들을 참고해서 받아와주시면 됩니다.
이 부분까지 설정해주시면 PR를 날릴 때마다 github-action[bot]이 레포에 대한 권한을 받아서 Swiftlint에 대한 검사를 진행하게 됩니다.

⓷ ACCESS_TOKEN 이제는 설정해주지 않아도 됩니다

위에서 겨우겨우 설정했는데, 이게 무슨 말이냐구요? 이 부분은 action-swiftlint 깃허브를 들어가보면 알 수 있는데요.
Since 3.0.0, GITHUB_TOKEN is no longer needed.
3.0.0부터는 GITHUB_TOKEN이 더이상 필요없다고 하는군요. 번 부분을 설정해주지 않아도 됩니다!
하지만 사용하지 않으려면 yml파일을 조금 수정해줘야 합니다. 현재는 repo-token를 꼭 써야 하는 형식인데, repo-token를 사용하지 않는 방식으로 변경해줄 필요가 있겠죠?
action-swiftlint 깃허브를 들어가보면 example workflow 형식을 볼 수 있어요. 그 부분을 원하는대로 커스텀해서 사용하면 되지 않을까 싶네요.
제 파일에서 repo-token: ${{ secrets.ACCESS_TOKEN }} 부분을 지우면 잘 돌아가는지는 저도 아직 확인을 안해봐서 잘 모르겠습니다. 더 좋은 방식을 아시는 분이 있다면 언제든 코멘트 달아주세요.

⓸ swiftlint 사용

PR를 날리고 Check가 성공적으로 진행됐다면 Success했다는 메시지를 코멘트로 받을 수 있어요!

 Builder를 Github Action에 적용해보기

Builder는 레포지토리에 올라온 우리의 프로젝트를 한 번 돌려주는 역할을 해줍니다.
"어차피 local 에서 잘 돌리고 있었는데, 왜 빌드를 또 하는 거죠?" 라고 생각이 들 수도 있을 거 같습니다.
물론 다들 잘 돌아가는 프로젝트를 push 하겠지만 사람이 하는 일이다보니 문제가 터지는 파일을 깃에다가 push 할 수도 있어요. 이 상황에서는 PR이 머지되고 나면 develop이 터지는 문제가 발생할 수 있어요.
이 문제는 굉장히 크리티컬해요. 따라서 애초에 문제가 생기지 않도록 PR에서 제대로 된 파일을 올렸는지 한 번 확인을 해주는거죠. 그러면 위와 같은 상황이 발생하지 않을거예요. 물론 문제가 터진 부분을 확인해서 PR에 잘 반영을 하면 말이죵.

⓵ builder.yml 파일 생성

사실 이 부분만 해주면 끝납니다. 파일의 위치는 swiftlint.yml 파일과 동일합니다.
builder.yml 파일이 돌아가면서 우리가 원하는 위치에서 yml 에서 정의한 액션을 실행해줍니다.
name: EarthValley Swift-Builder on: push: branches: [ develop, main ] pull_request: branches: [ develop, release, hotfix ] jobs: build: runs-on: macos-latest steps: - name: 👻Checkout Source Code👻 uses: actions/checkout@v2 - name: 🌏 EarthValley Build Tests 🌏 run: | xcodebuild clean test -project ./EarthValley80/EarthValley80.xcodeproj -scheme EarthValley80 -destination "platform=iOS Simulator,name=iPad Pro (11-inch) (3rd generation),OS=15.2" xcpretty --color --simple
Plain Text
복사
push, pull_request 상황에서 builder 액션이 돌텐데, 원하는 브랜치를 정해줄 수 있어요.
위의 파일에서 보면 develop, main 에서 push 가 일어나면 해당 builder action이 돈다는 걸 알 수 있어요.
중요한 부분은 역시나 EarthValley Build Tests 내부일 거 같네요.
run 부분에 써있는 글을 보면 xcodebuild clean test -project ./EarthValley80/EarthValley80.xcodeproj -scheme EarthValley80 -destination "platform=iOS Simulator,name=iPad Pro (11-inch) (3rd generation),OS=15.2" 네요.
builder가 돌아가면서 테스트를 진행하는 부분일 듯 싶네요. 조금 설명을 얹어보자면,
xcodebuild clean test -project <xcodeproj 파일 path>
Plain Text
복사
테스트를 진행할 xcodeproj 파일의 경로를 적어두는 부분이에요.
경로가 틀리면 action fail이 날 수 있으니 경로를 자신의 프로젝트에 맞게 지정해줘야 해요. 저희 프로젝트 같은 경우에는 EarthValley80 내부에 xcodeproj가 있었기 때문에 경로를 위처럼 적은 걸 알 수 있어요.
저희 팀은 xcodeproj 만 사용하기 때문에 저렇게 써도 되는데, cocoapod를 사용하는 경우에는 xcworkspace를 사용하게 되잖아요. 그 경우는 xcworkspace에 맞게끔 변경해줘야 합니다. 제 파일과 동일하게 쓰게 된다면 fail를 맛 볼 수 있어요....
빌드를 진행하고 싶은 scheme를 써주시면 됩니다. 저는 EarthValley80를 빌드해보고 싶어서 위처럼 써봤어요.
-scheme <run scheme>
Plain Text
복사
빌드 시 사용할 플랫폼, 기기, OS를 설정할 수 있어요. 저희 프로젝트는 iPadOS 앱이기 때문에 기종을 iPad Pro로 빌드 기기를 정했어요.
-destination "platform=iOS Simulator,name=iPad Pro (11-inch) (3rd generation),OS=15.2"
Plain Text
복사
OS의 경우에는 최신의 OS를 적용하고 싶다면 OS=latest로 써주시면 됩니다.

⓶ builder 실행

PR를 날리면 builder가 돌아가는 걸 볼 수 있습니다. builder는 작은 프로젝트의 경우는 평균 5-6분 걸리는 거 같아요. 더 큰 프로젝트의 경우에는 10분까지 돌아가는 듯 합니다..
builder가 제대로 돌아갔다면 PR 하단에 체크가 되는 걸 볼 수 있어요.

 Github Action를 사용할 때 주의해야 할 점

Github Action는 storage와 minute에 limit이 있습니다. 이 부분을 참고하셔서 Action를 사용해주면 좋아요. private 레포는 1000분이 limit인데 꽤나 limit 타임이 빨리 찹니다..
그 이유는 바로,
macOS은 다른 OS의 10배의 multiplier가 적용되기 때문입니다.
제가 위에서 말했듯, iOS의 빌드 타임은 평균 5-6분입니다. 근데 multiplier까지 적용이 된다면 50-60분이 걸리는 겁니다. 그러면 1000분은 뚝딱이에요.
Github Action를 레포에서 사용하면 같은 오가니제이션에 속한 빌더들과 시간을 함께 나눠쓰는데 iOS가 시간을 다 잡아갑니다. ^^ 민폐!
긴 글 읽어주셔서 감사하고 제 글이 도움이 되었으면 좋겠네요. 궁금한 점이나 지적할 점, 추가될 부분이 생긴다면 언제든 코멘트 달아주세요. 감사합니다!