다국어가 지원되는 프로젝트를 개발하는 것에 있어서 개발자의 노동이 최소화되고 휴먼에러를 축소시킬 수 있도록 하기 위해 어떻게 다국어 리소스 관리를 자동화해야 할 것인가에 대해 알아보고 있다.
앞선 내용까지는 1편 을 참고!
Git Submodule과 Github Actions를 통한 다국어 자동화 (1)
이제 localization에 대한 작업을 마친 PR을 자동으로 base branch에 머지하고 & 업데이트된 서브모듈 레포지토리에 대해 메인 레포지토리에 최신화 시켜주는 과정(서브모듈이 최신 커밋을 바라보도록)까지 하면 개발자가 손 델 일 없는 완전한 자동화 완성! 개발자는 UI에 넣을 텍스트에 대해 다국어 key값 혹은 swiftGen을 통해 변환된 static 프로퍼티 이름만 알고 있으면 끝!
추가적으로 중간중간 완료된 작업에 대해 팀 메신저에 성공적으로 끝났다고 알림이 오면 좋으니 슬랙 웹훅을 사용해서 특정 작업이 끝나면 팀 메신저에 메시지가 오도록 하는 부분동 알아보겠습니다. 그리고 리디님 글에는 PR을 머지하기 전에 다국어 key의 유효성 검증 같은 부분도 있지만 이번에는 패스! 파이썬 코드를 통해 검증하는 플로우도 넣을 수 있는 것 같다. 역시 안 해봤을 뿐 맘만 먹으면 다 길이 있군..
📍PR merge
일단 pr 머지 하는 작업에 대해 간단히 알아보면, 이전 글에서 SwiftGen을 통해 코드로 변환 후 완료 커밋까지 남겼던 작업을 마치고 아래 job에 대한 스크립트를 실행하면 된다.
...
review-and-merge:
# 선행하는 Job이 성공적으로 완료된 후 실행
needs: localization
if: ${{ needs.localization.result == 'success' }}
runs-on: ubuntu-latest
steps:
# PR Branch 체크아웃
- name: Checkout PR branch
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}
# Base Branch에 체크아웃
- name: Checkout base branch
uses: actions/checkout@v3
with:
path: base_branch
ref: ${{ github.base_ref }}
- name: Get First Commit Message
id: commit
uses: actions/github-script@v6
with:
script: |
const { data: commits } = await github.rest.pulls.listCommits({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number
});
const firstCommit = commits[0];
core.setOutput('message', firstCommit.commit.message);
- name: Merge PR
id: merge
uses: actions/github-script@v6
with:
script: |
await github.rest.pulls.merge({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: ${{ github.event.pull_request.number }},
merge_method: 'squash'
});
continue-on-error: true
...
📍Slack Webhook
그리고 위의 머지작업이 성공적으로 끝났다는 걸 팀 메신저에 메시지로 알림을 받고 싶다면, 슬랙 웹훅을 통해 구현해 볼 수 있다. 나는 개인 프로젝트라서 슬랙을 사용하고 있진 않았지만 이전 회사에서 사내 워크스페이스에 웹훅 사용했을 때도 개발 환경/상황을 공유하기 유용했기 때문에 혼자 있는 슬랙 채널이라도 만들어서 이번 자동화에도 이 과정을 넣었다.
먼저 슬랙 워크스페이스와 그 안에 관련 메시지를 받고 싶은 채널을 만들고 슬랙 웹훅 url 확인하기! 이런 건 사실 방법을 기억하고 있는 게 아니아서 할 때마다 찾아보는 게 국룰 ㅎㅎ (이 블로그를 참고했다! https://velog.io/@king/slack-incoming-webhook ). 이렇게 웹훅 url 확인하고 GitHub Secret에 저장하면 되는데 Webhook URL을 직접 .yml 워크플로우 파일에 넣으면 보안상 위험하기 때문!
위에 작업 (PR merge)가 끝나면 슬랙에 웹훅을 보낼 수 있도록해보자
...
# 성공시 Slack에 알림
- name: Notify Slack on Merge Success
if: steps.merge.outcome == 'success'
uses: slackapi/slack-github-action@v2.0.0
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger
payload: |
{
"text": "🎉 PR Merge Success\n\nPR: ${{ github.event.pull_request.html_url }}\nBranch: `${{ github.head_ref }}`\nCommit: ${{ steps.commit.outputs.message }}"
}
▶️ localization & review and merge 에 대한 job 모두 성공했을 때
이렇게 각 job 이 순차적으로 완료된 걸 볼 수 있다.
▶️ Slack Webhook 전송이 성공했을 때
이렇게 하면 서브모듈의 업데이트는 끝났죠?
그럼 이제 프로젝트에서 이 서브모듈의 업데이트를 최신화시켜서(메인 레포지토리에서 서브모듈의 최신 커밋 해시를 바라볼 수 있도록) 다국어 리소스를 사용할 수 있도록 해보겠습니다. 이것마저 자동화해 버립시다.
📍Dispatch Workflow
서브모듈의 워크플로우에서 어떤 트리거를 줬을 때, 메인 레포지토리의 특정 워크플로우가 반응해서 서브모듈을 최신화하는 코드를 실행하게 된다면?! 이걸 github actions에서는 workflow를 dispatch 한다고 하는 것 같습니다. submodule에서 createWorkflowDispatch 이라는 github API를 실행시키면 됩니다!
스크립트에서 보면 createWorkflowDispatch 실행 시, 반응할 레포지토리 owner, 레포지토리 이름, workflow 파일 이름 등을 넣는 걸 볼 수 있습니다.
...
dispatch-main-repo:
# review-and-merge Job이 성공적으로 완료된 후 실행
needs: review-and-merge
if: ${{ needs.review-and-merge.result == 'success' }}
runs-on: ubuntu-latest
steps:
- name: Trigger Main Repository Workflow
uses: actions/github-script@v6
with:
github-token: ${{ secrets.KOCO_GITHUB_TOKEN }}
script: |
await github.rest.actions.createWorkflowDispatch({
owner: 'yyeonjju',
repo: 'KoCo-Beauty',
workflow_id: 'updateSubmodule.yml',
ref: 'develop',
inputs: {
name: 'KoCo Main Repository'
}
});
📍 서브모듈 최신화
위처럼 서브모듈에서 createWorkflowDispatch을 실행해 주면 메인레포지토리에서 workflow_dispatch:를 트리거로 했던 workflow가 실행되게 됩니다. 그럼 실행할 워크플로우의 스크립트는 서브모듈을 최신으로 업데이트시켜주는 코드로 구성하면 되겠죠?
on:
workflow_dispatch:
inputs:
name:
description: 'Input name'
required: true
type: string
permissions: write-all
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
token: ${{ secrets.KOCO_GITHUB_TOKEN }}
- name: Pull & update submodules recursively
run: |
git submodule update --init --recursive
git submodule update --recursive --remote
- name: Commit & push
id: commit
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: "[Success] complete update submodule"
- name: Notify Slack on Submodule Update Success
if: steps.commit.outcome == 'success'
uses: slackapi/slack-github-action@v2.0.0
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: webhook-trigger
payload: |
{
"text": "💎 SubModule Update Success"
}
여기서도 서브모듈에 대한 업데이트가 성공 시, 슬랙 웹훅을 사용해서 메시지를 받을 수 있도록 했습니다. 그럼 이제 자동화 완료, 이제 개발자가 댜국어를 위해 노력하는 건 최소화되겠네요!
📍 요약
이해가 잘 안 되실 분(미래의 나..)을 위해 도식화를 해보았습니다!
1. Lokalise 플랫폼에서 다국어 리소스 생성 및 관리 수행
2. Lokalise 파이프라인을 통한 Submodule의 Pull Request 자동 생성
3. PR 이벤트를 트리거로 Submodule의 Workflow(localization.yml) 실행
- SwiftGen을 통해 다국어 리소스의 Type-safe 코드 생성
- 변경사항 commit & merge 후, Slack Webhook을 통한 작업 완료 알림 전송
- Submodule 동기화를 위한 메인 레포지토리 Workflow 트리거 발생
4. 메인 레포지토리에서 트리거를 감지 후, Workflow(updateSubmodule.yml) 실행
- Submodule 최신 상태 동기화 완료 후, Slack Webhook을 통한 알림 전송
'iOS' 카테고리의 다른 글
GitHub Actions를 통한 다국어 자동화 (1) | Git Submodule, Lokalise (0) | 2025.02.18 |
---|---|
ETag 기반 이미지 캐싱 & instruments로 로딩 속도 분석 |OSLog, os_signpost (0) | 2025.01.13 |
[iOS] App Thinning 앱 씨닝과 Slicing, On-Demand Resource, Bitcode (4) | 2024.06.08 |
[iOS] image asset의 크기 1x ,2x, 3x 사용하는 이유 | scale factor, 해상도(Resolution), pixel, point (0) | 2024.05.22 |
[iOS] 앱의 시작지점 @main (1) | 2024.02.11 |