본문 바로가기
프로젝트/블루투스 메신저

API 36 타깃 핫픽스, 재작성 브랜치 대신 main에서 네 줄만 바꿨다

by iwbap 2026. 10. 21.
728x90
반응형

블루투스 메신저 BlooTalk의 대상 API를 35에서 36으로 올리는 핫픽스를 했다. 재작성 브랜치는 병합하지 않고 기존 main에서 두 파일 네 줄만 바꿨다. 첫 커밋에서 병합까지 4분 35초가 걸렸지만 빌드 검사는 끝나지 못했다.

휴대폰 화면에 대상 API 36을 크게 표시하고 옆에 SDK 35에서 36, versionCode 7에서 8, 변경 파일 3개 검사를 나란히 그린, main에서 네 줄만 바꾼 API 36 타깃 핫픽스를 요약한 대표 이미지
큰 브랜치는 두고, 마지막 버전 커밋에서 네 줄만 바꿨다

앱 업데이트에 API 36이 필요했다

Google Play는 2026년 8월 31일부터 새 앱과 앱 업데이트에 Android 16(API 36) 이상을 요구한다. 필요하면 2026년 11월 1일까지 기한 연장을 요청할 수 있다.

main의 기준은 2025년 12월 5일의 1.1.5 버전 업 커밋이었다. 당시 targetSdk는 35였다. 기존 앱 제공 기준과 달리 새 업데이트 제출에는 API 36이 필요했다.

재작성 브랜치 대신 기존 main을 기준으로

10월 20일 낮까지 작업한 재작성 브랜치는 main보다 259커밋 앞서 있었다. 바뀐 파일은 121개였고, 이미 API 36과 versionCode 9를 사용하는 개발판이었다.

정책 대응 하나 때문에 그 변경까지 함께 내보낼 생각은 없었다. 그래서 main의 1.1.5 커밋에서 핫픽스 브랜치를 새로 땄다. 바꿀 것은 SDK 버전과 앱 버전뿐이었다.

main의 1.1.5 커밋(API 35)에서 핫픽스 브랜치를 따로 내 SDK 35에서 36, 버전 7에서 8, 검사 워크플로 추가와 삭제를 거쳐 1.1.6(API 36)으로 main에 병합하고, 259커밋 앞선 API 36 재작성 브랜치는 병합하지 않은 흐름을 그린 개념 도식

커밋에는 '기존 1.1.5 기반'에서 수정했다는 설명이 남아 있다. 다만 앞 문단의 브랜치 선택 이유는 커밋 메시지에서 추정한 배경이다.

SDK와 버전, 두 파일 네 줄 변경

22시 59분 22초에 compileSdk와 targetSdk를 35에서 36으로 바꿨다. AGP(Android Gradle Plugin)는 8.10.1을 유지했다. AGP 8.10은 최대 API 36을 지원한다.

4초 뒤 versionCode를 7에서 8로, versionName을 1.1.5에서 1.1.6으로 올렸다. 아래는 두 커밋의 변경 내용이다.

# gradle/libs.versions.toml
 agp = "8.10.1"
-compileSdk = "35"
+compileSdk = "36"
-targetSdk = "35"
+targetSdk = "36"

# app/build.gradle.kts
-versionCode = 7
-versionName = "1.1.5"
+versionCode = 8
+versionName = "1.1.6"

재작성 브랜치의 versionCode 9와도 값이 겹치지 않았다. 다만 이를 의도해 8을 골랐다는 기록은 없다. 최소 지원 버전 minSdk 26은 그대로였다.

main 대비 세 가지 검사를 준비했다

23시 00분 33초에는 핫픽스 브랜치용 GitHub Actions 워크플로를 추가했다. 확인 대상으로 정한 것은 다음 세 가지였다.

  • main(6e37b0a) 대비 변경 파일이 SDK 설정, 앱 버전, 워크플로 세 개뿐인지
  • 단위 테스트와 디버그 APK, 릴리스 AAB 빌드가 완료되는지
  • 디버그 APK의 targetSdkVersion이 36이고 versionCode가 8인지

파일 목록을 예상한 세 파일과 diff로 비교하도록 했다. 다른 파일이 추가로 바뀌면 이 검사 단계가 실패하는 방식이었다.

git diff --name-only 6e37b0a..HEAD | sort > changed.txt
printf '%s\n' \
  '.github/workflows/play-api36-hotfix.yml' \
  'app/build.gradle.kts' \
  'gradle/libs.versions.toml' | sort > expected.txt
diff -u expected.txt changed.txt
grep -Fx 'compileSdk = "36"' gradle/libs.versions.toml
grep -Fx 'targetSdk = "36"' gradle/libs.versions.toml
grep -F 'versionCode = 8' app/build.gradle.kts

이후 aapt dump badging으로 디버그 APK의 두 버전 값을 읽도록 했다. AAB는 unzip -t로 압축 무결성만 확인하도록 했다. 검토용 산출물 이름에는 NOT-FOR-PLAY-UPLOAD를 명시했다.

유일한 CI 실행은 빌드 중 취소됐다

워크플로는 23시 00분 36초에 딱 한 번 돌기 시작했다. 바뀐 파일 검사와 API 36 플랫폼 설치는 통과했다. 그런데 테스트·빌드 단계가 2분 20초쯤 지난 23시 03분에 취소됐다.

검사 워크플로 한 번의 실행에서 체크아웃, 변경 파일 3개 검사, JDK 17 설정, API 36 플랫폼 설치는 통과하고 테스트와 빌드 단계는 약 2분 20초 만에 취소되어 aapt로 API 36을 확인하는 단계와 검토용 아티팩트 업로드는 건너뛴 결과를 정리한 도식

23시 01분 28초에는 '요청에 따라' 워크플로 파일이 삭제됐다. 삭제 요청의 이유나 실제 CI 취소 주체는 기록으로 확인할 수 없다.

테스트·빌드 단계는 완료되지 않았고, 버전 검증과 산출물 업로드 단계도 건너뛰었다. 따라서 API 36 빌드 성공이나 검증 완료를 주장할 수 없다.

23시 03분 57초에 핫픽스 브랜치를 main에 병합했다. 워크플로는 넣었다 뺐으니 main에 남은 변경은 처음 두 커밋의 네 줄뿐이다. 첫 커밋부터 4분 35초가 걸렸다.

10월 20일 22시 59분 22초 SDK 변경부터 버전 변경, 23시 00분 33초 검사 워크플로 추가, 23시 01분 28초 워크플로 삭제, 23시 03분 29초 실행 취소, 23시 03분 57초 main 병합까지 4분 35초의 흐름을 시간순으로 그린 타임라인

이번 핫픽스에서 배운 것

  • 큰 재작성 브랜치와 별도로 작은 수정 범위를 유지할 수 있다.
  • 변경 파일 목록을 비교하면 예상 밖 수정이 있는지 검사할 수 있다.
  • 중간에 취소된 CI 실행을 빌드 성공으로 기록하면 안 된다.

Android 16에서는 최소 너비 600dp 이상 화면의 방향·크기 제한이 기본적으로 무시된다. 다만 이 앱에 미치는 영향은 아직 확인하지 않았다.

1.1.6의 Play 업로드·출시 여부도 제공된 기록만으로는 알 수 없다. 이후에는 릴리스 빌드 검증과 배포 상태 확인이 필요하다.

자주 묻는 질문

Q. 8월 31일 이후 API 35로 업데이트할 수 있나?
A. 일반 모바일 앱 업데이트는 API 36 이상이 필요하다. 다만 11월 1일까지 기한 연장을 요청할 수 있다.

Q. API를 올릴 때 AGP도 반드시 올려야 하나?
A. AGP 8.10은 최대 API 36을 지원한다. 이번 변경에서도 기존 AGP 8.10.1을 유지했다.

관련 글: R8 릴리스 시작 크래시에 WorkManager keep 규칙 두 개를 더했다
참고: Play Console 고객센터: Google Play 앱의 대상 API 수준 요구사항 · Android Gradle Plugin 8.10.0 출시 노트(지원 API 수준)

728x90
반응형