내가 자주 사용하는 CICD 툴인 Bitrise 에서는 배포를 위한 트리거 방식이 여러 가지가 존재한다.
- Branch PR 이 올라오는 경우
- Branch Push 가 되는 경우
- 특정 Tag 가 생성되는 경우
내 프로젝트의 경우 CI/CD 를 위한 Branch 명이 자주 바뀌는 관계로 Branch 명에는 정규표현식을 사용하여 특정 문자열로 시작하는 브랜치인 경우 무조건 CI/CD 가 실행되게 하였었으나, 이러는 경우 정규표현식에 포함되는 다른 브랜치도 트리거 해버려서 의도치 않게 배포를 해버리는 경우가 종종 있었다.
이를 해결하기 위해 나는 3번. 즉, 특정 Tag 를 통해 배포를 하기로 마음을 먹었다.
우선 나는 테드팍님 (박상권) 님의 블로그 를 참고하였는데, 이곳에서는 Branch 가 Push 되었을때 해당 커밋 내용과 버전만을 기록하고 있었지만 나의 경우 조금 더 손을 봐 A (Feature) -> B (Master) 브랜치로 PR 이 병합 되었을 때, 병합 전 B 브랜치의 버전과 A 브랜치 사이에 있었던 모든 커밋들을 Release Tag 에 기록되게 만들었다.
# 생성 방법
이제 대충 설명을 모두 마쳤으니 릴리즈 태그 생성용 워크플로우를 만들어보도록 하자.
[안드로이드 관점에서 작성하여으니 혹시나 다른 개발자분들은 조금 변형해서 쓰시면 될 것 같습니다.]
우선 Github Repository -> Actions 로 들어가 좌측 상단의 New workflow 를 생성해준다.
그 다음 Simple workflow 의 Configure 를 통해 커스텀 워크플로우를 구현하기 위한 준비를 하고, 모든 내용을 지운 뒤 다음과 같이 코드를 추가해준다.
# 이름은 자유롭게 설정하면 됩니다
name: Release Tag Creator
on:
pull_request:
types:
- closed
permissions:
contents: write
나의 경우 PR 이 병합되었을 경우에만 이 워크플로우를 실행하기를 원하니 on 에 PR 이 닫혔을 때 워크플로우가 실행되도록 해준다.
types 로는 병합 하나만을 확인이 불가능하고 닫힘만을 확인할 수 있기에, 이것에 대한 설정은 job 을 실행할 때 조건으로 추가해줄 것이다.
추가로 permissions: contents: write 를 추가해줘야 자동적으로 릴리즈 태그를 생성해줄 수 있기 때문에, 이는 필수적으로 등록이 필요하다.
위의 모든 작업을 마쳤다면 아래의 코드를 복사해주자.
jobs:
base-branch-release:
# 이곳에서 베이스 브랜치가 main 으로 시작하고, merge 되어야 실행되게 설정함.
if: ${{ startsWith(github.event.pull_request.base.ref, 'main') && github.event.pull_request.merged == true }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Base 및 Head Sha 가져옴
run: |
git fetch origin ${{ github.event.pull_request.base.sha }}
git fetch origin ${{ github.event.pull_request.head.sha }}
echo "BASE_SHA=${{ github.event.pull_request.base.sha }}" >> $GITHUB_ENV
echo "HEAD_SHA=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV
- name: Base Branch 로 체크아웃
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.base.ref }}
# versionName 으로 추출하도록 설정하였기 때문에, 변형이 필요하다면 이곳 수정
- name: 버전 정보 추출
run: |
echo "브랜치에서 앱 버전 정보를 가져옵니다."
PR_VERSION_NAME=$(grep -oP '(?<=versionName\s=\s").*?(?=")' app/build.gradle.kts)
echo "PR_VERSION_NAME=$PR_VERSION_NAME" >> $GITHUB_ENV
- name: 릴리즈 노트 (커밋 사안들) 생성
run: |
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
# Base Branch Log 및 Head Branch Log 가져오기 (병합 당시)
# oneline 으로 커밋 로그를 한 줄로 요약하여 출력
CHANGES=$(git log --oneline ${{ env.BASE_SHA }}..${{ env.HEAD_SHA }} )
# Merge Branch 문장 찾고 마지막 단어만 추출, 그리고 샾 세개를 붙여 강조표시
CHANGES=$(echo "$CHANGES" | sed '/^Merge Branch/ s/.*\s\([^ ]*\)$/### \1/')
# 샾 세개로 시작하지 않는 커밋 내역 각 줄 앞에 - 생성
CHANGES=$(echo "$CHANGES" | sed '/^###/! s/^/- /')
RELEASE_BODY="## What's Changed"$'\n'"$CHANGES"
{
echo "RELEASE_BODY<<$EOF"
echo "$RELEASE_BODY"
echo "$EOF"
} >> $GITHUB_ENV
- name: 깃허브 릴리즈 태그 생성
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ env.PR_VERSION_NAME }}
release_name: Release ${{ env.PR_VERSION_NAME }}
body: ${{ env.RELEASE_BODY }}
상세한 주석들은 내부 코드에 설정해두었으므로 이를 참고하자.
# 최종본
name: Release Tag Creator
on:
pull_request:
types:
- closed
permissions:
contents: write
jobs:
base-branch-release:
if: ${{ startsWith(github.event.pull_request.base.ref, 'main') && github.event.pull_request.merged == true }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Base 및 Head Sha 가져옴
run: |
git fetch origin ${{ github.event.pull_request.base.sha }}
git fetch origin ${{ github.event.pull_request.head.sha }}
echo "BASE_SHA=${{ github.event.pull_request.base.sha }}" >> $GITHUB_ENV
echo "HEAD_SHA=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV
- name: Base Branch 로 체크아웃
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.base.ref }}
- name: 버전 정보 추출
run: |
echo "Release 브랜치에서 앱 버전 정보를 가져옵니다."
PR_VERSION_NAME=$(grep -oP '(?<=versionName\s=\s").*?(?=")' app/build.gradle.kts)
echo "PR_VERSION_NAME=$PR_VERSION_NAME" >> $GITHUB_ENV
- name: 릴리즈 노트 (커밋 사안들) 생성
run: |
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
# Base Branch Log 및 Head Branch Log 가져오기 (병합 당시)
# oneline 으로 커밋 로그를 한 줄로 요약하여 출력
CHANGES=$(git log --oneline ${{ env.BASE_SHA }}..${{ env.HEAD_SHA }} )
# Merge Branch 문장 찾고 마지막 단어만 추출, 그리고 샾 세개를 붙여 강조표시
CHANGES=$(echo "$CHANGES" | sed '/^Merge Branch/ s/.*\s\([^ ]*\)$/### \1/')
# 샾 세개로 시작하지 않는 커밋 내역 각 줄 앞에 - 생성
CHANGES=$(echo "$CHANGES" | sed '/^###/! s/^/- /')
RELEASE_BODY="## What's Changed"$'\n'"$CHANGES"
{
echo "RELEASE_BODY<<$EOF"
echo "$RELEASE_BODY"
echo "$EOF"
} >> $GITHUB_ENV
- name: 깃허브 릴리즈 태그 생성
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ env.PR_VERSION_NAME }}
release_name: Release ${{ env.PR_VERSION_NAME }}
body: ${{ env.RELEASE_BODY }}
# 결과물
'프로그래밍 > 안드로이드' 카테고리의 다른 글
[Android Studio] Kotlin 2.0.x 버전에서 Unresolved Reference 에러 발생 (1) | 2025.01.05 |
---|---|
[Android Studio] Kotlin 버전을 2.0.x 으로 마이그레이션 하기 (0) | 2025.01.04 |
[Android] 안드로이드 스튜디오에서 제공하는 앱링크의 문제점 (3) | 2024.11.05 |
[Android Studio] Annotation Processor -> KSP 로 마이그레이션 작업하기 (1) | 2024.11.04 |
[Android] 진동 세기 조절이 안되는 문제 해결법 (0) | 2024.11.03 |